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