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.poller;
016    
017    import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
018    import com.liferay.portal.kernel.nio.intraband.proxy.TargetLocator;
019    import com.liferay.portal.kernel.poller.PollerProcessor;
020    import com.liferay.portal.nio.intraband.proxy.IntrabandProxyInstallationUtil;
021    import com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil;
022    import com.liferay.portal.nio.intraband.proxy.StubHolder.StubCreator;
023    import com.liferay.portal.nio.intraband.proxy.StubMap;
024    import com.liferay.portal.nio.intraband.proxy.StubMapImpl;
025    import com.liferay.portal.nio.intraband.proxy.WarnLogExceptionHandler;
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    import com.liferay.registry.collections.StringServiceRegistrationMap;
034    import com.liferay.registry.collections.StringServiceRegistrationMapImpl;
035    
036    import java.util.HashMap;
037    import java.util.Map;
038    import java.util.concurrent.Future;
039    
040    /**
041     * @author Brian Wing Shun Chan
042     */
043    public class PollerProcessorUtil {
044    
045            public static void addPollerProcessor(
046                    String portletId, PollerProcessor pollerProcessor) {
047    
048                    _instance._addPollerProcessor(portletId, pollerProcessor);
049            }
050    
051            public static void deletePollerProcessor(String portletId) {
052                    _instance._deletePollerProcessor(portletId);
053            }
054    
055            public static PollerProcessor getPollerProcessor(String portletId) {
056                    return _instance._getPollerProcessor(portletId);
057            }
058    
059            private PollerProcessorUtil() {
060                    Registry registry = RegistryUtil.getRegistry();
061    
062                    Filter filter = registry.getFilter(
063                            "(&(javax.portlet.name=*)(objectClass=" +
064                                    PollerProcessor.class.getName() + "))");
065    
066                    _serviceTracker = registry.trackServices(
067                            filter, new PollerProcessorServiceTrackerCustomizer());
068    
069                    _serviceTracker.open();
070            }
071    
072            private void _addPollerProcessor(
073                    String portletId, PollerProcessor pollerProcessor) {
074    
075                    Registry registry = RegistryUtil.getRegistry();
076    
077                    Map<String, Object> properties = new HashMap<>();
078    
079                    properties.put("javax.portlet.name", portletId);
080    
081                    ServiceRegistration<PollerProcessor> serviceRegistration =
082                            registry.registerService(
083                                    PollerProcessor.class, pollerProcessor, properties);
084    
085                    _serviceRegistrations.put(portletId, serviceRegistration);
086            }
087    
088            private void _deletePollerProcessor(String portletId) {
089                    ServiceRegistration<PollerProcessor> serviceRegistration =
090                            _serviceRegistrations.remove(portletId);
091    
092                    if (serviceRegistration != null) {
093                            serviceRegistration.unregister();
094                    }
095            }
096    
097            private PollerProcessor _getPollerProcessor(String portletId) {
098                    return _pollerPorcessors.get(portletId);
099            }
100    
101            private static final PollerProcessorUtil _instance =
102                    new PollerProcessorUtil();
103    
104            private final StubMap<PollerProcessor> _pollerPorcessors =
105                    new StubMapImpl<>(
106                            new StubCreator<PollerProcessor>() {
107    
108                                    @Override
109                                    public PollerProcessor createStub(
110                                                    String portletId, PollerProcessor pollerProcessor,
111                                                    RegistrationReference registrationReference)
112                                            throws Exception {
113    
114                                            Future<String[]> skeletonProxyMethodSignaturesFuture =
115                                                    IntrabandProxyInstallationUtil.installSkeleton(
116                                                            registrationReference, PollerProcessor.class,
117                                                            new PollerProcessorTargetLocator());
118    
119                                            String[] skeletonProxyMethodSignatures =
120                                                    skeletonProxyMethodSignaturesFuture.get();
121    
122                                            Class<? extends PollerProcessor>
123                                                    stubPollerClass =
124                                                            (Class<? extends PollerProcessor>)
125                                                                    IntrabandProxyUtil.getStubClass(
126                                                                            PollerProcessor.class,
127                                                                            PollerProcessor.class.getName());
128    
129                                            IntrabandProxyInstallationUtil.checkProxyMethodSignatures(
130                                                    skeletonProxyMethodSignatures,
131                                                    IntrabandProxyUtil.getProxyMethodSignatures(
132                                                            stubPollerClass));
133    
134                                            return IntrabandProxyUtil.newStubInstance(
135                                                    stubPollerClass, portletId, registrationReference,
136                                                    WarnLogExceptionHandler.INSTANCE);
137                                    }
138    
139                                    @Override
140                                    public PollerProcessor onCreationFailure(
141                                            String portletId, PollerProcessor pollerProcessor,
142                                            Exception e) {
143    
144                                            return pollerProcessor;
145                                    }
146    
147                                    @Override
148                                    public PollerProcessor onInvalidation(
149                                            String portletId, PollerProcessor pollerProcessor,
150                                            PollerProcessor stubPollerProcessor) {
151    
152                                            _pollerPorcessors.removeStubHolder(
153                                                    portletId, stubPollerProcessor);
154    
155                                            return pollerProcessor;
156                                    }
157    
158                            });
159    
160            private final StringServiceRegistrationMap<PollerProcessor>
161                    _serviceRegistrations = new StringServiceRegistrationMapImpl<>();
162            private final ServiceTracker<PollerProcessor, PollerProcessor>
163                    _serviceTracker;
164    
165            private static class PollerProcessorTargetLocator implements TargetLocator {
166    
167                    @Override
168                    public Object getTarget(String portletId) {
169                            PollerProcessor pollerProcessor =
170                                    PollerProcessorUtil.getPollerProcessor(portletId);
171    
172                            if (pollerProcessor == null) {
173                                    throw new IllegalStateException(
174                                            "Unable to get poller processor for portlet " + portletId);
175                            }
176    
177                            return pollerProcessor;
178                    }
179    
180            }
181    
182            private class PollerProcessorServiceTrackerCustomizer
183                    implements ServiceTrackerCustomizer<PollerProcessor, PollerProcessor> {
184    
185                    @Override
186                    public PollerProcessor addingService(
187                            ServiceReference<PollerProcessor> serviceReference) {
188    
189                            Registry registry = RegistryUtil.getRegistry();
190    
191                            PollerProcessor pollerProcessor = registry.getService(
192                                    serviceReference);
193    
194                            String portletId = (String)serviceReference.getProperty(
195                                    "javax.portlet.name");
196    
197                            _pollerPorcessors.put(portletId, pollerProcessor);
198    
199                            return pollerProcessor;
200                    }
201    
202                    @Override
203                    public void modifiedService(
204                            ServiceReference<PollerProcessor> serviceReference,
205                            PollerProcessor pollerProcessor) {
206                    }
207    
208                    @Override
209                    public void removedService(
210                            ServiceReference<PollerProcessor> serviceReference,
211                            PollerProcessor pollerProcessor) {
212    
213                            Registry registry = RegistryUtil.getRegistry();
214    
215                            registry.ungetService(serviceReference);
216    
217                            String portletId = (String)serviceReference.getProperty(
218                                    "javax.portlet.name");
219    
220                            _pollerPorcessors.remove(portletId);
221                    }
222    
223            }
224    
225    }