001
014
015 package com.liferay.portlet;
016
017 import com.liferay.portal.dao.shard.ShardPollerProcessorWrapper;
018 import com.liferay.portal.kernel.lar.PortletDataHandler;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.poller.PollerProcessor;
022 import com.liferay.portal.kernel.pop.MessageListener;
023 import com.liferay.portal.kernel.portlet.ConfigurationAction;
024 import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
025 import com.liferay.portal.kernel.portlet.PortletBag;
026 import com.liferay.portal.kernel.portlet.PortletBagPool;
027 import com.liferay.portal.kernel.portlet.PortletLayoutListener;
028 import com.liferay.portal.kernel.portlet.Route;
029 import com.liferay.portal.kernel.portlet.Router;
030 import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
031 import com.liferay.portal.kernel.scheduler.SchedulerEntry;
032 import com.liferay.portal.kernel.scheduler.SchedulerException;
033 import com.liferay.portal.kernel.search.Indexer;
034 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
035 import com.liferay.portal.kernel.search.OpenSearch;
036 import com.liferay.portal.kernel.servlet.ServletContextPool;
037 import com.liferay.portal.kernel.servlet.URLEncoder;
038 import com.liferay.portal.kernel.util.LocaleUtil;
039 import com.liferay.portal.kernel.util.MethodInvoker;
040 import com.liferay.portal.kernel.util.MethodWrapper;
041 import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
042 import com.liferay.portal.kernel.util.PrefsPropsUtil;
043 import com.liferay.portal.kernel.util.ProxyFactory;
044 import com.liferay.portal.kernel.util.SetUtil;
045 import com.liferay.portal.kernel.util.StringUtil;
046 import com.liferay.portal.kernel.util.Validator;
047 import com.liferay.portal.kernel.webdav.WebDAVStorage;
048 import com.liferay.portal.kernel.webdav.WebDAVUtil;
049 import com.liferay.portal.kernel.workflow.WorkflowHandler;
050 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
051 import com.liferay.portal.kernel.xml.Document;
052 import com.liferay.portal.kernel.xml.Element;
053 import com.liferay.portal.kernel.xml.SAXReaderUtil;
054 import com.liferay.portal.kernel.xmlrpc.Method;
055 import com.liferay.portal.model.Portlet;
056 import com.liferay.portal.model.PortletApp;
057 import com.liferay.portal.poller.PollerProcessorUtil;
058 import com.liferay.portal.pop.POPServerUtil;
059 import com.liferay.portal.service.PortletLocalServiceUtil;
060 import com.liferay.portal.util.PortalUtil;
061 import com.liferay.portal.util.PropsValues;
062 import com.liferay.portal.xmlrpc.XmlRpcServlet;
063 import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
064 import com.liferay.portlet.asset.model.AssetRendererFactory;
065 import com.liferay.portlet.expando.model.CustomAttributesDisplay;
066 import com.liferay.portlet.social.model.SocialActivityInterpreter;
067 import com.liferay.portlet.social.model.SocialRequestInterpreter;
068 import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
069 import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
070 import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
071 import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
072 import com.liferay.util.portlet.PortletProps;
073
074 import java.util.ArrayList;
075 import java.util.HashMap;
076 import java.util.List;
077 import java.util.Locale;
078 import java.util.Map;
079 import java.util.MissingResourceException;
080 import java.util.ResourceBundle;
081 import java.util.Set;
082
083 import javax.portlet.PreferencesValidator;
084
085 import javax.servlet.ServletContext;
086
087
093 public class PortletBagFactory {
094
095 public PortletBag create(Portlet portlet) throws Exception {
096 PortletApp portletApp = portlet.getPortletApp();
097
098 if (!portletApp.isWARFile() && _warFile) {
099 String contextPath = PortalUtil.getPathContext();
100
101 _servletContext = ServletContextPool.get(contextPath);
102
103 _classLoader = PortalClassLoaderUtil.getClassLoader();
104 }
105
106 Class<?> portletClass = null;
107
108 try {
109 portletClass = _classLoader.loadClass(portlet.getPortletClass());
110 }
111 catch (Throwable e) {
112 _log.error(e, e);
113
114 PortletLocalServiceUtil.destroyPortlet(portlet);
115
116 return null;
117 }
118
119 javax.portlet.Portlet portletInstance =
120 (javax.portlet.Portlet)portletClass.newInstance();
121
122 ConfigurationAction configurationActionInstance =
123 newConfigurationAction(portlet);
124
125 Indexer indexerInstance = newIndexer(portlet);
126
127 OpenSearch openSearchInstance = newOpenSearch(portlet);
128
129 initSchedulers(portlet);
130
131 FriendlyURLMapper friendlyURLMapperInstance = newFriendlyURLMapper(
132 portlet);
133
134 URLEncoder urlEncoderInstance = newURLEncoder(portlet);
135
136 PortletDataHandler portletDataHandlerInstance = newPortletDataHandler(
137 portlet);
138
139 PortletLayoutListener portletLayoutListenerInstance =
140 newPortletLayoutListener(portlet);
141
142 PollerProcessor pollerProcessorInstance = newPollerProcessor(portlet);
143
144 MessageListener popMessageListenerInstance = newPOPMessageListener(
145 portlet);
146
147 SocialActivityInterpreter socialActivityInterpreterInstance =
148 initSocialActivityInterpreterInstance(portlet);
149
150 SocialRequestInterpreter socialRequestInterpreterInstance = null;
151
152 if (Validator.isNotNull(portlet.getSocialRequestInterpreterClass())) {
153 socialRequestInterpreterInstance =
154 (SocialRequestInterpreter)newInstance(
155 SocialRequestInterpreter.class,
156 portlet.getSocialRequestInterpreterClass());
157
158 socialRequestInterpreterInstance = new SocialRequestInterpreterImpl(
159 portlet.getPortletId(), socialRequestInterpreterInstance);
160
161 SocialRequestInterpreterLocalServiceUtil.addRequestInterpreter(
162 socialRequestInterpreterInstance);
163 }
164
165 WebDAVStorage webDAVStorageInstance = null;
166
167 if (Validator.isNotNull(portlet.getWebDAVStorageClass())) {
168 webDAVStorageInstance = (WebDAVStorage)newInstance(
169 WebDAVStorage.class, portlet.getWebDAVStorageClass());
170
171 webDAVStorageInstance.setToken(portlet.getWebDAVStorageToken());
172
173 WebDAVUtil.addStorage(webDAVStorageInstance);
174 }
175
176 Method xmlRpcMethodInstance = null;
177
178 if (Validator.isNotNull(portlet.getXmlRpcMethodClass())) {
179 xmlRpcMethodInstance = (Method)newInstance(
180 Method.class, portlet.getXmlRpcMethodClass());
181
182 XmlRpcServlet.registerMethod(xmlRpcMethodInstance);
183 }
184
185 ControlPanelEntry controlPanelEntryInstance = null;
186
187 if (Validator.isNotNull(portlet.getControlPanelEntryClass())) {
188 controlPanelEntryInstance = (ControlPanelEntry)newInstance(
189 ControlPanelEntry.class, portlet.getControlPanelEntryClass());
190 }
191
192 List<AssetRendererFactory> assetRendererFactoryInstances =
193 newAssetRendererFactoryInstances(portlet);
194
195 List<CustomAttributesDisplay> customAttributesDisplayInstances =
196 new ArrayList<CustomAttributesDisplay>();
197
198 for (String customAttributesDisplayClass :
199 portlet.getCustomAttributesDisplayClasses()) {
200
201 CustomAttributesDisplay customAttributesDisplayInstance =
202 (CustomAttributesDisplay)newInstance(
203 CustomAttributesDisplay.class,
204 customAttributesDisplayClass);
205
206 customAttributesDisplayInstance.setClassNameId(
207 PortalUtil.getClassNameId(
208 customAttributesDisplayInstance.getClassName()));
209 customAttributesDisplayInstance.setPortletId(
210 portlet.getPortletId());
211
212 customAttributesDisplayInstances.add(
213 customAttributesDisplayInstance);
214 }
215
216 List<WorkflowHandler> workflowHandlerInstances =
217 new ArrayList<WorkflowHandler>();
218
219 for (String workflowHandlerClass :
220 portlet.getWorkflowHandlerClasses()) {
221
222 WorkflowHandler workflowHandlerInstance =
223 (WorkflowHandler)newInstance(
224 WorkflowHandler.class, workflowHandlerClass);
225
226 workflowHandlerInstances.add(workflowHandlerInstance);
227
228 WorkflowHandlerRegistryUtil.register(workflowHandlerInstance);
229 }
230
231 PreferencesValidator preferencesValidatorInstance = null;
232
233 if (Validator.isNotNull(portlet.getPreferencesValidator())) {
234 preferencesValidatorInstance = (PreferencesValidator)newInstance(
235 PreferencesValidator.class, portlet.getPreferencesValidator());
236
237 try {
238 if (PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
239 preferencesValidatorInstance.validate(
240 PortletPreferencesSerializer.fromDefaultXML(
241 portlet.getDefaultPreferences()));
242 }
243 }
244 catch (Exception e) {
245 _log.warn(
246 "Portlet with the name " + portlet.getPortletId() +
247 " does not have valid default preferences");
248 }
249 }
250
251 Map<String, ResourceBundle> resourceBundles = null;
252
253 if (Validator.isNotNull(portlet.getResourceBundle())) {
254 resourceBundles = new HashMap<String, ResourceBundle>();
255
256 initResourceBundle(
257 resourceBundles, portlet, LocaleUtil.getDefault());
258
259 Set<String> supportedLocales = portlet.getSupportedLocales();
260
261 if (supportedLocales.isEmpty()) {
262 supportedLocales = SetUtil.fromArray(PropsValues.LOCALES);
263 }
264
265 for (String supportedLocale : supportedLocales) {
266 Locale locale = LocaleUtil.fromLanguageId(supportedLocale);
267
268 initResourceBundle(resourceBundles, portlet, locale);
269 }
270 }
271
272 PortletBag portletBag = new PortletBagImpl(
273 portlet.getPortletId(), _servletContext, portletInstance,
274 configurationActionInstance, indexerInstance, openSearchInstance,
275 friendlyURLMapperInstance, urlEncoderInstance,
276 portletDataHandlerInstance, portletLayoutListenerInstance,
277 pollerProcessorInstance, popMessageListenerInstance,
278 socialActivityInterpreterInstance, socialRequestInterpreterInstance,
279 webDAVStorageInstance, xmlRpcMethodInstance,
280 controlPanelEntryInstance, assetRendererFactoryInstances,
281 customAttributesDisplayInstances, workflowHandlerInstances,
282 preferencesValidatorInstance, resourceBundles);
283
284 PortletBagPool.put(portlet.getRootPortletId(), portletBag);
285
286 try {
287 PortletInstanceFactoryUtil.create(portlet, _servletContext);
288 }
289 catch (Exception e) {
290 _log.error(e, e);
291 }
292
293 return portletBag;
294 }
295
296 public void setClassLoader(ClassLoader classLoader) {
297 _classLoader = classLoader;
298 }
299
300 public void setServletContext(ServletContext servletContext) {
301 _servletContext = servletContext;
302 }
303
304 public void setWARFile(boolean warFile) {
305 _warFile = warFile;
306 }
307
308 protected void initResourceBundle(
309 Map<String, ResourceBundle> resourceBundles, Portlet portlet,
310 Locale locale) {
311
312 try {
313 ResourceBundle resourceBundle = ResourceBundle.getBundle(
314 portlet.getResourceBundle(), locale, _classLoader);
315
316 resourceBundles.put(
317 LocaleUtil.toLanguageId(locale), resourceBundle);
318 }
319 catch (MissingResourceException mre) {
320 _log.warn(mre.getMessage());
321 }
322 }
323
324 protected void initScheduler(SchedulerEntry schedulerEntry)
325 throws Exception {
326
327 String propertyKey = schedulerEntry.getPropertyKey();
328
329 if (Validator.isNotNull(propertyKey)) {
330 String triggerValue = null;
331
332 if (_warFile) {
333 Thread currentThread = Thread.currentThread();
334
335 ClassLoader contextClassLoader =
336 currentThread.getContextClassLoader();
337
338 try {
339 currentThread.setContextClassLoader(_classLoader);
340
341 MethodWrapper methodWrapper = new MethodWrapper(
342 PortletProps.class.getName(), "get", propertyKey);
343
344 triggerValue = (String)MethodInvoker.invoke(
345 methodWrapper, false);
346 }
347 finally {
348 currentThread.setContextClassLoader(contextClassLoader);
349 }
350 }
351 else {
352 triggerValue = PrefsPropsUtil.getString(propertyKey);
353 }
354
355 if (_log.isDebugEnabled()) {
356 _log.debug(
357 "Scheduler property key " + propertyKey +
358 " has trigger value " + triggerValue);
359 }
360
361 if (Validator.isNull(triggerValue)) {
362 throw new SchedulerException(
363 "Property key " + propertyKey + " requires a value");
364 }
365
366 schedulerEntry.setTriggerValue(triggerValue);
367 }
368
369 SchedulerEngineUtil.schedule(schedulerEntry, _classLoader);
370 }
371
372 protected void initSchedulers(Portlet portlet) throws Exception {
373 if (!PropsValues.SCHEDULER_ENABLED){
374 return;
375 }
376
377 List<SchedulerEntry> schedulerEntries = portlet.getSchedulerEntries();
378
379 if ((schedulerEntries == null) || schedulerEntries.isEmpty()) {
380 return;
381 }
382
383 for (SchedulerEntry schedulerEntry : schedulerEntries) {
384 initScheduler(schedulerEntry);
385 }
386 }
387
388 protected SocialActivityInterpreter initSocialActivityInterpreterInstance(
389 Portlet portlet)
390 throws Exception {
391
392 if (Validator.isNull(portlet.getSocialActivityInterpreterClass())) {
393 return null;
394 }
395
396 SocialActivityInterpreter socialActivityInterpreterInstance =
397 (SocialActivityInterpreter)newInstance(
398 SocialActivityInterpreter.class,
399 portlet.getSocialActivityInterpreterClass());
400
401 socialActivityInterpreterInstance =
402 new SocialActivityInterpreterImpl(
403 portlet.getPortletId(), socialActivityInterpreterInstance);
404
405 SocialActivityInterpreterLocalServiceUtil.addActivityInterpreter(
406 socialActivityInterpreterInstance);
407
408 return socialActivityInterpreterInstance;
409 }
410
411 protected AssetRendererFactory newAssetRendererFactoryInstance(
412 Portlet portlet, String assetRendererFactoryClass)
413 throws Exception {
414
415 AssetRendererFactory assetRendererFactoryInstance =
416 (AssetRendererFactory)newInstance(
417 AssetRendererFactory.class, assetRendererFactoryClass);
418
419 assetRendererFactoryInstance.setClassNameId(
420 PortalUtil.getClassNameId(
421 assetRendererFactoryInstance.getClassName()));
422 assetRendererFactoryInstance.setPortletId(portlet.getPortletId());
423
424 AssetRendererFactoryRegistryUtil.register(assetRendererFactoryInstance);
425
426 return assetRendererFactoryInstance;
427 }
428
429 protected List<AssetRendererFactory> newAssetRendererFactoryInstances(
430 Portlet portlet)
431 throws Exception {
432
433 List<AssetRendererFactory> assetRendererFactoryInstances =
434 new ArrayList<AssetRendererFactory>();
435
436 for (String assetRendererFactoryClass :
437 portlet.getAssetRendererFactoryClasses()) {
438
439 AssetRendererFactory assetRendererFactoryInstance =
440 newAssetRendererFactoryInstance(
441 portlet, assetRendererFactoryClass);
442
443 assetRendererFactoryInstances.add(assetRendererFactoryInstance);
444 }
445
446 return assetRendererFactoryInstances;
447 }
448
449 protected ConfigurationAction newConfigurationAction(Portlet portlet)
450 throws Exception {
451
452 if (Validator.isNull(portlet.getConfigurationActionClass())) {
453 return null;
454 }
455
456 return (ConfigurationAction)newInstance(
457 ConfigurationAction.class, portlet.getConfigurationActionClass());
458 }
459
460 protected FriendlyURLMapper newFriendlyURLMapper(Portlet portlet)
461 throws Exception {
462
463 if (Validator.isNull(portlet.getFriendlyURLMapperClass())) {
464 return null;
465 }
466
467 FriendlyURLMapper friendlyURLMapper = (FriendlyURLMapper)newInstance(
468 FriendlyURLMapper.class, portlet.getFriendlyURLMapperClass());
469
470 friendlyURLMapper.setMapping(portlet.getFriendlyURLMapping());
471 friendlyURLMapper.setPortletId(portlet.getPortletId());
472 friendlyURLMapper.setPortletInstanceable(portlet.isInstanceable());
473
474 Router router = newFriendlyURLRouter(portlet);
475
476 friendlyURLMapper.setRouter(router);
477
478 return friendlyURLMapper;
479 }
480
481 protected Router newFriendlyURLRouter(Portlet portlet) throws Exception {
482 if (Validator.isNull(portlet.getFriendlyURLRoutes())) {
483 return null;
484 }
485
486 Router router = new RouterImpl();
487
488 String xml = StringUtil.read(
489 _classLoader, portlet.getFriendlyURLRoutes());
490
491 Document document = SAXReaderUtil.read(xml, true);
492
493 Element rootElement = document.getRootElement();
494
495 for (Element routeElement : rootElement.elements("route")) {
496 String pattern = routeElement.elementText("pattern");
497
498 Route route = router.addRoute(pattern);
499
500 for (Element generatedParameterElement :
501 routeElement.elements("generated-parameter")) {
502
503 String name = generatedParameterElement.attributeValue("name");
504 String value = generatedParameterElement.getText();
505
506 route.addGeneratedParameter(name, value);
507 }
508
509 for (Element ignoredParameterElement :
510 routeElement.elements("ignored-parameter")) {
511
512 String name = ignoredParameterElement.attributeValue("name");
513
514 route.addIgnoredParameter(name);
515 }
516
517 for (Element implicitParameterElement :
518 routeElement.elements("implicit-parameter")) {
519
520 String name = implicitParameterElement.attributeValue("name");
521 String value = implicitParameterElement.getText();
522
523 route.addImplicitParameter(name, value);
524 }
525
526 for (Element overriddenParameterElement :
527 routeElement.elements("overridden-parameter")) {
528
529 String name = overriddenParameterElement.attributeValue("name");
530 String value = overriddenParameterElement.getText();
531
532 route.addOverriddenParameter(name, value);
533 }
534 }
535
536 return router;
537 }
538
539 protected Indexer newIndexer(Portlet portlet) throws Exception {
540 if (Validator.isNull(portlet.getIndexerClass())) {
541 return null;
542 }
543
544 Indexer indexerInstance = (Indexer)newInstance(
545 Indexer.class, portlet.getIndexerClass());
546
547 IndexerRegistryUtil.register(indexerInstance);
548
549 return indexerInstance;
550 }
551
552 protected Object newInstance(Class<?> interfaceClass, String implClassName)
553 throws Exception {
554
555 return newInstance(new Class[] {interfaceClass}, implClassName);
556 }
557
558 protected Object newInstance(
559 Class<?>[] interfaceClasses, String implClassName)
560 throws Exception {
561
562 if (_warFile) {
563 return ProxyFactory.newInstance(
564 _classLoader, interfaceClasses, implClassName);
565 }
566 else {
567 Class<?> classObj = _classLoader.loadClass(implClassName);
568
569 return classObj.newInstance();
570 }
571 }
572
573 protected OpenSearch newOpenSearch(Portlet portlet) throws Exception {
574 if (Validator.isNull(portlet.getOpenSearchClass())) {
575 return null;
576 }
577
578 return (OpenSearch)newInstance(
579 OpenSearch.class, portlet.getOpenSearchClass());
580 }
581
582 protected PollerProcessor newPollerProcessor(Portlet portlet)
583 throws Exception {
584
585 if (Validator.isNull(portlet.getPollerProcessorClass())) {
586 return null;
587 }
588
589 PollerProcessor pollerProcessorInstance = (PollerProcessor)newInstance(
590 PollerProcessor.class, portlet.getPollerProcessorClass());
591
592 PollerProcessorUtil.addPollerProcessor(
593 portlet.getPortletId(),
594 new ShardPollerProcessorWrapper(pollerProcessorInstance));
595
596 return pollerProcessorInstance;
597 }
598
599 protected MessageListener newPOPMessageListener(Portlet portlet)
600 throws Exception {
601
602 if (Validator.isNull(portlet.getPopMessageListenerClass())) {
603 return null;
604 }
605
606 MessageListener popMessageListenerInstance =
607 (MessageListener)newInstance(
608 MessageListener.class, portlet.getPopMessageListenerClass());
609
610 POPServerUtil.addListener(popMessageListenerInstance);
611
612 return popMessageListenerInstance;
613 }
614
615 protected PortletDataHandler newPortletDataHandler(Portlet portlet)
616 throws Exception {
617
618 if (Validator.isNull(portlet.getPortletDataHandlerClass())) {
619 return null;
620 }
621
622 return (PortletDataHandler)newInstance(
623 PortletDataHandler.class, portlet.getPortletDataHandlerClass());
624 }
625
626 protected PortletLayoutListener newPortletLayoutListener(Portlet portlet)
627 throws Exception {
628
629 if (Validator.isNull(portlet.getPortletLayoutListenerClass())) {
630 return null;
631 }
632
633 return (PortletLayoutListener)newInstance(
634 PortletLayoutListener.class,
635 portlet.getPortletLayoutListenerClass());
636 }
637
638 protected URLEncoder newURLEncoder(Portlet portlet) throws Exception {
639 if (Validator.isNull(portlet.getURLEncoderClass())) {
640 return null;
641 }
642
643 return (URLEncoder)newInstance(
644 URLEncoder.class, portlet.getURLEncoderClass());
645 }
646
647 private static Log _log = LogFactoryUtil.getLog(PortletBagFactory.class);
648
649 private ClassLoader _classLoader;
650 private ServletContext _servletContext;
651 private boolean _warFile;
652
653 }