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