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