001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 */
019package org.nuxeo.ecm.webengine.jaxrs.views;
020
021import java.net.URI;
022import java.net.URL;
023import java.security.Principal;
024import java.util.LinkedList;
025
026import javax.servlet.http.HttpServletRequest;
027import javax.ws.rs.core.UriInfo;
028
029import org.nuxeo.ecm.core.api.CoreSession;
030import org.nuxeo.ecm.webengine.jaxrs.ApplicationHost;
031import org.nuxeo.ecm.webengine.jaxrs.session.SessionFactory;
032import org.nuxeo.ecm.platform.rendering.api.RenderingEngine;
033import org.osgi.framework.Bundle;
034
035/**
036 * A resource request context. This class is not thread safe.
037 *
038 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
039 */
040public class ResourceContext {
041
042    private static ThreadLocal<ResourceContext> perThreadContext = new ThreadLocal<ResourceContext>();
043
044    public final static void setContext(ResourceContext context) {
045        perThreadContext.set(context);
046    }
047
048    public final static ResourceContext getContext() {
049        return perThreadContext.get();
050    }
051
052    public final static void destroyContext() {
053        perThreadContext.remove();
054    }
055
056    /**
057     * The JAX-RS application providing the resources.
058     */
059    protected ApplicationHost app;
060
061    protected HttpServletRequest request;
062
063    protected UriInfo uriInfo;
064
065    private LinkedList<Bundle> bundleStack;
066
067    private CoreSession session;
068
069    protected ResourceContext() {
070    }
071
072    public ResourceContext(ApplicationHost app) {
073        // TODO rendering in app
074        this.app = app;
075        bundleStack = new LinkedList<Bundle>();
076        // this.bundleStack.add(app.getBundle());
077    }
078
079    public ApplicationHost getApplication() {
080        return app;
081    }
082
083    public final LinkedList<Bundle> getBundleStack() {
084        return bundleStack;
085    }
086
087    public void setUriInfo(UriInfo uriInfo) {
088        this.uriInfo = uriInfo;
089    }
090
091    public void setRequest(HttpServletRequest request) {
092        this.request = request;
093        session = SessionFactory.getSession(request);
094    }
095
096    public final Bundle getBundle() {
097        return bundleStack.isEmpty() ? null : bundleStack.get(bundleStack.size() - 1);
098    }
099
100    public final RenderingEngine getRenderingEngine() {
101        return app.getRendering();
102    }
103
104    public HttpServletRequest getRequest() {
105        return request;
106    }
107
108    public Principal getPrincipal() {
109        return request.getUserPrincipal();
110    }
111
112    public UriInfo getUriInfo() {
113        return uriInfo;
114    }
115
116    public CoreSession getSession() {
117        return session;
118    }
119
120    public URI getBaseUri() {
121        return uriInfo.getBaseUri();
122    }
123
124    public void pushBundleFor(Object obj) {
125        Bundle b = getResourceBundle(obj);
126        if (b != null) {
127            pushBundle(b);
128        }
129    }
130
131    public void pushBundle(Bundle bundle) {
132        for (Bundle b : bundleStack) {
133            if (b == bundle) {
134                // already present
135                return;
136            }
137        }
138        bundleStack.add(bundle);
139    }
140
141    protected Bundle getResourceBundle(Object res) {
142        // return FrameworkUtil.getBundle(res.getClass());
143        return app.getBundle(res.getClass());
144    }
145
146    /**
147     * The prefix used to reference templates in template source locators
148     *
149     * @return
150     */
151    public String getViewRoot() {
152        return bundleStack.isEmpty() ? "" : "view:" + bundleStack.get(bundleStack.size() - 1).getBundleId() + ":/";
153    }
154
155    public URL findEntry(String path) {
156        if (path.startsWith("view:")) {
157            int p = path.indexOf(":/");
158            if (p > -1) {
159                path = path.substring(p + 2);
160            }
161        }
162        for (int i = bundleStack.size() - 1; i >= 0; i--) {
163            URL url = bundleStack.get(i).getEntry(path);
164            if (url != null) {
165                return url;
166            }
167        }
168        return null;
169    }
170
171}