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