001
014
015 package com.liferay.portal.deploy.hot;
016
017 import com.liferay.portal.apache.bridges.struts.LiferayServletContextProvider;
018 import com.liferay.portal.kernel.atom.AtomCollectionAdapter;
019 import com.liferay.portal.kernel.atom.AtomCollectionAdapterRegistryUtil;
020 import com.liferay.portal.kernel.configuration.Configuration;
021 import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
022 import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
023 import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
024 import com.liferay.portal.kernel.deploy.hot.HotDeployException;
025 import com.liferay.portal.kernel.javadoc.JavadocManagerUtil;
026 import com.liferay.portal.kernel.language.LanguageUtil;
027 import com.liferay.portal.kernel.lar.StagedModelDataHandler;
028 import com.liferay.portal.kernel.lar.StagedModelDataHandlerRegistryUtil;
029 import com.liferay.portal.kernel.log.Log;
030 import com.liferay.portal.kernel.log.LogFactoryUtil;
031 import com.liferay.portal.kernel.notifications.UserNotificationHandler;
032 import com.liferay.portal.kernel.notifications.UserNotificationManagerUtil;
033 import com.liferay.portal.kernel.portlet.PortletBag;
034 import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
035 import com.liferay.portal.kernel.scheduler.SchedulerEntry;
036 import com.liferay.portal.kernel.scheduler.StorageType;
037 import com.liferay.portal.kernel.search.Indexer;
038 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
039 import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil;
040 import com.liferay.portal.kernel.servlet.FileTimestampUtil;
041 import com.liferay.portal.kernel.servlet.PortletServlet;
042 import com.liferay.portal.kernel.servlet.ServletContextPool;
043 import com.liferay.portal.kernel.servlet.ServletContextProvider;
044 import com.liferay.portal.kernel.trash.TrashHandler;
045 import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
046 import com.liferay.portal.kernel.util.ClassUtil;
047 import com.liferay.portal.kernel.util.GetterUtil;
048 import com.liferay.portal.kernel.util.HttpUtil;
049 import com.liferay.portal.kernel.util.InfrastructureUtil;
050 import com.liferay.portal.kernel.util.LocaleUtil;
051 import com.liferay.portal.kernel.util.PropsKeys;
052 import com.liferay.portal.kernel.util.ServerDetector;
053 import com.liferay.portal.kernel.util.StringUtil;
054 import com.liferay.portal.kernel.util.Validator;
055 import com.liferay.portal.kernel.webdav.WebDAVUtil;
056 import com.liferay.portal.kernel.workflow.WorkflowHandler;
057 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
058 import com.liferay.portal.model.Portlet;
059 import com.liferay.portal.model.PortletApp;
060 import com.liferay.portal.model.PortletCategory;
061 import com.liferay.portal.model.PortletFilter;
062 import com.liferay.portal.model.PortletURLListener;
063 import com.liferay.portal.poller.PollerProcessorUtil;
064 import com.liferay.portal.pop.POPServerUtil;
065 import com.liferay.portal.security.permission.ResourceActionsUtil;
066 import com.liferay.portal.service.PortletLocalServiceUtil;
067 import com.liferay.portal.service.ResourceActionLocalServiceUtil;
068 import com.liferay.portal.util.Portal;
069 import com.liferay.portal.util.PortalInstances;
070 import com.liferay.portal.util.PropsValues;
071 import com.liferay.portal.util.WebAppPool;
072 import com.liferay.portal.util.WebKeys;
073 import com.liferay.portal.xmlrpc.XmlRpcServlet;
074 import com.liferay.portlet.CustomUserAttributes;
075 import com.liferay.portlet.InvokerPortlet;
076 import com.liferay.portlet.PortletBagFactory;
077 import com.liferay.portlet.PortletContextBag;
078 import com.liferay.portlet.PortletContextBagPool;
079 import com.liferay.portlet.PortletFilterFactory;
080 import com.liferay.portlet.PortletInstanceFactoryUtil;
081 import com.liferay.portlet.PortletResourceBundles;
082 import com.liferay.portlet.PortletURLListenerFactory;
083 import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
084 import com.liferay.portlet.asset.model.AssetRendererFactory;
085 import com.liferay.portlet.social.model.SocialActivityInterpreter;
086 import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
087 import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
088 import com.liferay.util.bridges.php.PHPPortlet;
089
090 import java.util.HashMap;
091 import java.util.HashSet;
092 import java.util.Iterator;
093 import java.util.List;
094 import java.util.Locale;
095 import java.util.Map;
096 import java.util.Properties;
097 import java.util.ResourceBundle;
098 import java.util.Set;
099
100 import javax.naming.Context;
101 import javax.naming.InitialContext;
102 import javax.naming.NamingException;
103
104 import javax.portlet.PortletURLGenerationListener;
105
106 import javax.servlet.ServletContext;
107
108 import javax.sql.DataSource;
109
110 import org.apache.portals.bridges.struts.StrutsPortlet;
111
112
118 public class PortletHotDeployListener extends BaseHotDeployListener {
119
120 @Override
121 public void invokeDeploy(HotDeployEvent hotDeployEvent)
122 throws HotDeployException {
123
124 try {
125 doInvokeDeploy(hotDeployEvent);
126 }
127 catch (Throwable t) {
128 throwHotDeployException(
129 hotDeployEvent,
130 "Error registering portlets for " +
131 hotDeployEvent.getServletContextName(),
132 t);
133 }
134 }
135
136 @Override
137 public void invokeUndeploy(HotDeployEvent hotDeployEvent)
138 throws HotDeployException {
139
140 try {
141 doInvokeUndeploy(hotDeployEvent);
142 }
143 catch (Throwable t) {
144 throwHotDeployException(
145 hotDeployEvent,
146 "Error unregistering portlets for " +
147 hotDeployEvent.getServletContextName(),
148 t);
149 }
150 }
151
152 protected void bindDataSource(String servletContextName) throws Exception {
153 if (ServerDetector.isGlassfish() || ServerDetector.isJOnAS()) {
154 return;
155 }
156
157 if (_log.isDebugEnabled()) {
158 _log.debug("Dynamically binding the Liferay data source");
159 }
160
161 DataSource dataSource = InfrastructureUtil.getDataSource();
162
163 if (dataSource == null) {
164 if (_log.isDebugEnabled()) {
165 _log.debug(
166 "Abort dynamically binding the Liferay data source " +
167 "because it is not available");
168 }
169
170 return;
171 }
172
173 Context context = new InitialContext();
174
175 try {
176 try {
177 context.lookup(_JNDI_JDBC);
178 }
179 catch (NamingException ne) {
180 context.createSubcontext(_JNDI_JDBC);
181 }
182
183 try {
184 context.lookup(_JNDI_JDBC_LIFERAY_POOL);
185 }
186 catch (NamingException ne) {
187 context.bind(_JNDI_JDBC_LIFERAY_POOL, dataSource);
188 }
189
190 _dataSourceBindStates.put(servletContextName, true);
191 }
192 catch (Exception e) {
193 if (_log.isWarnEnabled()) {
194 _log.warn(
195 "Unable to dynamically bind the Liferay data source: " +
196 e.getMessage());
197 }
198 }
199 }
200
201 protected void destroyPortlet(Portlet portlet, Set<String> portletIds)
202 throws Exception {
203
204 PortletApp portletApp = portlet.getPortletApp();
205
206 Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
207
208 for (PortletFilter portletFilter : portletFilters) {
209 PortletFilterFactory.destroy(portletFilter);
210 }
211
212 Set<PortletURLListener> portletURLListeners =
213 portletApp.getPortletURLListeners();
214
215 for (PortletURLListener portletURLListener : portletURLListeners) {
216 PortletURLListenerFactory.destroy(portletURLListener);
217 }
218
219 List<Indexer> indexers = portlet.getIndexerInstances();
220
221 for (Indexer indexer : indexers) {
222 IndexerRegistryUtil.unregister(indexer);
223 }
224
225 if (PropsValues.SCHEDULER_ENABLED) {
226 List<SchedulerEntry> schedulerEntries =
227 portlet.getSchedulerEntries();
228
229 if ((schedulerEntries != null) && !schedulerEntries.isEmpty()) {
230 for (SchedulerEntry schedulerEntry : schedulerEntries) {
231 SchedulerEngineHelperUtil.unschedule(
232 schedulerEntry, StorageType.MEMORY_CLUSTERED);
233 }
234 }
235 }
236
237 List<StagedModelDataHandler<?>> stagedModelDataHandlers =
238 portlet.getStagedModelDataHandlerInstances();
239
240 if (stagedModelDataHandlers != null) {
241 StagedModelDataHandlerRegistryUtil.unregister(
242 stagedModelDataHandlers);
243 }
244
245 PollerProcessorUtil.deletePollerProcessor(portlet.getPortletId());
246
247 POPServerUtil.deleteListener(portlet.getPopMessageListenerInstance());
248
249 List<SocialActivityInterpreter> socialActivityInterpreters =
250 portlet.getSocialActivityInterpreterInstances();
251
252 if (socialActivityInterpreters != null) {
253 for (SocialActivityInterpreter socialActivityInterpreter :
254 socialActivityInterpreters) {
255
256 SocialActivityInterpreterLocalServiceUtil.
257 deleteActivityInterpreter(socialActivityInterpreter);
258 }
259 }
260
261 SocialRequestInterpreterLocalServiceUtil.deleteRequestInterpreter(
262 portlet.getSocialRequestInterpreterInstance());
263
264 UserNotificationManagerUtil.deleteUserNotificationDefinitions(
265 portlet.getPortletId());
266
267 List<UserNotificationHandler> userNotificationHandlers =
268 portlet.getUserNotificationHandlerInstances();
269
270 if (userNotificationHandlers != null) {
271 for (UserNotificationHandler userNotificationHandler :
272 userNotificationHandlers) {
273
274 UserNotificationManagerUtil.deleteUserNotificationHandler(
275 userNotificationHandler);
276 }
277 }
278
279 WebDAVUtil.deleteStorage(portlet.getWebDAVStorageInstance());
280
281 XmlRpcServlet.unregisterMethod(portlet.getXmlRpcMethodInstance());
282
283 List<AssetRendererFactory> assetRendererFactories =
284 portlet.getAssetRendererFactoryInstances();
285
286 if (assetRendererFactories != null) {
287 AssetRendererFactoryRegistryUtil.unregister(assetRendererFactories);
288 }
289
290 List<AtomCollectionAdapter<?>> atomCollectionAdapters =
291 portlet.getAtomCollectionAdapterInstances();
292
293 if (atomCollectionAdapters != null) {
294 AtomCollectionAdapterRegistryUtil.unregister(
295 atomCollectionAdapters);
296 }
297
298 List<TrashHandler> trashHandlers = portlet.getTrashHandlerInstances();
299
300 if (trashHandlers != null) {
301 TrashHandlerRegistryUtil.unregister(trashHandlers);
302 }
303
304 List<WorkflowHandler> workflowHandlers =
305 portlet.getWorkflowHandlerInstances();
306
307 if (workflowHandlers != null) {
308 WorkflowHandlerRegistryUtil.unregister(workflowHandlers);
309 }
310
311 PortletInstanceFactoryUtil.destroy(portlet);
312
313 portletIds.add(portlet.getPortletId());
314 }
315
316 protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
317 throws Exception {
318
319 ServletContext servletContext = hotDeployEvent.getServletContext();
320
321 String servletContextName = servletContext.getServletContextName();
322
323 if (_log.isDebugEnabled()) {
324 _log.debug("Invoking deploy for " + servletContextName);
325 }
326
327 String[] xmls = new String[] {
328 HttpUtil.URLtoString(
329 servletContext.getResource(
330 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD)),
331 HttpUtil.URLtoString(
332 servletContext.getResource(
333 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
334 HttpUtil.URLtoString(
335 servletContext.getResource("/WEB-INF/liferay-portlet.xml")),
336 HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
337 };
338
339 if ((xmls[0] == null) && (xmls[1] == null)) {
340 return;
341 }
342
343 if (_log.isInfoEnabled()) {
344 _log.info("Registering portlets for " + servletContextName);
345 }
346
347 List<Portlet> portlets = PortletLocalServiceUtil.initWAR(
348 servletContextName, servletContext, xmls,
349 hotDeployEvent.getPluginPackage());
350
351 boolean portletAppInitialized = false;
352
353 boolean phpPortlet = false;
354 boolean strutsBridges = false;
355
356 PortletBagFactory portletBagFactory = new PortletBagFactory();
357
358 ClassLoader classLoader = hotDeployEvent.getContextClassLoader();
359
360 portletBagFactory.setClassLoader(classLoader);
361
362 portletBagFactory.setServletContext(servletContext);
363 portletBagFactory.setWARFile(true);
364
365 Iterator<Portlet> itr = portlets.iterator();
366
367 while (itr.hasNext()) {
368 Portlet portlet = itr.next();
369
370 PortletBag portletBag = portletBagFactory.create(portlet);
371
372 if (portletBag == null) {
373 itr.remove();
374 }
375 else {
376 if (!portletAppInitialized) {
377 initPortletApp(
378 servletContextName, servletContext, classLoader,
379 portlet);
380
381 portletAppInitialized = true;
382 }
383
384 javax.portlet.Portlet portletInstance =
385 portletBag.getPortletInstance();
386
387 if (ClassUtil.isSubclass(
388 portletInstance.getClass(),
389 PHPPortlet.class.getName())) {
390
391 phpPortlet = true;
392 }
393
394 if (ClassUtil.isSubclass(
395 portletInstance.getClass(),
396 StrutsPortlet.class.getName())) {
397
398 strutsBridges = true;
399 }
400 }
401 }
402
403 if (phpPortlet) {
404 bindDataSource(servletContextName);
405 }
406
407 if (!strutsBridges) {
408 strutsBridges = GetterUtil.getBoolean(
409 servletContext.getInitParameter(
410 "struts-bridges-context-provider"));
411 }
412
413 if (strutsBridges) {
414 servletContext.setAttribute(
415 ServletContextProvider.STRUTS_BRIDGES_CONTEXT_PROVIDER,
416 new LiferayServletContextProvider());
417 }
418
419 String xml = HttpUtil.URLtoString(
420 servletContext.getResource("/WEB-INF/liferay-display.xml"));
421
422 PortletCategory newPortletCategory =
423 PortletLocalServiceUtil.getWARDisplay(servletContextName, xml);
424
425 long[] companyIds = PortalInstances.getCompanyIds();
426
427 for (long companyId : companyIds) {
428 PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
429 companyId, WebKeys.PORTLET_CATEGORY);
430
431 if (portletCategory != null) {
432 portletCategory.merge(newPortletCategory);
433 }
434 else {
435 _log.error(
436 "Unable to register portlet for company " + companyId +
437 " because it does not exist");
438 }
439 }
440
441 processPortletProperties(servletContextName, classLoader);
442
443 for (Portlet portlet : portlets) {
444 List<String> modelNames =
445 ResourceActionsUtil.getPortletModelResources(
446 portlet.getPortletId());
447
448 List<String> portletActions =
449 ResourceActionsUtil.getPortletResourceActions(
450 portlet.getPortletId());
451
452 ResourceActionLocalServiceUtil.checkResourceActions(
453 portlet.getPortletId(), portletActions);
454
455 for (String modelName : modelNames) {
456 List<String> modelActions =
457 ResourceActionsUtil.getModelResourceActions(modelName);
458
459 ResourceActionLocalServiceUtil.checkResourceActions(
460 modelName, modelActions);
461 }
462
463 for (long companyId : companyIds) {
464 Portlet curPortlet = PortletLocalServiceUtil.getPortletById(
465 companyId, portlet.getPortletId());
466
467 PortletLocalServiceUtil.checkPortlet(curPortlet);
468 }
469 }
470
471 for (Portlet portlet : portlets) {
472 boolean ready = GetterUtil.getBoolean(
473 servletContext.getInitParameter(
474 "portlets-ready-by-default"), true);
475
476 portlet.setReady(ready);
477 }
478
479 registerClpMessageListeners(servletContext, classLoader);
480
481 JavadocManagerUtil.load(servletContextName, classLoader);
482
483 DirectServletRegistryUtil.clearServlets();
484 FileTimestampUtil.reset();
485
486 _portlets.put(servletContextName, portlets);
487
488 servletContext.setAttribute(WebKeys.PLUGIN_PORTLETS, portlets);
489
490 if (_log.isInfoEnabled()) {
491 if (portlets.size() == 1) {
492 _log.info(
493 "1 portlet for " + servletContextName +
494 " is available for use");
495 }
496 else {
497 _log.info(
498 portlets.size() + " portlets for " + servletContextName +
499 " are available for use");
500 }
501 }
502 }
503
504 protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
505 throws Exception {
506
507 ServletContext servletContext = hotDeployEvent.getServletContext();
508
509 String servletContextName = servletContext.getServletContextName();
510
511 if (_log.isDebugEnabled()) {
512 _log.debug("Invoking undeploy for " + servletContextName);
513 }
514
515 List<Portlet> portlets = _portlets.remove(servletContextName);
516
517 if (portlets == null) {
518 return;
519 }
520
521 Set<String> portletIds = new HashSet<String>();
522
523 if (portlets != null) {
524 if (_log.isInfoEnabled()) {
525 _log.info("Unregistering portlets for " + servletContextName);
526 }
527
528 for (Portlet portlet : portlets) {
529 destroyPortlet(portlet, portletIds);
530 }
531 }
532
533 ServletContextPool.remove(servletContextName);
534
535 if (!portletIds.isEmpty()) {
536 long[] companyIds = PortalInstances.getCompanyIds();
537
538 for (long companyId : companyIds) {
539 PortletCategory portletCategory =
540 (PortletCategory)WebAppPool.get(
541 companyId, WebKeys.PORTLET_CATEGORY);
542
543 portletCategory.separate(portletIds);
544 }
545 }
546
547 PortletContextBagPool.remove(servletContextName);
548 PortletResourceBundles.remove(servletContextName);
549
550 unbindDataSource(servletContextName);
551
552 unregisterClpMessageListeners(servletContext);
553
554 JavadocManagerUtil.unload(servletContextName);
555
556 DirectServletRegistryUtil.clearServlets();
557
558 if (_log.isInfoEnabled()) {
559 if (portlets.size() == 1) {
560 _log.info(
561 "1 portlet for " + servletContextName +
562 " was unregistered");
563 }
564 else {
565 _log.info(
566 portlets.size() + " portlets for " + servletContextName +
567 " were unregistered");
568 }
569 }
570 }
571
572 protected void initPortletApp(
573 String servletContextName, ServletContext servletContext,
574 ClassLoader classLoader, Portlet portlet)
575 throws Exception {
576
577 PortletContextBag portletContextBag = new PortletContextBag(
578 servletContextName);
579
580 PortletContextBagPool.put(servletContextName, portletContextBag);
581
582 PortletApp portletApp = portlet.getPortletApp();
583
584 servletContext.setAttribute(PortletServlet.PORTLET_APP, portletApp);
585
586 Map<String, String> customUserAttributes =
587 portletApp.getCustomUserAttributes();
588
589 for (Map.Entry<String, String> entry :
590 customUserAttributes.entrySet()) {
591
592 String attrCustomClass = entry.getValue();
593
594 Class<?> clazz = classLoader.loadClass(attrCustomClass);
595
596 CustomUserAttributes customUserAttributesInstance =
597 (CustomUserAttributes)clazz.newInstance();
598
599 portletContextBag.getCustomUserAttributes().put(
600 attrCustomClass, customUserAttributesInstance);
601 }
602
603 Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
604
605 for (PortletFilter portletFilter : portletFilters) {
606 javax.portlet.filter.PortletFilter portletFilterInstance =
607 (javax.portlet.filter.PortletFilter)newInstance(
608 classLoader,
609 new Class<?>[] {
610 javax.portlet.filter.ActionFilter.class,
611 javax.portlet.filter.EventFilter.class,
612 javax.portlet.filter.PortletFilter.class,
613 javax.portlet.filter.RenderFilter.class,
614 javax.portlet.filter.ResourceFilter.class
615 },
616 portletFilter.getFilterClass());
617
618 portletContextBag.getPortletFilters().put(
619 portletFilter.getFilterName(), portletFilterInstance);
620 }
621
622 InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
623 portlet, servletContext);
624
625 invokerPortlet.setPortletFilters();
626
627 Set<PortletURLListener> portletURLListeners =
628 portletApp.getPortletURLListeners();
629
630 for (PortletURLListener portletURLListener : portletURLListeners) {
631 PortletURLGenerationListener portletURLListenerInstance =
632 (PortletURLGenerationListener)newInstance(
633 classLoader, PortletURLGenerationListener.class,
634 portletURLListener.getListenerClass());
635
636 portletContextBag.getPortletURLListeners().put(
637 portletURLListener.getListenerClass(),
638 portletURLListenerInstance);
639
640 PortletURLListenerFactory.create(portletURLListener);
641 }
642 }
643
644 protected void processPortletProperties(
645 String servletContextName, ClassLoader classLoader)
646 throws Exception {
647
648 Configuration portletPropertiesConfiguration = null;
649
650 try {
651 portletPropertiesConfiguration =
652 ConfigurationFactoryUtil.getConfiguration(
653 classLoader, "portlet");
654 }
655 catch (Exception e) {
656 if (_log.isDebugEnabled()) {
657 _log.debug("Unable to read portlet.properties");
658 }
659
660 return;
661 }
662
663 Properties portletProperties =
664 portletPropertiesConfiguration.getProperties();
665
666 if (portletProperties.size() == 0) {
667 return;
668 }
669
670 String languageBundleName = portletProperties.getProperty(
671 "language.bundle");
672
673 if (Validator.isNotNull(languageBundleName)) {
674 Locale[] locales = LanguageUtil.getAvailableLocales();
675
676 for (Locale locale : locales) {
677 ResourceBundle resourceBundle = ResourceBundle.getBundle(
678 languageBundleName, locale, classLoader);
679
680 PortletResourceBundles.put(
681 servletContextName, LocaleUtil.toLanguageId(locale),
682 resourceBundle);
683 }
684 }
685
686 String[] resourceActionConfigs = StringUtil.split(
687 portletProperties.getProperty(PropsKeys.RESOURCE_ACTIONS_CONFIGS));
688
689 for (String resourceActionConfig : resourceActionConfigs) {
690 ResourceActionsUtil.read(
691 servletContextName, classLoader, resourceActionConfig);
692 }
693 }
694
695 protected void unbindDataSource(String servletContextName) {
696 Boolean dataSourceBindState = _dataSourceBindStates.remove(
697 servletContextName);
698
699 if (dataSourceBindState == null) {
700 return;
701 }
702
703 try {
704 if (_log.isDebugEnabled()) {
705 _log.debug("Dynamically unbinding the Liferay data source");
706 }
707
708 Context context = new InitialContext();
709
710 try {
711 context.lookup(_JNDI_JDBC_LIFERAY_POOL);
712
713 context.unbind(_JNDI_JDBC_LIFERAY_POOL);
714 }
715 catch (NamingException ne) {
716 }
717
718 try {
719 context.lookup(_JNDI_JDBC);
720
721 context.destroySubcontext(_JNDI_JDBC);
722 }
723 catch (NamingException ne) {
724 }
725 }
726 catch (Exception e) {
727 if (_log.isWarnEnabled()) {
728 _log.warn(
729 "Unable to dynamically unbind the Liferay data source: " +
730 e.getMessage());
731 }
732 }
733 }
734
735 private static final String _JNDI_JDBC = "java_liferay:jdbc";
736
737 private static final String _JNDI_JDBC_LIFERAY_POOL =
738 _JNDI_JDBC + "/LiferayPool";
739
740 private static Log _log = LogFactoryUtil.getLog(
741 PortletHotDeployListener.class);
742
743 private static Map<String, Boolean> _dataSourceBindStates =
744 new HashMap<String, Boolean>();
745 private static Map<String, List<Portlet>> _portlets =
746 new HashMap<String, List<Portlet>>();
747
748 }