001 // Copyright 2004, 2005 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.tapestry.services.impl; 016 017 import javax.servlet.ServletContext; 018 import javax.servlet.http.HttpServlet; 019 020 import org.apache.commons.logging.Log; 021 import org.apache.hivemind.Resource; 022 import org.apache.hivemind.util.ContextResource; 023 import org.apache.tapestry.parse.ISpecificationParser; 024 import org.apache.tapestry.services.ApplicationGlobals; 025 import org.apache.tapestry.services.ApplicationInitializer; 026 import org.apache.tapestry.services.ClasspathResourceFactory; 027 import org.apache.tapestry.spec.ApplicationSpecification; 028 import org.apache.tapestry.spec.IApplicationSpecification; 029 import org.apache.tapestry.web.HttpServletWebActivator; 030 031 /** 032 * Locates the application specification and informs the servlet service about it. 033 * 034 * @author Howard Lewis Ship 035 * @since 4.0 036 */ 037 public class ApplicationSpecificationInitializer implements ApplicationInitializer 038 { 039 public static final String APP_SPEC_PATH_PARAM = "org.apache.tapestry.application-specification"; 040 041 private Log _log; 042 043 private ClasspathResourceFactory _classpathResourceFactory; 044 045 private ApplicationGlobals _globals; 046 047 private ISpecificationParser _parser; 048 049 public void initialize(HttpServlet servlet) 050 { 051 IApplicationSpecification spec = null; 052 053 Resource specResource = findApplicationSpecification(servlet); 054 055 if (specResource == null) 056 { 057 _log.warn(ImplMessages.noApplicationSpecification(servlet)); 058 059 spec = constructStandinSpecification(servlet); 060 } else 061 spec = _parser.parseApplicationSpecification(specResource); 062 063 _globals.storeActivator(new HttpServletWebActivator(servlet)); 064 _globals.storeSpecification(spec); 065 } 066 067 private Resource findApplicationSpecification(HttpServlet servlet) 068 { 069 String path = servlet.getInitParameter(APP_SPEC_PATH_PARAM); 070 071 if (path != null) 072 return _classpathResourceFactory.newResource(path); 073 074 ServletContext context = servlet.getServletContext(); 075 String servletName = servlet.getServletName(); 076 String expectedName = servletName + ".application"; 077 078 Resource webInfLocation = new ContextResource(context, "/WEB-INF/"); 079 Resource webInfAppLocation = webInfLocation.getRelativeResource(servletName + "/"); 080 081 Resource result = check(webInfAppLocation, expectedName); 082 if (result != null) 083 return result; 084 085 result = check(webInfLocation, expectedName); 086 if (result != null) 087 return result; 088 089 // Now look for it in classpath, just in case 090 091 result = _classpathResourceFactory.newResource(expectedName); 092 if (result != null && result.getResourceURL() != null) 093 return result; 094 095 return null; 096 } 097 098 private Resource check(Resource resource, String name) 099 { 100 Resource result = resource.getRelativeResource(name); 101 102 if (_log.isDebugEnabled()) 103 _log.debug("Checking for existence of " + result); 104 105 if (result.getResourceURL() != null) 106 { 107 _log.debug("Found " + result); 108 return result; 109 } 110 111 return null; 112 } 113 114 private IApplicationSpecification constructStandinSpecification(HttpServlet servlet) 115 { 116 String servletName = servlet.getServletName(); 117 118 ApplicationSpecification result = new ApplicationSpecification(); 119 120 // Pretend the file exists in the most common expected location. 121 122 Resource virtualLocation = new ContextResource(servlet.getServletContext(), "/WEB-INF/" + servletName + ".application"); 123 124 result.setSpecificationLocation(virtualLocation); 125 126 result.setName(servletName); 127 128 return result; 129 } 130 131 public void setClasspathResourceFactory(ClasspathResourceFactory factory) 132 { 133 _classpathResourceFactory = factory; 134 } 135 136 public void setLog(Log log) 137 { 138 _log = log; 139 } 140 141 public void setGlobals(ApplicationGlobals globals) 142 { 143 _globals = globals; 144 } 145 146 public void setParser(ISpecificationParser parser) 147 { 148 _parser = parser; 149 } 150 151 }