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 }