/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portlet;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.portlet.InvokerFilterContainer;
import com.liferay.portal.kernel.util.ClassLoaderUtil;
import com.liferay.portal.kernel.util.ClassUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.model.impl.PortletFilterImpl;
import com.liferay.portal.util.PropsValues;
import com.liferay.registry.Filter;
import com.liferay.registry.Registry;
import com.liferay.registry.RegistryUtil;
import com.liferay.registry.ServiceReference;
import com.liferay.registry.ServiceRegistration;
import com.liferay.registry.ServiceTracker;
import com.liferay.registry.ServiceTrackerCustomizer;
import java.io.Closeable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.filter.ActionFilter;
import javax.portlet.filter.EventFilter;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.PortletFilter;
import javax.portlet.filter.RenderFilter;
import javax.portlet.filter.ResourceFilter;
/**
* @author Raymond Augé
*/
public class InvokerFilterContainerImpl
implements Closeable, InvokerFilterContainer {
public static final InvokerFilterContainer EMPTY_INVOKER_FILTER_CONTAINER =
new EmptyInvokerFilterContainer();
public InvokerFilterContainerImpl(
Portlet portlet, PortletContext portletContext)
throws PortletException {
String rootPortletId = portlet.getRootPortletId();
Registry registry = RegistryUtil.getRegistry();
Filter filter = registry.getFilter(
"(&(javax.portlet.name=" + rootPortletId + ")(objectClass=" +
PortletFilter.class.getName() + "))");
_serviceTracker = registry.trackServices(
filter, new PortletFilterServiceTrackerCustomizer(portletContext));
_serviceTracker.open();
Map<String, Object> properties = new HashMap<>();
properties.put("javax.portlet.name", rootPortletId);
properties.put("preinitialized.filter", Boolean.TRUE);
Map<String, com.liferay.portal.kernel.model.PortletFilter>
portletFilters = portlet.getPortletFilters();
for (Map.Entry<String, com.liferay.portal.kernel.model.PortletFilter>
entry : portletFilters.entrySet()) {
com.liferay.portal.kernel.model.PortletFilter portletFilterModel =
entry.getValue();
PortletFilter portletFilter = PortletFilterFactory.create(
portletFilterModel, portletContext);
ServiceRegistration<PortletFilter> serviceRegistration =
registry.registerService(
PortletFilter.class, portletFilter, properties);
ServiceRegistrationTuple serviceRegistrationTuple =
new ServiceRegistrationTuple(
portletFilterModel, serviceRegistration);
_serviceRegistrationTuples.add(serviceRegistrationTuple);
}
ClassLoader classLoader = ClassLoaderUtil.getContextClassLoader();
try {
ClassLoaderUtil.setContextClassLoader(
ClassLoaderUtil.getPortalClassLoader());
for (String portletFilterClassName :
PropsValues.PORTLET_FILTERS_SYSTEM) {
com.liferay.portal.kernel.model.PortletFilter
portletFilterModel = new PortletFilterImpl(
portletFilterClassName, portletFilterClassName,
Collections.<String>emptySet(),
Collections.<String, String>emptyMap(),
portlet.getPortletApp());
PortletFilter portletFilter = PortletFilterFactory.create(
portletFilterModel, portletContext);
ServiceRegistration<PortletFilter> serviceRegistration =
registry.registerService(
PortletFilter.class, portletFilter, properties);
_serviceRegistrationTuples.add(
new ServiceRegistrationTuple(
portletFilterModel, serviceRegistration));
}
}
finally {
ClassLoaderUtil.setContextClassLoader(classLoader);
}
}
@Override
public void close() {
for (ServiceRegistrationTuple serviceRegistrationTuple :
_serviceRegistrationTuples) {
PortletFilterFactory.destroy(
serviceRegistrationTuple.getPortletFilterModel());
ServiceRegistration<PortletFilter> serviceRegistration =
serviceRegistrationTuple.getServiceRegistration();
serviceRegistration.unregister();
}
_serviceRegistrationTuples.clear();
_serviceTracker.close();
_actionFilters.clear();
_eventFilters.clear();
_renderFilters.clear();
_resourceFilters.clear();
}
@Override
public List<ActionFilter> getActionFilters() {
return _actionFilters;
}
@Override
public List<EventFilter> getEventFilters() {
return _eventFilters;
}
@Override
public List<RenderFilter> getRenderFilters() {
return _renderFilters;
}
@Override
public List<ResourceFilter> getResourceFilters() {
return _resourceFilters;
}
private static final Log _log = LogFactoryUtil.getLog(
InvokerFilterContainerImpl.class);
private final List<ActionFilter> _actionFilters =
new CopyOnWriteArrayList<>();
private final List<EventFilter> _eventFilters =
new CopyOnWriteArrayList<>();
private final List<RenderFilter> _renderFilters =
new CopyOnWriteArrayList<>();
private final List<ResourceFilter> _resourceFilters =
new CopyOnWriteArrayList<>();
private final List<ServiceRegistrationTuple> _serviceRegistrationTuples =
new CopyOnWriteArrayList<>();
private final ServiceTracker<PortletFilter, PortletFilter> _serviceTracker;
private static class EmptyInvokerFilterContainer
implements Closeable, InvokerFilterContainer {
@Override
public void close() {
}
@Override
public List<ActionFilter> getActionFilters() {
return Collections.emptyList();
}
@Override
public List<EventFilter> getEventFilters() {
return Collections.emptyList();
}
@Override
public List<RenderFilter> getRenderFilters() {
return Collections.emptyList();
}
@Override
public List<ResourceFilter> getResourceFilters() {
return Collections.emptyList();
}
}
private static class ServiceRegistrationTuple {
public ServiceRegistrationTuple(
com.liferay.portal.kernel.model.PortletFilter portletFilterModel,
ServiceRegistration<PortletFilter> serviceRegistration) {
_portletFilterModel = portletFilterModel;
_serviceRegistration = serviceRegistration;
}
public com.liferay.portal.kernel.model.PortletFilter
getPortletFilterModel() {
return _portletFilterModel;
}
public ServiceRegistration<PortletFilter> getServiceRegistration() {
return _serviceRegistration;
}
private final com.liferay.portal.kernel.model.PortletFilter
_portletFilterModel;
private final ServiceRegistration<PortletFilter> _serviceRegistration;
}
private class PortletFilterServiceTrackerCustomizer
implements ServiceTrackerCustomizer<PortletFilter, PortletFilter> {
public PortletFilterServiceTrackerCustomizer(
PortletContext portletContext) {
_portletContext = portletContext;
}
@Override
public PortletFilter addingService(
ServiceReference<PortletFilter> serviceReference) {
Registry registry = RegistryUtil.getRegistry();
PortletFilter portletFilter = registry.getService(serviceReference);
boolean preinitializedFilter = GetterUtil.getBoolean(
serviceReference.getProperty("preinitialized.filter"));
if (!preinitializedFilter) {
String filterName = GetterUtil.getString(
serviceReference.getProperty("service.id"),
ClassUtil.getClassName(portletFilter));
Map<String, String> params = new HashMap<>();
for (String key : serviceReference.getPropertyKeys()) {
String value = GetterUtil.getString(
serviceReference.getProperty(key));
params.put(key, value);
}
FilterConfig filterConfig = new FilterConfigImpl(
filterName, _portletContext, params);
try {
portletFilter.init(filterConfig);
}
catch (PortletException pe) {
_log.error(pe, pe);
registry.ungetService(serviceReference);
return null;
}
}
if (portletFilter instanceof ActionFilter) {
_actionFilters.add((ActionFilter)portletFilter);
}
if (portletFilter instanceof EventFilter) {
_eventFilters.add((EventFilter)portletFilter);
}
if (portletFilter instanceof RenderFilter) {
_renderFilters.add((RenderFilter)portletFilter);
}
if (portletFilter instanceof ResourceFilter) {
_resourceFilters.add((ResourceFilter)portletFilter);
}
return portletFilter;
}
@Override
public void modifiedService(
ServiceReference<PortletFilter> serviceReference,
PortletFilter portletFilter) {
}
@Override
public void removedService(
ServiceReference<PortletFilter> serviceReference,
PortletFilter portletFilter) {
Registry registry = RegistryUtil.getRegistry();
registry.ungetService(serviceReference);
_actionFilters.remove(portletFilter);
_eventFilters.remove(portletFilter);
_renderFilters.remove(portletFilter);
_resourceFilters.remove(portletFilter);
boolean preinitializedFilter = GetterUtil.getBoolean(
serviceReference.getProperty("preinitialized.filter"));
if (preinitializedFilter) {
return;
}
portletFilter.destroy();
}
private final PortletContext _portletContext;
}
}