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