001    /**
002     * Copyright (c) 2000-present 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.kernel.servlet;
016    
017    import com.liferay.portal.model.Portlet;
018    import com.liferay.portal.model.PortletApp;
019    import com.liferay.registry.Registry;
020    import com.liferay.registry.RegistryUtil;
021    import com.liferay.registry.ServiceReference;
022    import com.liferay.registry.ServiceTracker;
023    import com.liferay.registry.ServiceTrackerCustomizer;
024    
025    import java.net.MalformedURLException;
026    import java.net.URL;
027    
028    import java.util.Map;
029    import java.util.concurrent.ConcurrentHashMap;
030    
031    import javax.servlet.ServletContext;
032    
033    /**
034     * @author Michael Bradford
035     */
036    public class PortletResourcesUtil {
037    
038            public static ServletContext getPathServletContext(String path) {
039                    for (ServletContext servletContext :
040                                    _instance._servletContexts.values()) {
041    
042                            if (path.startsWith(servletContext.getContextPath())) {
043                                    return servletContext;
044                            }
045                    }
046    
047                    return null;
048            }
049    
050            public static URL getResource(ServletContext servletContext, String path) {
051                    path = PortalWebResourcesUtil.stripContextPath(servletContext, path);
052    
053                    try {
054                            URL url = servletContext.getResource(path);
055    
056                            if (url != null) {
057                                    return url;
058                            }
059                    }
060                    catch (MalformedURLException murle) {
061                    }
062    
063                    return null;
064            }
065    
066            public static URL getResource(String path) {
067                    ServletContext servletContext = getPathServletContext(path);
068    
069                    if (servletContext != null) {
070                            return getResource(servletContext, path);
071                    }
072    
073                    return null;
074            }
075    
076            private PortletResourcesUtil() {
077                    Registry registry = RegistryUtil.getRegistry();
078    
079                    _serviceTracker = registry.trackServices(
080                            Portlet.class, new PortletResourcesServiceTrackerCustomizer());
081    
082                    _serviceTracker.open();
083            }
084    
085            private static final PortletResourcesUtil _instance =
086                    new PortletResourcesUtil();
087    
088            private final ServiceTracker<Portlet, Portlet> _serviceTracker;
089            private final Map<ServiceReference<Portlet>, ServletContext>
090                    _servletContexts = new ConcurrentHashMap<>();
091    
092            private class PortletResourcesServiceTrackerCustomizer
093                    implements ServiceTrackerCustomizer<Portlet, Portlet> {
094    
095                    @Override
096                    public Portlet addingService(
097                            ServiceReference<Portlet> serviceReference) {
098    
099                            Registry registry = RegistryUtil.getRegistry();
100    
101                            Portlet portlet = registry.getService(serviceReference);
102    
103                            PortletApp portletApp = portlet.getPortletApp();
104    
105                            ServletContext servletContext = portletApp.getServletContext();
106    
107                            if (portletApp.isWARFile()) {
108                                    _servletContexts.put(serviceReference, servletContext);
109                            }
110    
111                            return portlet;
112                    }
113    
114                    @Override
115                    public void modifiedService(
116                            ServiceReference<Portlet> serviceReference, Portlet portlet) {
117                    }
118    
119                    @Override
120                    public void removedService(
121                            ServiceReference<Portlet> serviceReference, Portlet portlet) {
122    
123                            Registry registry = RegistryUtil.getRegistry();
124    
125                            registry.ungetService(serviceReference);
126    
127                            _servletContexts.remove(serviceReference);
128                    }
129    
130            }
131    
132    }