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
015package org.apache.tapestry.services.impl;
016
017import java.util.Iterator;
018
019import org.apache.hivemind.ErrorHandler;
020import org.apache.tapestry.IEngine;
021import org.apache.tapestry.IRequestCycle;
022import org.apache.tapestry.Tapestry;
023import org.apache.tapestry.engine.IMonitor;
024import org.apache.tapestry.engine.IMonitorFactory;
025import org.apache.tapestry.engine.RequestCycle;
026import org.apache.tapestry.engine.RequestCycleEnvironment;
027import org.apache.tapestry.engine.ServiceEncoder;
028import org.apache.tapestry.engine.ServiceEncodingImpl;
029import org.apache.tapestry.record.PropertyPersistenceStrategySource;
030import org.apache.tapestry.request.RequestContext;
031import org.apache.tapestry.services.AbsoluteURLBuilder;
032import org.apache.tapestry.services.Infrastructure;
033import org.apache.tapestry.services.RequestCycleFactory;
034import org.apache.tapestry.services.RequestGlobals;
035import org.apache.tapestry.services.ServiceConstants;
036import org.apache.tapestry.util.QueryParameterMap;
037import 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 */
046public 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}