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