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 }