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 java.util.Iterator;
018    
019    import javax.servlet.http.HttpServletRequest;
020    import javax.servlet.http.HttpServletResponse;
021    
022    import org.apache.hivemind.ErrorHandler;
023    import org.apache.tapestry.IEngine;
024    import org.apache.tapestry.IRequestCycle;
025    import org.apache.tapestry.Tapestry;
026    import org.apache.tapestry.engine.IMonitor;
027    import org.apache.tapestry.engine.IMonitorFactory;
028    import org.apache.tapestry.engine.RequestCycle;
029    import org.apache.tapestry.engine.RequestCycleEnvironment;
030    import org.apache.tapestry.engine.ServiceEncoder;
031    import org.apache.tapestry.engine.ServiceEncodingImpl;
032    import org.apache.tapestry.record.PropertyPersistenceStrategySource;
033    import org.apache.tapestry.request.RequestContext;
034    import org.apache.tapestry.services.AbsoluteURLBuilder;
035    import org.apache.tapestry.services.Infrastructure;
036    import org.apache.tapestry.services.RequestCycleFactory;
037    import org.apache.tapestry.services.RequestGlobals;
038    import org.apache.tapestry.services.ServiceConstants;
039    import org.apache.tapestry.util.QueryParameterMap;
040    import org.apache.tapestry.web.WebRequest;
041    
042    /**
043     * Service that creates instances of {@link org.apache.tapestry.IRequestCycle}on behalf of an
044     * engine.
045     * 
046     * @author Howard M. Lewis Ship
047     * @since 4.0
048     */
049    public class RequestCycleFactoryImpl implements RequestCycleFactory
050    {
051        private ServiceEncoder[] _encoders;
052    
053        private IMonitorFactory _monitorFactory;
054    
055        private PropertyPersistenceStrategySource _strategySource;
056    
057        private ErrorHandler _errorHandler;
058    
059        private Infrastructure _infrastructure;
060    
061        private AbsoluteURLBuilder _absoluteURLBuilder;
062    
063        private RequestCycleEnvironment _environment;
064    
065        private RequestGlobals _requestGlobals;
066    
067        public void initializeService()
068        {
069            RequestContext context = new RequestContext(_requestGlobals.getRequest(), _requestGlobals
070                    .getResponse());
071    
072            _environment = new RequestCycleEnvironment(_errorHandler, _infrastructure, context,
073                    _strategySource, _absoluteURLBuilder);
074        }
075    
076        public IRequestCycle newRequestCycle(IEngine engine)
077        {
078            WebRequest request = _infrastructure.getRequest();
079    
080            IMonitor monitor = _monitorFactory.createMonitor(request);
081    
082            QueryParameterMap parameters = extractParameters(request);
083    
084            decodeParameters(request.getActivationPath(), request.getPathInfo(), parameters);
085    
086            String serviceName = findService(parameters);
087    
088            IRequestCycle cycle = new RequestCycle(engine, parameters, serviceName, monitor,
089                    _environment);
090    
091            _requestGlobals.store(cycle);
092    
093            return cycle;
094        }
095    
096        private String findService(QueryParameterMap parameters)
097        {
098            String serviceName = parameters.getParameterValue(ServiceConstants.SERVICE);
099    
100            return serviceName == null ? Tapestry.HOME_SERVICE : serviceName;
101        }
102    
103        /**
104         * Constructs a {@link org.apache.tapestry.util.QueryParameterMap}using the parameters
105         * available from the {@link org.apache.tapestry.request.RequestContext} (but ignoring any
106         * file upload parameters!).
107         */
108    
109        private QueryParameterMap extractParameters(WebRequest request)
110        {
111            QueryParameterMap result = new QueryParameterMap();
112    
113            Iterator i = request.getParameterNames().iterator();
114    
115            while (i.hasNext())
116            {
117                String name = (String) i.next();
118    
119                String[] values = request.getParameterValues(name);
120    
121                if (values.length == 1)
122                    result.setParameterValue(name, values[0]);
123                else
124                    result.setParameterValues(name, values);
125            }
126    
127            return result;
128        }
129    
130        private void decodeParameters(String servletPath, String pathInfo, QueryParameterMap map)
131        {
132            ServiceEncodingImpl se = new ServiceEncodingImpl(servletPath, pathInfo, map);
133    
134            for (int i = 0; i < _encoders.length; i++)
135            {
136                _encoders[i].decode(se);
137    
138                if (se.isModified())
139                    return;
140            }
141        }
142    
143        public void setEncoders(ServiceEncoder[] encoders)
144        {
145            _encoders = encoders;
146        }
147    
148        public void setMonitorFactory(IMonitorFactory monitorFactory)
149        {
150            _monitorFactory = monitorFactory;
151        }
152    
153        public void setStrategySource(PropertyPersistenceStrategySource strategySource)
154        {
155            _strategySource = strategySource;
156        }
157    
158        public void setErrorHandler(ErrorHandler errorHandler)
159        {
160            _errorHandler = errorHandler;
161        }
162    
163        public void setInfrastructure(Infrastructure infrastructure)
164        {
165            _infrastructure = infrastructure;
166        }
167    
168        public void setAbsoluteURLBuilder(AbsoluteURLBuilder absoluteURLBuilder)
169        {
170            _absoluteURLBuilder = absoluteURLBuilder;
171        }
172    
173        public void setRequestGlobals(RequestGlobals requestGlobals)
174        {
175            _requestGlobals = requestGlobals;
176        }
177    }