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        this.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    }
094
095    public final Bundle getBundle() {
096        return bundleStack.isEmpty() ? null : bundleStack.get(bundleStack.size() - 1);
097    }
098
099    public final RenderingEngine getRenderingEngine() {
100        return app.getRendering();
101    }
102
103    public HttpServletRequest getRequest() {
104        return request;
105    }
106
107    public Principal getPrincipal() {
108        return request.getUserPrincipal();
109    }
110
111    public UriInfo getUriInfo() {
112        return uriInfo;
113    }
114
115    public CoreSession getSession() {
116        if (session == null) {
117            session = SessionFactory.getSession(request);
118        }
119        return session;
120    }
121
122    public URI getBaseUri() {
123        return uriInfo.getBaseUri();
124    }
125
126    public void pushBundleFor(Object obj) {
127        Bundle b = getResourceBundle(obj);
128        if (b != null) {
129            pushBundle(b);
130        }
131    }
132
133    public void pushBundle(Bundle bundle) {
134        for (Bundle b : bundleStack) {
135            if (b == bundle) {
136                // already present
137                return;
138            }
139        }
140        bundleStack.add(bundle);
141    }
142
143    protected Bundle getResourceBundle(Object res) {
144        // return FrameworkUtil.getBundle(res.getClass());
145        return app.getBundle(res.getClass());
146    }
147
148    /**
149     * The prefix used to reference templates in template source locators
150     *
151     * @return
152     */
153    public String getViewRoot() {
154        return bundleStack.isEmpty() ? "" : "view:" + bundleStack.get(bundleStack.size() - 1).getBundleId() + ":/";
155    }
156
157    public URL findEntry(String path) {
158        if (path.startsWith("view:")) {
159            int p = path.indexOf(":/");
160            if (p > -1) {
161                path = path.substring(p + 2);
162            }
163        }
164        for (int i = bundleStack.size() - 1; i >= 0; i--) {
165            URL url = bundleStack.get(i).getEntry(path);
166            if (url != null) {
167                return url;
168            }
169        }
170        return null;
171    }
172
173}