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.portlet;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.ClassUtil;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.model.Portlet;
022    import com.liferay.portal.model.PortletApp;
023    import com.liferay.portal.model.impl.PortletFilterImpl;
024    import com.liferay.portal.util.ClassLoaderUtil;
025    import com.liferay.portal.util.PropsValues;
026    import com.liferay.registry.Filter;
027    import com.liferay.registry.Registry;
028    import com.liferay.registry.RegistryUtil;
029    import com.liferay.registry.ServiceReference;
030    import com.liferay.registry.ServiceRegistration;
031    import com.liferay.registry.ServiceTracker;
032    import com.liferay.registry.ServiceTrackerCustomizer;
033    
034    import java.io.Closeable;
035    
036    import java.util.Collections;
037    import java.util.HashMap;
038    import java.util.List;
039    import java.util.Map;
040    import java.util.concurrent.CopyOnWriteArrayList;
041    
042    import javax.portlet.PortletContext;
043    import javax.portlet.PortletException;
044    import javax.portlet.filter.ActionFilter;
045    import javax.portlet.filter.EventFilter;
046    import javax.portlet.filter.FilterConfig;
047    import javax.portlet.filter.PortletFilter;
048    import javax.portlet.filter.RenderFilter;
049    import javax.portlet.filter.ResourceFilter;
050    
051    /**
052     * @author Raymond Aug??
053     */
054    public class InvokerFilterContainerImpl
055            implements Closeable, InvokerFilterContainer {
056    
057            public InvokerFilterContainerImpl(
058                            Portlet portlet, PortletContext portletContext)
059                    throws PortletException {
060    
061                    String rootPortletId = portlet.getRootPortletId();
062    
063                    Registry registry = RegistryUtil.getRegistry();
064    
065                    Filter filter = registry.getFilter(
066                            "(&(javax.portlet.name=" + rootPortletId + ")(objectClass=" +
067                                    PortletFilter.class.getName() + "))");
068    
069                    _serviceTracker =
070                            registry.trackServices(
071                                    filter,
072                                    new PortletFilterServiceTrackerCustomizer(portletContext));
073    
074                    _serviceTracker.open();
075    
076                    PortletApp portletApp = portlet.getPortletApp();
077    
078                    PortletContextBag portletContextBag = PortletContextBagPool.get(
079                            portletApp.getServletContextName());
080    
081                    if (portletApp.isWARFile() && (portletContextBag == null)) {
082                            return;
083                    }
084    
085                    Map<String, Object> properties = new HashMap<String, Object>();
086    
087                    properties.put("javax.portlet.name", rootPortletId);
088                    properties.put("preinitialized.filter", Boolean.TRUE);
089    
090                    Map<String, com.liferay.portal.model.PortletFilter> portletFilters =
091                            portlet.getPortletFilters();
092    
093                    for (Map.Entry<String, com.liferay.portal.model.PortletFilter> entry :
094                                    portletFilters.entrySet()) {
095    
096                            com.liferay.portal.model.PortletFilter portletFilterModel =
097                                    entry.getValue();
098    
099                            PortletFilter portletFilter = PortletFilterFactory.create(
100                                    portletFilterModel, portletContext);
101    
102                            ServiceRegistration<PortletFilter> serviceRegistration =
103                                    registry.registerService(
104                                            PortletFilter.class, portletFilter, properties);
105    
106                            _serviceRegistrations.add(serviceRegistration);
107                    }
108    
109                    ClassLoader classLoader = ClassLoaderUtil.getContextClassLoader();
110    
111                    try {
112                            ClassLoaderUtil.setContextClassLoader(
113                                    ClassLoaderUtil.getPortalClassLoader());
114    
115                            for (String portletFilterClassName :
116                                            PropsValues.PORTLET_FILTERS_SYSTEM) {
117    
118                                    com.liferay.portal.model.PortletFilter portletFilterModel =
119                                            new PortletFilterImpl(
120                                                    portletFilterClassName, portletFilterClassName,
121                                                    Collections.<String>emptySet(),
122                                                    Collections.<String, String>emptyMap(), portletApp);
123    
124                                    PortletFilter portletFilter = PortletFilterFactory.create(
125                                            portletFilterModel, portletContext);
126    
127                                    ServiceRegistration<PortletFilter> serviceRegistration =
128                                            registry.registerService(
129                                                    PortletFilter.class, portletFilter, properties);
130    
131                                    _serviceRegistrations.add(serviceRegistration);
132                            }
133                    }
134                    finally {
135                            ClassLoaderUtil.setContextClassLoader(classLoader);
136                    }
137            }
138    
139            @Override
140            public void close() {
141                    for (ServiceRegistration<?> serviceRegistration :
142                                    _serviceRegistrations) {
143    
144                            serviceRegistration.unregister();
145                    }
146    
147                    _serviceRegistrations.clear();
148    
149                    _serviceTracker.close();
150    
151                    _actionFilters.clear();
152                    _eventFilters.clear();
153                    _renderFilters.clear();
154                    _resourceFilters.clear();
155            }
156    
157            @Override
158            public List<ActionFilter> getActionFilters() {
159                    return _actionFilters;
160            }
161    
162            @Override
163            public List<EventFilter> getEventFilters() {
164                    return _eventFilters;
165            }
166    
167            @Override
168            public List<RenderFilter> getRenderFilters() {
169                    return _renderFilters;
170            }
171    
172            @Override
173            public List<ResourceFilter> getResourceFilters() {
174                    return _resourceFilters;
175            }
176    
177            private static final Log _log = LogFactoryUtil.getLog(
178                    InvokerFilterContainerImpl.class);
179    
180            private final List<ActionFilter> _actionFilters =
181                    new CopyOnWriteArrayList<>();
182            private final List<EventFilter> _eventFilters =
183                    new CopyOnWriteArrayList<>();
184            private final List<RenderFilter> _renderFilters =
185                    new CopyOnWriteArrayList<>();
186            private final List<ResourceFilter> _resourceFilters =
187                    new CopyOnWriteArrayList<>();
188            private final List<ServiceRegistration<PortletFilter>>
189                    _serviceRegistrations = new CopyOnWriteArrayList<>();
190            private final ServiceTracker<PortletFilter, PortletFilter> _serviceTracker;
191    
192            private class PortletFilterServiceTrackerCustomizer
193                    implements ServiceTrackerCustomizer<PortletFilter, PortletFilter> {
194    
195                    public PortletFilterServiceTrackerCustomizer(
196                            PortletContext portletContext) {
197    
198                            _portletContext = portletContext;
199                    }
200    
201                    @Override
202                    public PortletFilter addingService(
203                            ServiceReference<PortletFilter> serviceReference) {
204    
205                            Registry registry = RegistryUtil.getRegistry();
206    
207                            PortletFilter portletFilter = registry.getService(serviceReference);
208    
209                            boolean preinitializedFilter = GetterUtil.getBoolean(
210                                    serviceReference.getProperty("preinitialized.filter"));
211    
212                            if (!preinitializedFilter) {
213                                    String filterName = GetterUtil.getString(
214                                            serviceReference.getProperty("service.id"),
215                                            ClassUtil.getClassName(portletFilter));
216    
217                                    Map<String, String> params = new HashMap<String, String>();
218    
219                                    for (String key : serviceReference.getPropertyKeys()) {
220                                            String value = GetterUtil.getString(
221                                                    serviceReference.getProperty(key));
222    
223                                            params.put(key, value);
224                                    }
225    
226                                    FilterConfig filterConfig = new FilterConfigImpl(
227                                            filterName, _portletContext, params);
228    
229                                    try {
230                                            portletFilter.init(filterConfig);
231                                    }
232                                    catch (PortletException e) {
233                                            _log.error(e, e);
234    
235                                            registry.ungetService(serviceReference);
236    
237                                            return null;
238                                    }
239                            }
240    
241                            if (portletFilter instanceof ActionFilter) {
242                                    _actionFilters.add((ActionFilter)portletFilter);
243                            }
244    
245                            if (portletFilter instanceof EventFilter) {
246                                    _eventFilters.add((EventFilter)portletFilter);
247                            }
248    
249                            if (portletFilter instanceof RenderFilter) {
250                                    _renderFilters.add((RenderFilter)portletFilter);
251                            }
252    
253                            if (portletFilter instanceof ResourceFilter) {
254                                    _resourceFilters.add((ResourceFilter)portletFilter);
255                            }
256    
257                            return portletFilter;
258                    }
259    
260                    @Override
261                    public void modifiedService(
262                            ServiceReference<PortletFilter> serviceReference,
263                            PortletFilter portletFilter) {
264                    }
265    
266                    @Override
267                    public void removedService(
268                            ServiceReference<PortletFilter> serviceReference,
269                            PortletFilter portletFilter) {
270    
271                            Registry registry = RegistryUtil.getRegistry();
272    
273                            registry.ungetService(serviceReference);
274    
275                            _actionFilters.remove(portletFilter);
276                            _eventFilters.remove(portletFilter);
277                            _renderFilters.remove(portletFilter);
278                            _resourceFilters.remove(portletFilter);
279    
280                            boolean preinitializedFilter = GetterUtil.getBoolean(
281                                    serviceReference.getProperty("preinitialized.filter"));
282    
283                            if (preinitializedFilter) {
284                                    return;
285                            }
286    
287                            portletFilter.destroy();
288                    }
289    
290                    private final PortletContext _portletContext;
291    
292            }
293    
294    }