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.model.Portlet;
020    import com.liferay.portal.kernel.portlet.InvokerFilterContainer;
021    import com.liferay.portal.kernel.util.ClassLoaderUtil;
022    import com.liferay.portal.kernel.util.ClassUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.model.impl.PortletFilterImpl;
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 = registry.trackServices(
070                            filter, new PortletFilterServiceTrackerCustomizer(portletContext));
071    
072                    _serviceTracker.open();
073    
074                    Map<String, Object> properties = new HashMap<>();
075    
076                    properties.put("javax.portlet.name", rootPortletId);
077                    properties.put("preinitialized.filter", Boolean.TRUE);
078    
079                    Map<String, com.liferay.portal.kernel.model.PortletFilter>
080                            portletFilters = portlet.getPortletFilters();
081    
082                    for (Map.Entry<String, com.liferay.portal.kernel.model.PortletFilter>
083                                    entry : portletFilters.entrySet()) {
084    
085                            com.liferay.portal.kernel.model.PortletFilter portletFilterModel =
086                                    entry.getValue();
087    
088                            PortletFilter portletFilter = PortletFilterFactory.create(
089                                    portletFilterModel, portletContext);
090    
091                            ServiceRegistration<PortletFilter> serviceRegistration =
092                                    registry.registerService(
093                                            PortletFilter.class, portletFilter, properties);
094    
095                            ServiceRegistrationTuple serviceRegistrationTuple =
096                                    new ServiceRegistrationTuple(
097                                            portletFilterModel, serviceRegistration);
098    
099                            _serviceRegistrationTuples.add(serviceRegistrationTuple);
100                    }
101    
102                    ClassLoader classLoader = ClassLoaderUtil.getContextClassLoader();
103    
104                    try {
105                            ClassLoaderUtil.setContextClassLoader(
106                                    ClassLoaderUtil.getPortalClassLoader());
107    
108                            for (String portletFilterClassName :
109                                            PropsValues.PORTLET_FILTERS_SYSTEM) {
110    
111                                    com.liferay.portal.kernel.model.PortletFilter
112                                            portletFilterModel = new PortletFilterImpl(
113                                                    portletFilterClassName, portletFilterClassName,
114                                                    Collections.<String>emptySet(),
115                                                    Collections.<String, String>emptyMap(),
116                                                    portlet.getPortletApp());
117    
118                                    PortletFilter portletFilter = PortletFilterFactory.create(
119                                            portletFilterModel, portletContext);
120    
121                                    ServiceRegistration<PortletFilter> serviceRegistration =
122                                            registry.registerService(
123                                                    PortletFilter.class, portletFilter, properties);
124    
125                                    _serviceRegistrationTuples.add(
126                                            new ServiceRegistrationTuple(
127                                                    portletFilterModel, serviceRegistration));
128                            }
129                    }
130                    finally {
131                            ClassLoaderUtil.setContextClassLoader(classLoader);
132                    }
133            }
134    
135            @Override
136            public void close() {
137                    for (ServiceRegistrationTuple serviceRegistrationTuple :
138                                    _serviceRegistrationTuples) {
139    
140                            PortletFilterFactory.destroy(
141                                    serviceRegistrationTuple.getPortletFilterModel());
142    
143                            ServiceRegistration<PortletFilter> serviceRegistration =
144                                    serviceRegistrationTuple.getServiceRegistration();
145    
146                            serviceRegistration.unregister();
147                    }
148    
149                    _serviceRegistrationTuples.clear();
150    
151                    _serviceTracker.close();
152    
153                    _actionFilters.clear();
154                    _eventFilters.clear();
155                    _renderFilters.clear();
156                    _resourceFilters.clear();
157            }
158    
159            @Override
160            public List<ActionFilter> getActionFilters() {
161                    return _actionFilters;
162            }
163    
164            @Override
165            public List<EventFilter> getEventFilters() {
166                    return _eventFilters;
167            }
168    
169            @Override
170            public List<RenderFilter> getRenderFilters() {
171                    return _renderFilters;
172            }
173    
174            @Override
175            public List<ResourceFilter> getResourceFilters() {
176                    return _resourceFilters;
177            }
178    
179            private static final Log _log = LogFactoryUtil.getLog(
180                    InvokerFilterContainerImpl.class);
181    
182            private final List<ActionFilter> _actionFilters =
183                    new CopyOnWriteArrayList<>();
184            private final List<EventFilter> _eventFilters =
185                    new CopyOnWriteArrayList<>();
186            private final List<RenderFilter> _renderFilters =
187                    new CopyOnWriteArrayList<>();
188            private final List<ResourceFilter> _resourceFilters =
189                    new CopyOnWriteArrayList<>();
190            private final List<ServiceRegistrationTuple> _serviceRegistrationTuples =
191                    new CopyOnWriteArrayList<>();
192            private final ServiceTracker<PortletFilter, PortletFilter> _serviceTracker;
193    
194            private static class ServiceRegistrationTuple {
195    
196                    public ServiceRegistrationTuple(
197                            com.liferay.portal.kernel.model.PortletFilter portletFilterModel,
198                            ServiceRegistration<PortletFilter> serviceRegistration) {
199    
200                            _portletFilterModel = portletFilterModel;
201                            _serviceRegistration = serviceRegistration;
202                    }
203    
204                    public com.liferay.portal.kernel.model.PortletFilter
205                            getPortletFilterModel() {
206    
207                            return _portletFilterModel;
208                    }
209    
210                    public ServiceRegistration<PortletFilter> getServiceRegistration() {
211                            return _serviceRegistration;
212                    }
213    
214                    private final com.liferay.portal.kernel.model.PortletFilter
215                            _portletFilterModel;
216                    private final ServiceRegistration<PortletFilter> _serviceRegistration;
217    
218            }
219    
220            private class PortletFilterServiceTrackerCustomizer
221                    implements ServiceTrackerCustomizer<PortletFilter, PortletFilter> {
222    
223                    public PortletFilterServiceTrackerCustomizer(
224                            PortletContext portletContext) {
225    
226                            _portletContext = portletContext;
227                    }
228    
229                    @Override
230                    public PortletFilter addingService(
231                            ServiceReference<PortletFilter> serviceReference) {
232    
233                            Registry registry = RegistryUtil.getRegistry();
234    
235                            PortletFilter portletFilter = registry.getService(serviceReference);
236    
237                            boolean preinitializedFilter = GetterUtil.getBoolean(
238                                    serviceReference.getProperty("preinitialized.filter"));
239    
240                            if (!preinitializedFilter) {
241                                    String filterName = GetterUtil.getString(
242                                            serviceReference.getProperty("service.id"),
243                                            ClassUtil.getClassName(portletFilter));
244    
245                                    Map<String, String> params = new HashMap<>();
246    
247                                    for (String key : serviceReference.getPropertyKeys()) {
248                                            String value = GetterUtil.getString(
249                                                    serviceReference.getProperty(key));
250    
251                                            params.put(key, value);
252                                    }
253    
254                                    FilterConfig filterConfig = new FilterConfigImpl(
255                                            filterName, _portletContext, params);
256    
257                                    try {
258                                            portletFilter.init(filterConfig);
259                                    }
260                                    catch (PortletException pe) {
261                                            _log.error(pe, pe);
262    
263                                            registry.ungetService(serviceReference);
264    
265                                            return null;
266                                    }
267                            }
268    
269                            if (portletFilter instanceof ActionFilter) {
270                                    _actionFilters.add((ActionFilter)portletFilter);
271                            }
272    
273                            if (portletFilter instanceof EventFilter) {
274                                    _eventFilters.add((EventFilter)portletFilter);
275                            }
276    
277                            if (portletFilter instanceof RenderFilter) {
278                                    _renderFilters.add((RenderFilter)portletFilter);
279                            }
280    
281                            if (portletFilter instanceof ResourceFilter) {
282                                    _resourceFilters.add((ResourceFilter)portletFilter);
283                            }
284    
285                            return portletFilter;
286                    }
287    
288                    @Override
289                    public void modifiedService(
290                            ServiceReference<PortletFilter> serviceReference,
291                            PortletFilter portletFilter) {
292                    }
293    
294                    @Override
295                    public void removedService(
296                            ServiceReference<PortletFilter> serviceReference,
297                            PortletFilter portletFilter) {
298    
299                            Registry registry = RegistryUtil.getRegistry();
300    
301                            registry.ungetService(serviceReference);
302    
303                            _actionFilters.remove(portletFilter);
304                            _eventFilters.remove(portletFilter);
305                            _renderFilters.remove(portletFilter);
306                            _resourceFilters.remove(portletFilter);
307    
308                            boolean preinitializedFilter = GetterUtil.getBoolean(
309                                    serviceReference.getProperty("preinitialized.filter"));
310    
311                            if (preinitializedFilter) {
312                                    return;
313                            }
314    
315                            portletFilter.destroy();
316                    }
317    
318                    private final PortletContext _portletContext;
319    
320            }
321    
322    }