001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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    /**
113     * @author Brian Wing Shun Chan
114     * @author Brian Myunghun Kim
115     * @author Ivica Cardic
116     * @author Raymond Aug??
117     */
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    }