001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * bstefanescu 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.webengine.model.impl; 021 022import java.io.IOException; 023import java.io.PrintWriter; 024import java.io.StringWriter; 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.HttpHeaders; 034import javax.ws.rs.core.Response; 035import javax.ws.rs.core.Response.ResponseBuilder; 036import javax.ws.rs.core.UriInfo; 037 038import org.nuxeo.ecm.core.api.DocumentModel; 039import org.nuxeo.ecm.webengine.WebException; 040import org.nuxeo.ecm.webengine.app.DefaultContext; 041import org.nuxeo.ecm.webengine.model.Module; 042import org.nuxeo.ecm.webengine.model.ModuleResource; 043import org.nuxeo.ecm.webengine.model.ResourceType; 044import org.nuxeo.ecm.webengine.model.WebContext; 045import org.nuxeo.ecm.webengine.model.WebObject; 046import org.nuxeo.ecm.webengine.scripting.ScriptFile; 047 048/** 049 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 050 */ 051public class ModuleRoot extends DefaultObject implements ModuleResource { 052 053 protected HttpServletRequest request; 054 055 protected UriInfo uriInfo; 056 057 protected HttpHeaders httpHeaders; 058 059 @Context 060 public void setUriInfo(UriInfo info) { 061 this.uriInfo = info; 062 if (request != null && httpHeaders != null) { 063 init(); 064 } 065 } 066 067 @Context 068 public void setHttpHeaders(HttpHeaders headers) { 069 this.httpHeaders = headers; 070 if (request != null && uriInfo != null) { 071 init(); 072 } 073 } 074 075 @Context 076 public void setHttpRequest(HttpServletRequest request) { 077 this.request = request; 078 if (uriInfo != null && httpHeaders != null) { 079 init(); 080 } 081 } 082 083 private void init() { 084 DefaultContext ctx = (DefaultContext) request.getAttribute(WebContext.class.getName()); 085 if (ctx == null) { 086 throw new java.lang.IllegalStateException( 087 "No WebContext found in http request! You should install the WebEngineFilter"); 088 } 089 ctx.setHttpHeaders(httpHeaders); 090 ctx.setUriInfo(uriInfo); 091 Module module = findModule(ctx); 092 ResourceType type = module.getType(getClass().getAnnotation(WebObject.class).type()); 093 ctx.setModule(module); 094 initialize(ctx, type); 095 setRoot(true); 096 ctx.push(this); 097 } 098 099 private Module findModule(DefaultContext ctx) { 100 Path path = getClass().getAnnotation(Path.class); 101 if (path == null) { 102 throw new java.lang.IllegalStateException("ModuleRoot not annotated with @Path: " + getClass()); 103 } 104 ModuleConfiguration mc = ctx.getEngine().getModuleManager().getModuleByRootClass(getClass()); 105 if (mc == null) { 106 throw new java.lang.IllegalStateException("No module found for root resource: " + getClass()); 107 } 108 return mc.get(); 109 } 110 111 @GET 112 @Path("skin/{path:.*}") 113 public Response getSkinResource(@PathParam("path") String path) { 114 try { 115 ScriptFile file = getModule().getSkinResource("/resources/" + path); 116 if (file != null) { 117 long lastModified = file.lastModified(); 118 ResponseBuilder resp = Response.ok(file.getFile()).lastModified(new Date(lastModified)).header( 119 "Cache-Control", "public").header("Server", "Nuxeo/WebEngine-1.0"); 120 121 String mimeType = ctx.getEngine().getMimeType(file.getExtension()); 122 if (mimeType == null) { 123 mimeType = "text/plain"; 124 } 125 resp.type(mimeType); 126 return resp.build(); 127 } 128 } catch (IOException e) { 129 throw WebException.wrap("Failed to get resource file: " + path, e); 130 } 131 return Response.status(404).build(); 132 } 133 134 /** 135 * You should override this method to resolve objects to links. This method is usually called by a search view to 136 * generate links for object that are listed 137 * 138 * @param doc the document 139 * @return the link corresponding to that object 140 */ 141 public String getLink(DocumentModel doc) { 142 return new StringBuilder().append(getPath()).append("/@nxdoc/").append(doc.getId()).toString(); 143 } 144 145 public Object handleError(WebApplicationException e) { 146 return e; 147 } 148 149}