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