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.dao.shard.ShardPollerProcessorWrapper;
018    import com.liferay.portal.kernel.dao.shard.ShardUtil;
019    import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
020    import com.liferay.portal.kernel.nio.intraband.proxy.TargetLocator;
021    import com.liferay.portal.kernel.poller.PollerProcessor;
022    import com.liferay.portal.nio.intraband.proxy.IntrabandProxyInstallationUtil;
023    import com.liferay.portal.nio.intraband.proxy.IntrabandProxyUtil;
024    import com.liferay.portal.nio.intraband.proxy.StubHolder.StubCreator;
025    import com.liferay.portal.nio.intraband.proxy.StubMap;
026    import com.liferay.portal.nio.intraband.proxy.WarnLogExceptionHandler;
027    import com.liferay.registry.Filter;
028    import com.liferay.registry.Registry;
029    import com.liferay.registry.RegistryUtil;
030    import com.liferay.registry.ServiceReference;
031    import com.liferay.registry.ServiceRegistration;
032    import com.liferay.registry.ServiceTracker;
033    import com.liferay.registry.ServiceTrackerCustomizer;
034    import com.liferay.registry.collections.StringServiceRegistrationMap;
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<String, Object>();
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 StubMap<PollerProcessor>(
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 =
162                            new StringServiceRegistrationMap<PollerProcessor>();
163            private final ServiceTracker<PollerProcessor, PollerProcessor>
164                    _serviceTracker;
165    
166            private static class PollerProcessorTargetLocator implements TargetLocator {
167    
168                    @Override
169                    public Object getTarget(String portletId) {
170                            PollerProcessor pollerProcessor =
171                                    PollerProcessorUtil.getPollerProcessor(portletId);
172    
173                            if (pollerProcessor == null) {
174                                    throw new IllegalStateException(
175                                            "Unable to get poller processor for portlet " + portletId);
176                            }
177    
178                            return pollerProcessor;
179                    }
180    
181            }
182    
183            private class PollerProcessorServiceTrackerCustomizer
184                    implements ServiceTrackerCustomizer<PollerProcessor, PollerProcessor> {
185    
186                    @Override
187                    public PollerProcessor addingService(
188                            ServiceReference<PollerProcessor> serviceReference) {
189    
190                            Registry registry = RegistryUtil.getRegistry();
191    
192                            PollerProcessor pollerProcessor = registry.getService(
193                                    serviceReference);
194    
195                            if (ShardUtil.isEnabled()) {
196                                    pollerProcessor = new ShardPollerProcessorWrapper(
197                                            pollerProcessor);
198                            }
199    
200                            String portletId = (String)serviceReference.getProperty(
201                                    "javax.portlet.name");
202    
203                            _pollerPorcessors.put(portletId, pollerProcessor);
204    
205                            return pollerProcessor;
206                    }
207    
208                    @Override
209                    public void modifiedService(
210                            ServiceReference<PollerProcessor> serviceReference,
211                            PollerProcessor pollerProcessor) {
212                    }
213    
214                    @Override
215                    public void removedService(
216                            ServiceReference<PollerProcessor> serviceReference,
217                            PollerProcessor pollerProcessor) {
218    
219                            Registry registry = RegistryUtil.getRegistry();
220    
221                            registry.ungetService(serviceReference);
222    
223                            String portletId = (String)serviceReference.getProperty(
224                                    "javax.portlet.name");
225    
226                            _pollerPorcessors.remove(portletId);
227                    }
228    
229            }
230    
231    }