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