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
033     * {@link org.apache.tapestry.services.ServletInfo}service about it.
034     * 
035     * @author Howard Lewis Ship
036     * @since 4.0
037     */
038    public class ApplicationSpecificationInitializer implements ApplicationInitializer
039    {
040        private Log _log;
041    
042        private ClasspathResourceFactory _classpathResourceFactory;
043    
044        private ApplicationGlobals _globals;
045    
046        private ISpecificationParser _parser;
047    
048        public static final String APP_SPEC_PATH_PARAM = "org.apache.tapestry.application-specification";
049    
050        public void initialize(HttpServlet servlet)
051        {
052            IApplicationSpecification spec = null;
053    
054            Resource specResource = findApplicationSpecification(servlet);
055    
056            if (specResource == null)
057            {
058                _log.debug(ImplMessages.noApplicationSpecification(servlet));
059    
060                spec = constructStandinSpecification(servlet);
061            }
062            else
063                spec = _parser.parseApplicationSpecification(specResource);
064    
065            _globals.storeActivator(new HttpServletWebActivator(servlet));
066            _globals.storeSpecification(spec);
067        }
068    
069        private Resource findApplicationSpecification(HttpServlet servlet)
070        {
071            String path = servlet.getInitParameter(APP_SPEC_PATH_PARAM);
072    
073            if (path != null)
074                return _classpathResourceFactory.newResource(path);
075    
076            ServletContext context = servlet.getServletContext();
077            String servletName = servlet.getServletName();
078            String expectedName = servletName + ".application";
079    
080            Resource webInfLocation = new ContextResource(context, "/WEB-INF/");
081            Resource webInfAppLocation = webInfLocation.getRelativeResource(servletName + "/");
082    
083            Resource result = check(webInfAppLocation, expectedName);
084            if (result != null)
085                return result;
086    
087            return check(webInfLocation, expectedName);
088        }
089    
090        private Resource check(Resource resource, String name)
091        {
092            Resource result = resource.getRelativeResource(name);
093    
094            if (_log.isDebugEnabled())
095                _log.debug("Checking for existence of " + result);
096    
097            if (result.getResourceURL() != null)
098            {
099                _log.debug("Found " + result);
100                return result;
101            }
102    
103            return null;
104        }
105    
106        private IApplicationSpecification constructStandinSpecification(HttpServlet servlet)
107        {
108            String servletName = servlet.getServletName();
109    
110            ApplicationSpecification result = new ApplicationSpecification();
111    
112            // Pretend the file exists in the most common expected location.
113    
114            Resource virtualLocation = new ContextResource(servlet.getServletContext(), "/WEB-INF/"
115                    + servletName + ".application");
116    
117            result.setSpecificationLocation(virtualLocation);
118    
119            result.setName(servletName);
120    
121            return result;
122        }
123    
124        public void setClasspathResourceFactory(ClasspathResourceFactory factory)
125        {
126            _classpathResourceFactory = factory;
127        }
128    
129        public void setLog(Log log)
130        {
131            _log = log;
132        }
133    
134        public void setGlobals(ApplicationGlobals globals)
135        {
136            _globals = globals;
137        }
138    
139        public void setParser(ISpecificationParser parser)
140        {
141            _parser = parser;
142        }
143    
144    }