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