001: /*
002: * $Header: /export/home/cvsroot/MyPersonalizerRepository/MyPersonalizer/Subsystems/Portal/Sources/es/udc/mypersonalizer/portal/controller/services/DefaultServiceController.java,v 1.1.1.1 2004/03/25 12:08:39 fbellas Exp $
003: * $Revision: 1.1.1.1 $
004: * $Date: 2004/03/25 12:08:39 $
005: *
006: * =============================================================================
007: *
008: * Copyright (c) 2003, The MyPersonalizer Development Group
009: * (http://www.tic.udc.es/~fbellas/mypersonalizer/index.html) at
010: * University Of A Coruna
011: * All rights reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions are met:
015: *
016: * - Redistributions of source code must retain the above copyright notice,
017: * this list of conditions and the following disclaimer.
018: *
019: * - Redistributions in binary form must reproduce the above copyright notice,
020: * this list of conditions and the following disclaimer in the documentation
021: * and/or other materials provided with the distribution.
022: *
023: * - Neither the name of the University Of A Coruna nor the names of its
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
028: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
029: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
030: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
031: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
032: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
033: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
034: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
035: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
036: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
037: * POSSIBILITY OF SUCH DAMAGE.
038: *
039: */
040:
041: package es.udc.mypersonalizer.portal.controller.services;
042:
043: import es.udc.mypersonalizer.portal.conventions.ServiceConfigurationConventions;
044: import es.udc.mypersonalizer.kernel.log.Log;
045: import es.udc.mypersonalizer.kernel.log.LogManager;
046: import es.udc.mypersonalizer.kernel.log.LogNamingConventions;
047: import es.udc.mypersonalizer.kernel.model.repository.interfaces.ServiceButtonsState;
048: import es.udc.mypersonalizer.kernel.model.repository.interfaces.ServiceConfiguration;
049: import es.udc.mypersonalizer.kernel.model.repository.interfaces.ServiceConfigurationRegistrySingleton;
050: import es.udc.mypersonalizer.kernel.model.repository.interfaces.ServiceProperty;
051: import es.udc.mypersonalizer.kernel.model.repository.interfaces.ServicePropertyKey;
052: import es.udc.mypersonalizer.kernel.util.exceptions.InternalErrorException;
053: import es.udc.mypersonalizer.portal.config.ServiceReplyCatcherConfig;
054: import es.udc.mypersonalizer.portal.config.PortalConfig;
055: import es.udc.mypersonalizer.portal.config.PortalConfigManager;
056: import javax.servlet.http.HttpServletRequest;
057: import javax.servlet.http.HttpServletResponse;
058: import java.net.URL;
059: import java.util.*;
060:
061: /**
062: * Default implementation of a Service Controller. It
063: * gets from a {@link ServiceReplyCatcherConfig} object the following
064: * configuration parameters:
065: * <ul>
066: * <li><tt>defaultServiceTimeOut</tt>: The default time out for a service.</li>
067: * <li><tt>containerURL</tt> The URL that identifies the container, to
068: * avoid problems in certain NAT configurations.</li>
069: * </ul>
070: *
071: * The main objective of this class is to provide the reply of a service
072: * by following these steps:
073: * <ol>
074: * <li>Asks the abstract method <tt>getPersonalizedReplyRequest</tt> for an
075: * object of class {@link PersonalizedReplyRequest} suitable for calling
076: * this service. The composition of this <tt>PersonalizedReplyRequest</tt>
077: * object will be specific for the service being called, and will be
078: * constructed by a subclass of this one.</li>
079: * <li>Calls the method <tt>getRealURL</tt>, which builds the URL which
080: * will be used to call the service by examining the
081: * <tt>PersonalizedReplyRequest</tt> object.</li>
082: * <li>Calls the {@link ServiceReplyCatcher}.getReply method, passing as
083: * parameters the URL to call and the timeout for the request, which
084: * will be the one configured for this service (if it has been
085: * specified) or the default time out (if it has not).</li>
086: * </ol>
087: *
088: * @author Daniel Fernandez
089: * @author Fernando Bellas
090: * @since 1.0
091: */
092: public abstract class DefaultServiceController implements
093: ServiceController {
094:
095: /**
096: * The default time out, from configuration.
097: */
098: private int defaultServiceTimeOut = 0;
099:
100: /**
101: * The container URL.
102: */
103: private String containerURL = null;
104:
105: /**
106: * Creates a new instance of DefaultServiceController and
107: * loads the configuration data.
108: */
109: public DefaultServiceController() {
110:
111: try {
112: PortalConfig portalConfig = PortalConfigManager.getConfig();
113:
114: ServiceReplyCatcherConfig serviceReplyCatcherConfig = portalConfig
115: .getPortalControllerConfig()
116: .getServiceReplyCatcherConfig();
117:
118: String timeOutStr = serviceReplyCatcherConfig
119: .getDefaultTimeOutSeconds();
120:
121: containerURL = serviceReplyCatcherConfig.getContainerURL();
122:
123: defaultServiceTimeOut = (new Integer(timeOutStr))
124: .intValue();
125:
126: } catch (Exception e) {
127:
128: Log mypersonalizerLog = LogManager
129: .getLog(LogNamingConventions.MYPERSONALIZER);
130: mypersonalizerLog.write(
131: "Could not initialize configuration for "
132: + "ServiceReplyCatcher", e,
133: DefaultServiceController.class);
134:
135: }
136:
137: }
138:
139: /**
140: * Returns the service reply by asking for a
141: * <tt>PersonalizedReplyRequest</tt>, building the URL by calling
142: * <tt>getRealURL</tt> and then asking the ServiceReplyCatcher.
143: *
144: * @param request the request object.
145: * @param response the response object.
146: * @param servicePropertyKey the service property key.
147: * @param serviceProperty the service property.
148: * @param buttons the service buttons state.
149: * @throws InternalErrorException if any fatal errors happen.
150: * @throws ServiceNotAvailableException if the service is not available.
151: * @throws ServiceTimeOutException if the service exceeds the established
152: * timeout.
153: * @return the service reply.
154: */
155: public String getPersonalizedReply(HttpServletRequest request,
156: HttpServletResponse response,
157: ServicePropertyKey servicePropertyKey,
158: ServiceProperty serviceProperty, ServiceButtonsState buttons)
159: throws InternalErrorException,
160: ServiceNotAvailableException, ServiceTimeOutException {
161:
162: PersonalizedReplyRequest personalizedReplyRequest = getPersonalizedReplyRequest(
163: request, response, servicePropertyKey, serviceProperty,
164: buttons);
165:
166: URL serviceURL = getRealURL(request, personalizedReplyRequest);
167:
168: ServiceConfigurationRegistrySingleton serviceConfigurationRegistrySingleton = ServiceConfigurationRegistrySingleton
169: .getInstance();
170:
171: ServiceConfiguration serviceConfiguration = serviceConfigurationRegistrySingleton
172: .getServiceConfiguration(servicePropertyKey
173: .getServiceIdentifier());
174:
175: String timeOutStr = (String) serviceConfiguration
176: .getParameters()
177: .get(ServiceConfigurationConventions.TIMEOUT_IN_SECONDS);
178:
179: int timeOut = 0;
180: if (timeOutStr != null) {
181:
182: try {
183: timeOut = (new Integer(timeOutStr)).intValue();
184: } catch (Exception e) {
185: throw new InternalErrorException(e);
186: }
187:
188: } else {
189:
190: timeOut = defaultServiceTimeOut;
191:
192: }
193:
194: String reply = ServiceReplyCatcher
195: .getReply(serviceURL, timeOut);
196:
197: return reply;
198:
199: }
200:
201: /**
202: * This method builds a {@link PersonalizedReplyRequest} object in a
203: * way which is specific to the service being dealt with.
204: *
205: * @param request the request object.
206: * @param response the response object.
207: * @param servicePropertyKey the service property key.
208: * @param serviceProperty the service property.
209: * @param buttons the service buttons state.
210: * @throws InternalErrorException if any fatal errors happen.
211: * @return the specific PersonalizedReplyRequest object.
212: */
213: protected abstract PersonalizedReplyRequest getPersonalizedReplyRequest(
214: HttpServletRequest request, HttpServletResponse response,
215: ServicePropertyKey servicePropertyKey,
216: ServiceProperty serviceProperty, ServiceButtonsState buttons)
217: throws InternalErrorException;
218:
219: /**
220: * Returns the real URL that will be used to call the service, based on
221: * the information in the request and the <tt>PersonalizedReplyRequest</tt>
222: * object received.<p>
223: *
224: * Parameters with an empty array of values (length 0) are discarded, since
225: * it is not possible to pass them appropriately when making an URL
226: * invocation.
227: *
228: * @param request the request object.
229: * @param personalizedReplyRequest the PersonalizedReplyRequest object.
230: * @throws InternalErrorException if any fatal errors happen.
231: * @return the URL to call the service.
232: */
233: protected URL getRealURL(HttpServletRequest request,
234: PersonalizedReplyRequest personalizedReplyRequest)
235: throws InternalErrorException {
236:
237: String containerURLStr = null;
238: if (containerURL != null) {
239: containerURLStr = containerURL;
240: } else {
241: containerURLStr = request.getScheme() + "://"
242: + request.getServerName() + ":"
243: + request.getServerPort();
244: }
245:
246: String realURLStr = containerURLStr + request.getContextPath()
247: + personalizedReplyRequest.getContextRelativePath()
248: + ";jsessionid=" + request.getSession().getId();
249: Map requestParameters = personalizedReplyRequest
250: .getParameters();
251: if (!requestParameters.isEmpty()) {
252:
253: String parametersStr = "?";
254:
255: Iterator parameterIter = requestParameters.entrySet()
256: .iterator();
257: while (parameterIter.hasNext()) {
258: Map.Entry entry = (Map.Entry) parameterIter.next();
259: String parameterName = (String) entry.getKey();
260: String[] parameterValues = (String[]) entry.getValue();
261:
262: if (parameterValues.length > 0) {
263: parametersStr += parameterName + "="
264: + parameterValues[0];
265: for (int i = 1; i < parameterValues.length; i++) {
266: parametersStr += "&" + parameterName + "="
267: + parameterValues[i];
268: }
269: }
270:
271: if (parameterIter.hasNext()) {
272: parametersStr += "&";
273: }
274: }
275:
276: realURLStr += parametersStr;
277: }
278:
279: URL resultURL = null;
280: try {
281:
282: resultURL = new URL(realURLStr);
283:
284: } catch (Exception e) {
285: throw new InternalErrorException(e);
286: }
287:
288: return resultURL;
289: }
290:
291: }
|