001/*
002 * (C) Copyright 2006-2008 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 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.webengine.model.impl;
023
024import java.io.IOException;
025import java.util.Date;
026
027import javax.servlet.http.HttpServletRequest;
028import javax.ws.rs.GET;
029import javax.ws.rs.Path;
030import javax.ws.rs.PathParam;
031import javax.ws.rs.WebApplicationException;
032import javax.ws.rs.core.Context;
033import javax.ws.rs.core.Response;
034import javax.ws.rs.core.Response.ResponseBuilder;
035import org.nuxeo.ecm.core.api.DocumentModel;
036import org.nuxeo.ecm.webengine.WebException;
037import org.nuxeo.ecm.webengine.app.DefaultContext;
038import org.nuxeo.ecm.webengine.model.Module;
039import org.nuxeo.ecm.webengine.model.ModuleResource;
040import org.nuxeo.ecm.webengine.model.ResourceType;
041import org.nuxeo.ecm.webengine.model.WebContext;
042import org.nuxeo.ecm.webengine.model.WebObject;
043import org.nuxeo.ecm.webengine.scripting.ScriptFile;
044
045import com.sun.jersey.api.core.HttpContext;
046import com.sun.jersey.server.impl.inject.ServerInjectableProviderContext;
047
048/**
049 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
050 */
051public class ModuleRoot extends DefaultObject implements ModuleResource {
052
053    @Context
054    protected HttpServletRequest request;
055
056    @Context
057    protected ServerInjectableProviderContext sic;
058
059    @Context
060    public void setContext(HttpContext hc) {
061        DefaultContext ctx = (DefaultContext) request.getAttribute(WebContext.class.getName());
062        if (ctx == null) {
063            throw new java.lang.IllegalStateException(
064                    "No WebContext found in http request! You should install the WebEngineFilter");
065        }
066        if (ctx.getModule() != null) { // just a resource, not a module root
067            return;
068        }
069        try {
070            ctx.setJerseyContext(sic, hc);
071            Module module = findModule(ctx);
072            ResourceType type = module.getType(getClass().getAnnotation(WebObject.class).type());
073            ctx.setModule(module);
074            initialize(ctx, type);
075            setRoot(true);
076        } finally {
077            ctx.push(this);
078        }
079    }
080
081    private Module findModule(DefaultContext ctx) {
082        Path path = getClass().getAnnotation(Path.class);
083        if (path == null) {
084            throw new java.lang.IllegalStateException("ModuleRoot not annotated with @Path: " + getClass());
085        }
086        ModuleConfiguration mc = ctx.getEngine().getModuleManager().getModuleByRootClass(getClass());
087        if (mc == null) {
088            throw new java.lang.IllegalStateException("No module found for root resource: " + getClass());
089        }
090        return mc.get(ctx);
091    }
092
093    @GET
094    @Path("skin/{path:.*}")
095    public Response getSkinResource(@PathParam("path") String path) {
096        try {
097            ScriptFile file = getModule().getSkinResource("/resources/" + path);
098            if (file != null) {
099                long lastModified = file.lastModified();
100                ResponseBuilder resp = Response.ok(file.getFile()).lastModified(new Date(lastModified)).header(
101                        "Cache-Control", "public").header("Server", "Nuxeo/WebEngine-1.0");
102
103                String mimeType = ctx.getEngine().getMimeType(file.getExtension());
104                if (mimeType == null) {
105                    mimeType = "text/plain";
106                }
107                resp.type(mimeType);
108                return resp.build();
109            }
110        } catch (IOException e) {
111            throw WebException.wrap("Failed to get resource file: " + path, e);
112        }
113        return Response.status(404).build();
114    }
115
116    /**
117     * You should override this method to resolve objects to links. This method is usually called by a search view to
118     * generate links for object that are listed
119     *
120     * @param doc the document
121     * @return the link corresponding to that object
122     */
123    @Override
124    public String getLink(DocumentModel doc) {
125        return new StringBuilder().append(getPath()).append("/@nxdoc/").append(doc.getId()).toString();
126    }
127
128    @Override
129    public Object handleError(WebApplicationException e) {
130        return e;
131    }
132
133}