View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.springframework.extensions.surf;
20  
21  import java.util.Collections;
22  import java.util.Enumeration;
23  
24  import javax.servlet.GenericServlet;
25  import javax.servlet.ServletConfig;
26  import javax.servlet.ServletContext;
27  import javax.servlet.ServletException;
28  import javax.servlet.ServletRequest;
29  import javax.servlet.ServletResponse;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.springframework.beans.BeansException;
34  import org.springframework.beans.factory.BeanInitializationException;
35  import org.springframework.context.ApplicationContext;
36  import org.springframework.context.ApplicationContextAware;
37  import org.springframework.context.ApplicationEvent;
38  import org.springframework.context.ApplicationListener;
39  import org.springframework.context.event.ContextRefreshedEvent;
40  import org.springframework.extensions.config.Config;
41  import org.springframework.extensions.config.ConfigService;
42  import org.springframework.extensions.config.RemoteConfigElement;
43  import org.springframework.extensions.config.WebFrameworkConfigElement;
44  import org.springframework.extensions.surf.render.RenderService;
45  import org.springframework.extensions.surf.render.TagService;
46  import org.springframework.extensions.surf.resource.ResourceService;
47  import org.springframework.extensions.webscripts.Container;
48  import org.springframework.extensions.webscripts.ScriptRemote;
49  import org.springframework.extensions.webscripts.connector.ConnectorService;
50  import org.springframework.web.context.ServletContextAware;
51  import org.springframework.web.context.support.WebApplicationContextUtils;
52  
53  import freemarker.ext.jsp.TaglibFactory;
54  import freemarker.ext.servlet.ServletContextHashModel;
55  import freemarker.template.ObjectWrapper;
56  
57  /**
58   * Service Registry for Web Framework
59   * 
60   * This service provides getters for all Web Framework services and
61   * helper beans.
62   * 
63   * @author muzquiano
64   */
65  public class WebFrameworkServiceRegistry implements ApplicationContextAware, ServletContextAware, ApplicationListener
66  {
67      private static final Log logger = LogFactory.getLog(WebFrameworkServiceRegistry.class);
68          
69      private ApplicationContext applicationContext;
70      private ServletContext servletContext;
71          
72      // web framework service registry singleton
73      public static final String WEB_FRAMEWORK_SERVICE_REGISTRY_ID = "webframework.serviceregistry";
74      
75      // core service bean ids
76      private static final String CONFIG_SERVICE_ID = "web.config";
77      private static final String WEB_FRAMEWORK_MANAGER_ID = "webframework.manager";
78      private static final String WEB_FRAMEWORK_RENDER_SERVICE_ID = "webframework.service.render";
79      private static final String WEB_FRAMEWORK_RESOURCE_SERVICE_ID = "webframework.service.resource";
80      private static final String WEB_FRAMEWORK_TAG_SERVICE_ID = "webframework.service.tag";
81      private static final String CONNECTOR_SERVICE_ID = "connector.service";
82      private static final String PRESETS_MANAGER_ID = "webframework.presets.manager";
83      private static final String SCRIPT_REMOTE_ID = "webframework.webscripts.scriptremote";
84      private static final String WEBFRAMEWORK_TEMPLATES_CONTAINER_ID = "webframework.templates.container";
85      
86      // core service beans
87      private ConfigService configService;
88      private WebFrameworkManager webFrameworkManager;
89      private RenderService webFrameworkRenderService;
90      private ResourceService webFrameworkResourceService;
91      private TagService webFrameworkTagService;
92      private ConnectorService connectorService;
93      private PresetsManager presetsManager;
94      private ScriptRemote scriptRemote;
95      
96      // extensible service bean ids
97      private static final String PAGE_MAPPER_FACTORY_ID = "webframework.factory.pagemapper";
98      private static final String LINK_BUILDER_FACTORY_ID = "webframework.factory.linkbuilder";
99      private static final String USER_FACTORY_ID = "webframework.factory.userfactory";
100     private static final String REQUEST_CONTEXT_FACTORY_ID = "webframework.factory.requestcontext";
101     
102     // extensible service beans
103     private PageMapperFactory pageMapperFactory;
104     private LinkBuilderFactory linkBuilderFactory;
105     private UserFactory userFactory;
106     private RequestContextFactory requestContextFactory;
107     
108     // configuration elements
109     private RemoteConfigElement remoteConfigElement;
110     private WebFrameworkConfigElement webFrameworkConfigElement;
111     
112     // web framework webscripts container
113     private static final String WEBFRAMEWORK_WEBSCRIPTS_CONTAINER_ID = "webscripts.container";
114     private Container webFrameworkContainer;
115     
116     // templates container
117     private TemplatesContainer templatesContainer;
118     
119     // precomputed hash models for use by processors
120     private static TaglibFactory taglibFactory;
121     private static ServletContextHashModel servletContextHashModel;
122     
123         
124     /**
125      * Helper method for retrieving the service registry bound to the
126      * current application context.
127      * 
128      * @return
129      */
130     public static WebFrameworkServiceRegistry getInstance(ServletContext servletContext)
131     {
132         ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
133         
134         return (WebFrameworkServiceRegistry) applicationContext.getBean(WEB_FRAMEWORK_SERVICE_REGISTRY_ID);
135     }
136     
137     /* (non-Javadoc)
138      * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
139      */
140     public void setApplicationContext(ApplicationContext applicationContext)
141         throws BeansException
142     {
143         this.applicationContext = applicationContext;
144     }
145     
146     /* (non-Javadoc)
147      * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext)
148      */
149     public void setServletContext(ServletContext servletContext)
150         throws BeansException
151     {
152         this.servletContext = servletContext;
153     }
154     
155     /**
156      * Gets the application context.
157      * 
158      * @return the application context
159      */
160     public ApplicationContext getApplicationContext()
161     {
162         return this.applicationContext;
163     }
164     
165     /**
166      * Gets the servlet context.
167      * 
168      * @return the servlet context
169      */
170     public ServletContext getServletContext()
171     {
172         return this.servletContext;
173     }
174     
175     /**
176      * Sets the request context factory.
177      * 
178      * @param requestContextFactory the new request context factory
179      */
180     public void setRequestContextFactory(RequestContextFactory requestContextFactory)
181     {
182         this.requestContextFactory = requestContextFactory;
183     }
184     
185     /**
186      * Sets the page mapper factory.
187      * 
188      * @param pageMapperFactory the new page mapper factory
189      */
190     public void setPageMapperFactory(PageMapperFactory pageMapperFactory)
191     {
192         this.pageMapperFactory = pageMapperFactory;
193     }
194     
195     /**
196      * Sets the link builder factory.
197      * 
198      * @param linkBuilderFactory the new link builder factory
199      */
200     public void setLinkBuilderFactory(LinkBuilderFactory linkBuilderFactory)
201     {
202         this.linkBuilderFactory = linkBuilderFactory;
203     }
204     
205     /**
206      * Sets the user factory.
207      * 
208      * @param userFactory the new user factory
209      */
210     public void setUserFactory(UserFactory userFactory)
211     {
212         this.userFactory = userFactory;
213     }
214     
215     /* (non-Javadoc)
216      * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
217      */
218     public void onApplicationEvent(ApplicationEvent event)
219     {
220         if (event instanceof ContextRefreshedEvent)
221         {
222             ContextRefreshedEvent refreshEvent = (ContextRefreshedEvent)event;            
223             ApplicationContext refreshContext = refreshEvent.getApplicationContext();
224             if (refreshContext != null && refreshContext.equals(getApplicationContext()))
225             {
226                 onBootstrap();
227             }
228         }
229     }
230     
231     
232     /**
233      * Initialization of the Web Framework Service Registry
234      */
235     protected void onBootstrap()
236     {
237         // retrieve all core framework services        
238         configService = (ConfigService) applicationContext.getBean(CONFIG_SERVICE_ID);
239         webFrameworkManager = (WebFrameworkManager) applicationContext.getBean(WEB_FRAMEWORK_MANAGER_ID);
240         webFrameworkRenderService = (RenderService) applicationContext.getBean(WEB_FRAMEWORK_RENDER_SERVICE_ID);
241         webFrameworkResourceService = (ResourceService) applicationContext.getBean(WEB_FRAMEWORK_RESOURCE_SERVICE_ID);
242         webFrameworkTagService = (TagService) applicationContext.getBean(WEB_FRAMEWORK_TAG_SERVICE_ID);
243         connectorService = (ConnectorService) applicationContext.getBean(CONNECTOR_SERVICE_ID);
244         presetsManager = (PresetsManager) applicationContext.getBean(PRESETS_MANAGER_ID);
245         scriptRemote = (ScriptRemote) applicationContext.getBean(SCRIPT_REMOTE_ID);
246         
247         // web framework container
248         webFrameworkContainer = (Container) applicationContext.getBean(WEBFRAMEWORK_WEBSCRIPTS_CONTAINER_ID);
249         
250         // template container
251         templatesContainer = (TemplatesContainer) applicationContext.getBean(WEBFRAMEWORK_TEMPLATES_CONTAINER_ID);
252         
253         // retrieve configuration elements
254         Config remoteConfig = configService.getConfig("Remote");
255         remoteConfigElement = (RemoteConfigElement) remoteConfig.getConfigElement("remote");
256         Config webFrameworkConfig = configService.getConfig("WebFramework");
257         webFrameworkConfigElement = (WebFrameworkConfigElement) webFrameworkConfig.getConfigElement("web-framework");
258         
259         // extensible services
260         // use defaults if not otherwise set
261         if (pageMapperFactory == null)
262         {
263             pageMapperFactory = (PageMapperFactory) applicationContext.getBean(PAGE_MAPPER_FACTORY_ID);
264         }
265         if (linkBuilderFactory == null)
266         {
267             linkBuilderFactory = (LinkBuilderFactory) applicationContext.getBean(LINK_BUILDER_FACTORY_ID);
268         }
269         if (userFactory == null)
270         {
271             userFactory = (UserFactory) applicationContext.getBean(USER_FACTORY_ID);
272         }
273         if (requestContextFactory == null)
274         {
275             requestContextFactory = (RequestContextFactory) applicationContext.getBean(REQUEST_CONTEXT_FACTORY_ID);
276         }
277         
278         // build tag library container
279         taglibFactory = new TaglibFactory(servletContext);
280 
281         // build the servlet context hash model
282         GenericServlet servlet = new GenericServletAdapter();
283         try {
284             servlet.init(new DelegatingServletConfig(servletContext));
285         }
286         catch (ServletException ex) {
287             throw new BeanInitializationException("Initialization of GenericServlet adapter failed", ex);
288         }        
289         servletContextHashModel = new ServletContextHashModel(servlet, ObjectWrapper.DEFAULT_WRAPPER);        
290     }
291     
292     /**
293      * Gets the config service.
294      * 
295      * @return the config service
296      */
297     public ConfigService getConfigService()
298     {
299         return this.configService;
300     }
301     
302     /**
303      * Gets the web framework manager.
304      * 
305      * @return the web framework manager
306      */
307     public WebFrameworkManager getWebFrameworkManager()
308     {
309         return this.webFrameworkManager;
310     }
311 
312     /**
313      * Gets the web framework render service.
314      * 
315      * @return the web framework render service
316      */
317     public RenderService getRenderService()
318     {
319         return this.webFrameworkRenderService;
320     }
321     
322     /**
323      * Gets the resource service.
324      * 
325      * @return the resource service
326      */
327     public ResourceService getResourceService()
328     {
329         return this.webFrameworkResourceService;
330     }
331     
332     /**
333      * Gets the tag service.
334      * 
335      * @return the tag service
336      */
337     public TagService getTagService()
338     {
339         return this.webFrameworkTagService;
340     }
341     
342     /**
343      * Gets the connector service.
344      * 
345      * @return the connector service
346      */
347     public ConnectorService getConnectorService()
348     {
349         return this.connectorService;
350     }
351     
352     /**
353      * Gets the presets manager.
354      * 
355      * @return the presets manager
356      */
357     public PresetsManager getPresetsManager()
358     {
359         return this.presetsManager;
360     }
361     
362     /**
363      * Gets the script remote.
364      * 
365      * @return the script remote
366      */
367     public ScriptRemote getScriptRemote()
368     {
369         return this.scriptRemote;
370     }
371     
372     /**
373      * Gets the remote configuration.
374      * 
375      * @return the remote configuration
376      */
377     public RemoteConfigElement getRemoteConfiguration()
378     {
379         return this.remoteConfigElement;
380     }
381     
382     /**
383      * Gets the web framework configuration.
384      * 
385      * @return the web framework configuration
386      */
387     public WebFrameworkConfigElement getWebFrameworkConfiguration()
388     {
389         return this.webFrameworkConfigElement;
390     }
391     
392     /**
393      * Gets the page mapper factory.
394      * 
395      * @return the page mapper factory
396      */
397     public PageMapperFactory getPageMapperFactory()
398     {
399         return this.pageMapperFactory;
400     }
401     
402     /**
403      * Gets the link builder factory.
404      * 
405      * @return the link builder factory
406      */
407     public LinkBuilderFactory getLinkBuilderFactory()
408     {
409         return this.linkBuilderFactory;
410     }
411     
412     /**
413      * Gets the user factory.
414      * 
415      * @return the user factory
416      */
417     public UserFactory getUserFactory()
418     {
419         return this.userFactory;
420     }
421     
422     /**
423      * Gets the request context factory.
424      * 
425      * @return the request context factory
426      */
427     public RequestContextFactory getRequestContextFactory()
428     {
429         return this.requestContextFactory;
430     }
431     
432     /**
433      * Gets the web framework container.
434      * 
435      * @return the web framework container
436      */
437     public Container getWebFrameworkContainer()
438     {
439         return this.webFrameworkContainer;
440     }
441     
442     /**
443      * Gets the templates container.
444      * 
445      * @return the templates container
446      */
447     public TemplatesContainer getTemplatesContainer()
448     {
449         return this.templatesContainer;
450     }
451     
452     /**
453      * Gets the taglib factory.
454      * 
455      * @return the taglib factory
456      */
457     public TaglibFactory getTaglibFactory()
458     {
459         return taglibFactory;
460     }
461     
462     /**
463      * Gets the servlet context hash model.
464      * 
465      * @return the servlet context hash model
466      */
467     public ServletContextHashModel getServletContextHashModel()
468     {
469         return servletContextHashModel;
470     }        
471     
472     /**
473      * Simple adapter class that extends {@link GenericServlet}.
474      * Needed to support generic JSP tag libraries in FreeMarker.
475      */
476     private class GenericServletAdapter extends GenericServlet 
477     {
478         public void service(ServletRequest servletRequest, ServletResponse servletResponse) 
479         {
480             // no-op
481         }
482     }
483 
484     /**
485      * Internal implementation of the {@link ServletConfig} interface,
486      * to be passed to the servlet adapter.
487      */
488     private class DelegatingServletConfig implements ServletConfig 
489     {
490         private ServletContext servletContext = null;
491         
492         public DelegatingServletConfig(ServletContext servletContext)
493         {
494             this.servletContext = servletContext;
495         }
496         
497         public String getServletName() 
498         {
499             return FrameworkUtil.class.getSimpleName();
500         }
501 
502         public ServletContext getServletContext() 
503         {
504             return servletContext;
505         }
506 
507         public String getInitParameter(String paramName) 
508         {
509             return null;
510         }
511 
512         public Enumeration getInitParameterNames() 
513         {
514             return Collections.enumeration(Collections.EMPTY_SET);
515         }
516     }
517 }