/** * 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.registry.internal; import com.liferay.registry.ServiceReference; import com.liferay.registry.ServiceTrackerCustomizer; import com.liferay.registry.collections.ServiceReferenceMapper; import com.liferay.registry.collections.ServiceTrackerMap; import com.liferay.registry.collections.ServiceTrackerMapFactory; import com.liferay.registry.collections.ServiceTrackerMapListener; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.osgi.framework.BundleContext; /** * @author Carlos Sierra Andrés */ public class ServiceTrackerMapFactoryImpl implements ServiceTrackerMapFactory { public ServiceTrackerMapFactoryImpl(BundleContext bundleContext) { _bundleContext = bundleContext; } public void clearServiceTrackerMaps() { Iterator<Reference<com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?>>> iterator = _serviceTrackerMaps.iterator(); while (iterator.hasNext()) { Reference<com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?>> serviceTrackerMapReference = iterator.next(); iterator.remove(); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?> serviceTrackerMap = serviceTrackerMapReference.get(); if (serviceTrackerMap != null) { try { serviceTrackerMap.close(); } catch (Throwable t) { } } } // Drain the reference queue since there are no more service tracker // references while (_referenceQueue.poll() != null); } @Override public <S> ServiceTrackerMap<String, List<S>> multiValueMap( Class<S> clazz, String propertyKey) { com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<String, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, propertyKey); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, S> ServiceTrackerMap<K, List<S>> multiValueMap( Class<S> clazz, String filterString, final ServiceReferenceMapper<K, ? super S> serviceReferenceMapper) { ServiceReferenceMapperWrapper<K, S> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, S> ServiceTrackerMap<K, List<S>> multiValueMap( Class<S> clazz, String filterString, ServiceReferenceMapper<K, ? super S> serviceReferenceMapper, Comparator<ServiceReference<S>> comparator) { ServiceReferenceMapperWrapper<K, S> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceReferenceComparatorAdapter<S> serviceReferenceComparatorAdapter = new ServiceReferenceComparatorAdapter<>(comparator); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceReferenceComparatorAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, S> ServiceTrackerMap<K, List<S>> multiValueMap( Class<S> clazz, String filterString, ServiceReferenceMapper<K, ? super S> serviceReferenceMapper, ServiceTrackerMapListener<K, ? super S, List<S>> serviceTrackerMapListener) { ServiceReferenceMapperWrapper<K, S> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceTrackerMapListenerWrapper<K, S> serviceTrackerMapListenerWrapper = new ServiceTrackerMapListenerWrapper<>( serviceTrackerMapListener); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceTrackerMapListenerWrapper); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, SR, S> ServiceTrackerMap<K, List<S>> multiValueMap( Class<SR> clazz, String filterString, ServiceReferenceMapper<K, ? super SR> serviceReferenceMapper, ServiceTrackerCustomizer<SR, S> serviceTrackerCustomizer) { ServiceReferenceMapperWrapper<K, SR> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceTrackerCustomizerAdapter<SR, S> serviceTrackerCustomizerAdapter = new ServiceTrackerCustomizerAdapter<>(serviceTrackerCustomizer); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceTrackerCustomizerAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, SR, S> ServiceTrackerMap<K, List<S>> multiValueMap( Class<SR> clazz, String filterString, ServiceReferenceMapper<K, ? super SR> serviceReferenceMapper, ServiceTrackerCustomizer<SR, S> serviceTrackerCustomizer, Comparator<ServiceReference<SR>> comparator) { ServiceReferenceMapperWrapper<K, SR> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceTrackerCustomizerAdapter<SR, S> serviceTrackerCustomizerAdapter = new ServiceTrackerCustomizerAdapter<>(serviceTrackerCustomizer); ServiceReferenceComparatorAdapter<SR> serviceReferenceComparatorAdapter = new ServiceReferenceComparatorAdapter<>(comparator); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceTrackerCustomizerAdapter, serviceReferenceComparatorAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <SR, S> ServiceTrackerMap<String, List<S>> multiValueMap( Class<SR> clazz, String propertyKey, ServiceTrackerCustomizer<SR, S> serviceTrackerCustomizer) { ServiceTrackerCustomizerAdapter<SR, S> serviceTrackerCustomizerAdapter = new ServiceTrackerCustomizerAdapter<>(serviceTrackerCustomizer); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<String, List<S>> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.multiValueMap( _bundleContext, clazz, propertyKey, serviceTrackerCustomizerAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <S> ServiceTrackerMap<String, S> singleValueMap( Class<S> clazz, String propertyKey) { com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<String, S> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.singleValueMap( _bundleContext, clazz, propertyKey); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, S> ServiceTrackerMap<K, S> singleValueMap( Class<S> clazz, String filterString, ServiceReferenceMapper<K, ? super S> serviceReferenceMapper) { ServiceReferenceMapperWrapper<K, S> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, S> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.singleValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, S> ServiceTrackerMap<K, S> singleValueMap( Class<S> clazz, String filterString, ServiceReferenceMapper<K, ? super S> serviceReferenceMapper, final Comparator<ServiceReference<S>> comparator) { ServiceReferenceMapperWrapper<K, S> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceReferenceComparatorAdapter<S> serviceReferenceComparatorAdapter = new ServiceReferenceComparatorAdapter<>(comparator); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, S> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.singleValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceReferenceComparatorAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, SR, S> ServiceTrackerMap<K, S> singleValueMap( Class<SR> clazz, String filterString, ServiceReferenceMapper<K, ? super SR> serviceReferenceMapper, ServiceTrackerCustomizer<SR, S> serviceTrackerCustomizer) { ServiceReferenceMapperWrapper<K, SR> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceTrackerCustomizerAdapter<SR, S> serviceTrackerCustomizerAdapter = new ServiceTrackerCustomizerAdapter<>(serviceTrackerCustomizer); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, S> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.singleValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceTrackerCustomizerAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <K, SR, S> ServiceTrackerMap<K, S> singleValueMap( Class<SR> clazz, String filterString, ServiceReferenceMapper<K, ? super SR> serviceReferenceMapper, ServiceTrackerCustomizer<SR, S> serviceTrackerCustomizer, Comparator<ServiceReference<SR>> comparator) { ServiceReferenceMapperWrapper<K, SR> serviceReferenceMapperWrapper = new ServiceReferenceMapperWrapper<>(serviceReferenceMapper); ServiceTrackerCustomizerAdapter<SR, S> serviceTrackerCustomizerAdapter = new ServiceTrackerCustomizerAdapter<>(serviceTrackerCustomizer); ServiceReferenceComparatorAdapter<SR> serviceReferenceComparatorAdapter = new ServiceReferenceComparatorAdapter<>(comparator); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, S> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.singleValueMap( _bundleContext, clazz, filterString, serviceReferenceMapperWrapper, serviceTrackerCustomizerAdapter, serviceReferenceComparatorAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } @Override public <SR, S> ServiceTrackerMap<String, S> singleValueMap( Class<SR> clazz, String propertyKey, ServiceTrackerCustomizer<SR, S> serviceTrackerCustomizer) { ServiceTrackerCustomizerAdapter<SR, S> serviceTrackerCustomizerAdapter = new ServiceTrackerCustomizerAdapter<>(serviceTrackerCustomizer); com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<String, S> serviceTrackerMap = com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapFactory.singleValueMap( _bundleContext, clazz, propertyKey, serviceTrackerCustomizerAdapter); addServiceTrackerMap(serviceTrackerMap); return new ServiceTrackerMapWrapper<>(serviceTrackerMap); } protected void addServiceTrackerMap( com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?> serviceTrackerMap) { Reference<com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?>> reference = new WeakReference<>( serviceTrackerMap, _referenceQueue); _serviceTrackerMaps.add(reference); while ((reference = (Reference<com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?>>) _referenceQueue.poll()) != null) { _serviceTrackerMaps.remove(reference); } } private final BundleContext _bundleContext; private final ReferenceQueue<com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?>> _referenceQueue = new ReferenceQueue<>(); private final Set<Reference<com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<?, ?>>> _serviceTrackerMaps = Collections.newSetFromMap(new ConcurrentHashMap<>()); private static class EmitterWrapper<K> implements ServiceReferenceMapper.Emitter<K> { public EmitterWrapper( com.liferay.osgi.service.tracker.collections.map. ServiceReferenceMapper.Emitter<K> emitter) { _emitter = emitter; } @Override public void emit(K key) { _emitter.emit(key); } private final com.liferay.osgi.service.tracker.collections.map. ServiceReferenceMapper.Emitter<K> _emitter; } private static class ServiceReferenceComparatorAdapter<S> implements Comparator<org.osgi.framework.ServiceReference<S>> { public ServiceReferenceComparatorAdapter( Comparator<ServiceReference<S>> comparator) { _comparator = comparator; } @Override public int compare( org.osgi.framework.ServiceReference<S> serviceReference1, org.osgi.framework.ServiceReference<S> serviceReference2) { return _comparator.compare( new ServiceReferenceWrapper<S>(serviceReference1), new ServiceReferenceWrapper<S>(serviceReference2)); } private final Comparator<ServiceReference<S>> _comparator; } private static class ServiceReferenceMapperWrapper<K, S> implements com.liferay.osgi.service.tracker.collections.map. ServiceReferenceMapper<K, S> { public ServiceReferenceMapperWrapper( ServiceReferenceMapper<K, ? super S> serviceReferenceMapper) { _serviceReferenceMapper = serviceReferenceMapper; } @Override @SuppressWarnings({"rawtypes", "unchecked"}) public void map( org.osgi.framework.ServiceReference<S> serviceReference, final Emitter<K> emitter) { ServiceReferenceWrapper<S> serviceReferenceWrapper = new ServiceReferenceWrapper<>(serviceReference); _serviceReferenceMapper.map( (ServiceReferenceWrapper)serviceReferenceWrapper, new EmitterWrapper<>(emitter)); } private final ServiceReferenceMapper<K, ? super S> _serviceReferenceMapper; } private static class ServiceTrackerMapListenerWrapper<K, S> implements com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMapListener<K, S, List<S>> { public ServiceTrackerMapListenerWrapper( ServiceTrackerMapListener<K, ? super S, List<S>> serviceTrackerMapListener) { _serviceTrackerMapListener = serviceTrackerMapListener; } @Override public void keyEmitted( com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMap <K, List<S>> serviceTrackerMap, K key, S service, List<S> content) { _serviceTrackerMapListener.keyEmitted( new ServiceTrackerMapWrapper<>(serviceTrackerMap), key, service, content); } @Override public void keyRemoved( com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMap <K, List<S>> serviceTrackerMap, K key, S service, List<S> content) { _serviceTrackerMapListener.keyRemoved( new ServiceTrackerMapWrapper<>(serviceTrackerMap), key, service, content); } private final ServiceTrackerMapListener<K, ? super S, List<S>> _serviceTrackerMapListener; } private static class ServiceTrackerMapWrapper<K, S> implements ServiceTrackerMap<K, S> { public ServiceTrackerMapWrapper( com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, S> serviceTrackerMap) { _serviceTrackerMap = serviceTrackerMap; } @Override public void close() { _serviceTrackerMap.close(); } @Override public boolean containsKey(K k) { return _serviceTrackerMap.containsKey(k); } @Override public S getService(K k) { return _serviceTrackerMap.getService(k); } @Override public Set<K> keySet() { return _serviceTrackerMap.keySet(); } @Override public void open() { _serviceTrackerMap.open(); } private final com.liferay.osgi.service.tracker.collections.map. ServiceTrackerMap<K, S> _serviceTrackerMap; } }