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.resiliency.spi;
016    
017    import com.liferay.portal.kernel.concurrent.ConcurrentHashSet;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.resiliency.spi.SPI;
021    import com.liferay.portal.kernel.resiliency.spi.SPIConfiguration;
022    import com.liferay.portal.kernel.resiliency.spi.SPIRegistry;
023    import com.liferay.portal.model.Portlet;
024    import com.liferay.portal.model.PortletApp;
025    import com.liferay.portal.service.PortletLocalServiceUtil;
026    import com.liferay.portal.spring.aop.ServiceBeanAopCacheManagerUtil;
027    
028    import java.rmi.RemoteException;
029    
030    import java.util.ArrayList;
031    import java.util.List;
032    import java.util.Map;
033    import java.util.Set;
034    import java.util.concurrent.ConcurrentHashMap;
035    import java.util.concurrent.locks.Lock;
036    import java.util.concurrent.locks.ReentrantLock;
037    
038    /**
039     * @author Shuyang Zhou
040     */
041    public class SPIRegistryImpl implements SPIRegistry {
042    
043            @Override
044            public void addExcludedPortletId(String portletId) {
045                    _excludedPortletIds.add(portletId);
046            }
047    
048            @Override
049            public Set<String> getExcludedPortletIds() {
050                    return _excludedPortletIds;
051            }
052    
053            @Override
054            public SPI getPortletSPI(String portletId) {
055                    if (_excludedPortletIds.contains(portletId)) {
056                            return null;
057                    }
058    
059                    return _portletSPIs.get(portletId);
060            }
061    
062            @Override
063            public SPI getServletContextSPI(String servletContextName) {
064                    return _servletContextSPIs.get(servletContextName);
065            }
066    
067            @Override
068            public void registerSPI(SPI spi) throws RemoteException {
069                    List<String> portletIds = new ArrayList<String>();
070    
071                    SPIConfiguration spiConfiguration = spi.getSPIConfiguration();
072    
073                    for (String portletId : spiConfiguration.getPortletIds()) {
074                            Portlet portlet = PortletLocalServiceUtil.getPortletById(portletId);
075    
076                            if (portlet == null) {
077                                    if (_log.isWarnEnabled()) {
078                                            _log.warn("Skip unknown portlet id " + portletId);
079                                    }
080                            }
081                            else {
082                                    portletIds.add(portletId);
083                            }
084                    }
085    
086                    String[] servletContextNames =
087                            spiConfiguration.getServletContextNames();
088    
089                    for (String servletContextName : servletContextNames) {
090                            PortletApp portletApp = PortletLocalServiceUtil.getPortletApp(
091                                    servletContextName);
092    
093                            if (portletApp == null) {
094                                    if (_log.isWarnEnabled()) {
095                                            _log.warn(
096                                                    "Skip unknown servlet context name " +
097                                                            servletContextName);
098                                    }
099                            }
100                            else {
101                                    List<Portlet> portlets = portletApp.getPortlets();
102    
103                                    for (Portlet portlet : portlets) {
104                                            portletIds.add(portlet.getPortletId());
105                                    }
106                            }
107                    }
108    
109                    _lock.lock();
110    
111                    try {
112                            for (String portletId : portletIds) {
113                                    _portletSPIs.put(portletId, spi);
114                            }
115    
116                            _portletIds.put(
117                                    spi, portletIds.toArray(new String[portletIds.size()]));
118    
119                            for (String servletContextName : servletContextNames) {
120                                    _servletContextSPIs.put(servletContextName, spi);
121                            }
122    
123                            _servletContextNames.put(spi, servletContextNames.clone());
124    
125                            ServiceBeanAopCacheManagerUtil.reset();
126                    }
127                    finally {
128                            _lock.unlock();
129                    }
130            }
131    
132            @Override
133            public void removeExcludedPortletId(String portletId) {
134                    _excludedPortletIds.remove(portletId);
135            }
136    
137            @Override
138            public void unregisterSPI(SPI spi) {
139                    _lock.lock();
140    
141                    try {
142                            String[] portletIds = _portletIds.remove(spi);
143    
144                            if (portletIds != null) {
145                                    for (String portletId : portletIds) {
146                                            _portletSPIs.remove(portletId);
147                                    }
148                            }
149    
150                            String[] servletContextNames = _servletContextNames.remove(spi);
151    
152                            if (servletContextNames != null) {
153                                    for (String servletContextName : servletContextNames) {
154                                            _servletContextSPIs.remove(servletContextName);
155                                    }
156                            }
157                    }
158                    finally {
159                            _lock.unlock();
160                    }
161            }
162    
163            private static Log _log = LogFactoryUtil.getLog(SPIRegistryImpl.class);
164    
165            private Set<String> _excludedPortletIds = new ConcurrentHashSet<String>();
166            private Lock _lock = new ReentrantLock();
167            private Map<SPI, String[]> _portletIds =
168                    new ConcurrentHashMap<SPI, String[]>();
169            private Map<String, SPI> _portletSPIs =
170                    new ConcurrentHashMap<String, SPI>();
171            private Map<SPI, String[]> _servletContextNames =
172                    new ConcurrentHashMap<SPI, String[]>();
173            private Map<String, SPI> _servletContextSPIs =
174                    new ConcurrentHashMap<String, SPI>();
175    
176    }