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> stubPollerClass =
123                                                    (Class<? extends PollerProcessor>)
124                                                            IntrabandProxyUtil.getStubClass(
125                                                                    PollerProcessor.class,
126                                                                    PollerProcessor.class.getName());
127    
128                                            IntrabandProxyInstallationUtil.checkProxyMethodSignatures(
129                                                    skeletonProxyMethodSignatures,
130                                                    IntrabandProxyUtil.getProxyMethodSignatures(
131                                                            stubPollerClass));
132    
133                                            return IntrabandProxyUtil.newStubInstance(
134                                                    stubPollerClass, portletId, registrationReference,
135                                                    WarnLogExceptionHandler.INSTANCE);
136                                    }
137    
138                                    @Override
139                                    public PollerProcessor onCreationFailure(
140                                            String portletId, PollerProcessor pollerProcessor,
141                                            Exception e) {
142    
143                                            return pollerProcessor;
144                                    }
145    
146                                    @Override
147                                    public PollerProcessor onInvalidation(
148                                            String portletId, PollerProcessor pollerProcessor,
149                                            PollerProcessor stubPollerProcessor) {
150    
151                                            _pollerPorcessors.removeStubHolder(
152                                                    portletId, stubPollerProcessor);
153    
154                                            return pollerProcessor;
155                                    }
156    
157                            });
158    
159            private final StringServiceRegistrationMap<PollerProcessor>
160                    _serviceRegistrations = new StringServiceRegistrationMapImpl<>();
161            private final ServiceTracker<PollerProcessor, PollerProcessor>
162                    _serviceTracker;
163    
164            private static class PollerProcessorTargetLocator implements TargetLocator {
165    
166                    @Override
167                    public Object getTarget(String portletId) {
168                            PollerProcessor pollerProcessor =
169                                    PollerProcessorUtil.getPollerProcessor(portletId);
170    
171                            if (pollerProcessor == null) {
172                                    throw new IllegalStateException(
173                                            "Unable to get poller processor for portlet " + portletId);
174                            }
175    
176                            return pollerProcessor;
177                    }
178    
179            }
180    
181            private class PollerProcessorServiceTrackerCustomizer
182                    implements ServiceTrackerCustomizer<PollerProcessor, PollerProcessor> {
183    
184                    @Override
185                    public PollerProcessor addingService(
186                            ServiceReference<PollerProcessor> serviceReference) {
187    
188                            Registry registry = RegistryUtil.getRegistry();
189    
190                            PollerProcessor pollerProcessor = registry.getService(
191                                    serviceReference);
192    
193                            String portletId = (String)serviceReference.getProperty(
194                                    "javax.portlet.name");
195    
196                            _pollerPorcessors.put(portletId, pollerProcessor);
197    
198                            return pollerProcessor;
199                    }
200    
201                    @Override
202                    public void modifiedService(
203                            ServiceReference<PollerProcessor> serviceReference,
204                            PollerProcessor pollerProcessor) {
205                    }
206    
207                    @Override
208                    public void removedService(
209                            ServiceReference<PollerProcessor> serviceReference,
210                            PollerProcessor pollerProcessor) {
211    
212                            Registry registry = RegistryUtil.getRegistry();
213    
214                            registry.ungetService(serviceReference);
215    
216                            String portletId = (String)serviceReference.getProperty(
217                                    "javax.portlet.name");
218    
219                            _pollerPorcessors.remove(portletId);
220                    }
221    
222            }
223    
224    }