View Javadoc

1   /*
2    * Copyright (c) 2005-2007 Creative Sphere Limited.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *
10   *   Creative Sphere - initial API and implementation
11   *
12   */
13  package org.abstracthorizon.danube.tapestry;
14  
15  import java.io.IOException;
16  import java.io.InputStream;
17  import java.net.URL;
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Locale;
22  import java.util.Map;
23  
24  import org.abstracthorizon.danube.connection.Connection;
25  import org.abstracthorizon.danube.connection.ConnectionHandler;
26  import org.abstracthorizon.danube.http.HTTPConnection;
27  import org.abstracthorizon.danube.http.session.HTTPSessionManager;
28  import org.abstracthorizon.danube.http.session.SimpleSessionManager;
29  import org.abstracthorizon.danube.support.RuntimeIOException;
30  
31  import org.apache.hivemind.ClassResolver;
32  import org.apache.hivemind.ErrorHandler;
33  import org.apache.hivemind.ModuleDescriptorProvider;
34  import org.apache.hivemind.Registry;
35  import org.apache.hivemind.Resource;
36  import org.apache.hivemind.impl.DefaultClassResolver;
37  import org.apache.hivemind.impl.RegistryBuilder;
38  import org.apache.hivemind.impl.StrictErrorHandler;
39  import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
40  import org.apache.hivemind.parse.CreateInstanceDescriptor;
41  import org.apache.hivemind.parse.ImplementationDescriptor;
42  import org.apache.hivemind.parse.ModuleDescriptor;
43  import org.apache.hivemind.util.ClasspathResource;
44  import org.apache.tapestry.parse.ISpecificationParser;
45  import org.apache.tapestry.services.ApplicationGlobals;
46  import org.apache.tapestry.services.Infrastructure;
47  import org.apache.tapestry.services.WebRequestServicer;
48  import org.apache.tapestry.spec.IApplicationSpecification;
49  import org.apache.tapestry.web.WebActivator;
50  import org.apache.tapestry.web.WebContext;
51  import org.apache.tapestry.web.WebContextResource;
52  import org.apache.tapestry.web.WebRequest;
53  import org.apache.tapestry.web.WebResponse;
54  import org.slf4j.Logger;
55  import org.slf4j.LoggerFactory;
56  
57  /**
58   * Tapestry connection handler.
59   *
60   * During initialisation it reads tapestry application configuration file
61   * which defaults to {@link #TAPESTRY_DEFAULT_APPLICATION_NAME} ("tapestry.application").
62   *
63   *
64   * @author Daniel Sendula
65   */
66  public class TapestryConnectionHandler implements ConnectionHandler {
67  
68      /** Suffix of tapestry configuration files */
69      public static final String TAPESTRY_SUFFIX = ".application";
70  
71      /** Default tapestry application configuration file */
72      public static final String TAPESTRY_DEFAULT_APPLICATION_NAME = "tapestry" + TAPESTRY_SUFFIX;
73  
74      /** Logger */
75      protected final Logger logger = LoggerFactory.getLogger(getClass());
76  
77      /** Tapestry's class resolver */
78      protected ClassResolver classResolver;
79  
80      /** Tapestry's registry */
81      protected Registry registry;
82  
83      /** Tapestry's web request servicer */
84      protected WebRequestServicer webRequestServicer;
85  
86      /** Web activator implementation reference */
87      protected WebActivator webActivator;
88  
89      /** Web context implementation reference */
90      protected WebContext webContext;
91  
92      /** Danube's session manager */
93      protected HTTPSessionManager sessionManager;
94  
95      /** Application specification resource name. Initial value is "tapestry.application" */
96      protected String applicationSpecificationResourceName = TAPESTRY_DEFAULT_APPLICATION_NAME;
97  
98      /** Initial parameters */
99      protected Map<String, String> initialParameters;
100 
101     /**
102      * Handles connection by creating {@link DanubeRequest} and {@link DanubeResponse}
103      * and invokes servicer's service method.
104      * @param connection connection
105      */
106     public void handleConnection(Connection connection) {
107         HTTPConnection httpConnection = (HTTPConnection)connection.adapt(HTTPConnection.class);
108 
109         try {
110             registry.setupThread();
111 
112             WebRequest request = new DanubeRequest(httpConnection, getSessionManager());
113             WebResponse response = new DanubeResponse(httpConnection);
114 
115             webRequestServicer.service(request, response);
116         } catch (IOException e) {
117             throw new RuntimeIOException(e);
118         } finally {
119             registry.cleanupThread();
120         }
121     }
122 
123     /**
124      * Initialises this connection handler
125      * @throws Exception
126      */
127     @SuppressWarnings("unchecked")
128     public void init() throws Exception {
129 
130         classResolver = getClassResolver();
131 
132         ErrorHandler errorHandler = constructErrorHandler();
133 
134         RegistryBuilder builder = new RegistryBuilder(errorHandler);
135 
136         builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(classResolver));
137 
138         builder.addModuleDescriptorProvider(new ModuleDescriptorProvider() {
139             ArrayList<ModuleDescriptor> list;
140 
141             public List<ModuleDescriptor> getModuleDescriptors(ErrorHandler errorHandler) {
142                 if (list == null) {
143                     list = new ArrayList<ModuleDescriptor>();
144                     ModuleDescriptor moduleDescriptor = new ModuleDescriptor(classResolver, errorHandler);
145                     ImplementationDescriptor implementationDescriptor = new ImplementationDescriptor();
146                     implementationDescriptor.setServiceId("tapestry.request.CookieSource");
147                     CreateInstanceDescriptor instanceBuilder = new CreateInstanceDescriptor();
148                     instanceBuilder.setInstanceClassName(DanubeCookieSource.class.getName());
149                     implementationDescriptor.setInstanceBuilder(instanceBuilder);
150                     moduleDescriptor.addImplementation(implementationDescriptor);
151                     list.add(moduleDescriptor);
152                 }
153                 return list;
154             }
155 
156         });
157 
158         try {
159             // TODO WEB-INF?!
160             // ClassResolver classResolver = getClassResolver();
161             URL url = classResolver.getResource("WEB-INF/hivemodule.xml");
162             InputStream is = url.openStream();
163             is.read();
164             is.close();
165 
166             Resource hivemoduleResource = new ClasspathResource(classResolver, "WEB-INF/hivemodule.xml");
167             builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(classResolver, hivemoduleResource));
168         } catch (Exception ignore) {
169         }
170 
171         registry = builder.constructRegistry(Locale.getDefault());
172 
173         Resource location = obtainApplicationResource();
174 
175         // URL url = location.getResourceURL();
176         // System.out.println(new File(url.getFile()).exists());
177         ISpecificationParser parser = (ISpecificationParser)registry.getService("tapestry.parse.SpecificationParser", ISpecificationParser.class);
178         IApplicationSpecification specification = parser.parseApplicationSpecification(location);
179 
180         List factoryServices = (List)registry.getConfiguration("tapestry.services.FactoryServices");
181 
182         ApplicationGlobals globals = (ApplicationGlobals)registry.getService("tapestry.globals.ApplicationGlobals", ApplicationGlobals.class);
183         globals.storeActivator(getWebActivator());
184         globals.storeWebContext(getWebContext());
185         globals.storeSpecification(specification);
186         globals.storeFactoryServices(factoryServices);
187 
188         Infrastructure infrastructure = (Infrastructure)registry.getService("tapestry.Infrastructure", Infrastructure.class);
189         infrastructure.initialize("danube");
190 
191         registry.cleanupThread();
192 
193         webRequestServicer = (WebRequestServicer) registry.getService("tapestry.request.WebRequestServicer", WebRequestServicer.class);
194     }
195 
196     /**
197      * Creates {@link WebContext}.
198      * @return new {@link DanubeContext}
199      */
200     protected WebContext obtainWebContext() {
201         return new DanubeContext(this);
202     }
203 
204     /**
205      * Constructs error handler. This method returns
206      * {@link StrictErrorHandler}
207      * @return error handler
208      */
209     protected ErrorHandler constructErrorHandler() {
210         return new StrictErrorHandler();
211     }
212 
213     /**
214      * Obtains application resource.
215      * This implementation returns &quot;tapestry.application&qout; file resource
216      * @return application resource
217      */
218     protected Resource obtainApplicationResource() {
219         return new WebContextResource(getWebContext(), getApplicationSpecificationResourceName());
220     }
221 
222     /**
223      * Returns session manager. If none is supplied then {@link #createSessionManager()} method is called.
224      * @return the sessionManager
225      */
226     public HTTPSessionManager getSessionManager() {
227         if (sessionManager == null) {
228             sessionManager = createSessionManager();
229         }
230         return sessionManager;
231     }
232 
233     /**
234      * Sets session manager
235      * @param sessionManager the sessionManager to set
236      */
237     public void setSessionManager(HTTPSessionManager sessionManager) {
238         this.sessionManager = sessionManager;
239     }
240 
241     /**
242      * Creates session manager. This implementation returns
243      * {@link SimpleSessionManager}
244      * @return creates new session manager
245      */
246     protected HTTPSessionManager createSessionManager() {
247         return new SimpleSessionManager();
248     }
249 
250     /**
251      * Returns class resolver. If none is supplied then {@link #createClassResolver()} method
252      * is called
253      * @return class resolver
254      */
255     public ClassResolver getClassResolver() {
256         if (classResolver == null) {
257             classResolver = createClassResolver();
258         }
259         return classResolver;
260     }
261 
262     /**
263      * Sets class resolver
264      * @param classResolver class resolver
265      */
266     public void setClassResolver(ClassResolver classResolver) {
267         this.classResolver = classResolver;
268     }
269 
270     /**
271      * Creates class resolver. This implementation returns
272      * {@link DefaultClassResolver}.
273      * @return new class resolver
274      */
275     protected ClassResolver createClassResolver() {
276         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
277         return new DefaultClassResolver(classLoader);
278     }
279 
280     /**
281      * Returns initial parameters. If not already set then it creates new, empty
282      * map.
283      * @return initial parameters
284      */
285     public Map<String, String> getInitialParameters() {
286         if (initialParameters == null) {
287             initialParameters = new HashMap<String, String>();
288         }
289         return initialParameters;
290     }
291 
292     /**
293      * Sets initial parameters
294      * @param parameters initial parameters
295      */
296     public void setInitialParameters(Map<String, String> parameters) {
297         this.initialParameters = parameters;
298     }
299 
300     /**
301      * Returns name of application specification resource
302      * @return name of application specification resource
303      */
304     public String getApplicationSpecificationResourceName() {
305         if (applicationSpecificationResourceName == null) {
306             applicationSpecificationResourceName = TAPESTRY_DEFAULT_APPLICATION_NAME;
307         }
308         return applicationSpecificationResourceName;
309     }
310 
311     /**
312      * Sets name of application specification resource
313      * @param applicationSpecificationResourceName name of application specification resource
314      */
315     public void setApplicationSpecificationResourceName(String applicationSpecificationResourceName) {
316         this.applicationSpecificationResourceName = applicationSpecificationResourceName;
317     }
318 
319     /**
320      * Returns web activator. If not already set then {@link DanubeActivator} will be
321      * instantiated.
322      * @return web activator
323      */
324     public WebActivator getWebActivator() {
325         if (webActivator == null) {
326             webActivator = new DanubeActivator(this);
327         }
328         return webActivator;
329     }
330 
331     /**
332      * Sets web activator.
333      * @param webActivator web activator
334      */
335     public void setWebActivator(WebActivator webActivator) {
336         this.webActivator = webActivator;
337     }
338 
339     /**
340      * Returns web context assigned to this handler. If not already set then {@link DanubeContext}
341      * will be instantiated.
342      * @return web context
343      */
344     public WebContext getWebContext() {
345         if (webContext == null) {
346             webContext = new DanubeContext(this);
347         }
348         return webContext;
349     }
350 
351     /**
352      * Sets web context.
353      * @param webContext web context
354      */
355     public void setWebContext(WebContext webContext) {
356         this.webContext = webContext;
357     }
358 
359 }