
com.liferay.registry.collections.internal.ServiceTrackerCollectionImpl Maven / Gradle / Ivy
/**
* 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.collections.internal;
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 com.liferay.registry.collections.ServiceRegistrationMap;
import com.liferay.registry.collections.ServiceRegistrationMapImpl;
import com.liferay.registry.collections.ServiceTrackerList;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author Raymond Augé
*/
public class ServiceTrackerCollectionImpl implements ServiceTrackerList {
public ServiceTrackerCollectionImpl(
Class clazz, Filter filter,
ServiceTrackerCustomizer serviceTrackerCustomizer,
Map properties) {
_clazz = clazz;
_filter = filter;
_properties = Collections.unmodifiableMap(properties);
Registry registry = RegistryUtil.getRegistry();
if (filter != null) {
filter = _getFilter(filter, _clazz);
_serviceTracker = registry.trackServices(
filter,
new DefaultServiceTrackerCustomizer(serviceTrackerCustomizer));
}
else {
_serviceTracker = registry.trackServices(
clazz,
new DefaultServiceTrackerCustomizer(serviceTrackerCustomizer));
}
}
@Override
public void add(int index, S service) {
throw new UnsupportedOperationException();
}
@Override
public boolean add(S service) {
if (service == null) {
throw new IllegalArgumentException("Service is null");
}
if ((_filter != null) && !_filter.matches(_properties)) {
throw new IllegalStateException();
}
Map properties = new HashMap<>(_properties);
Registry registry = RegistryUtil.getRegistry();
ServiceRegistration serviceRegistration = registry.registerService(
_clazz, service, properties);
_serviceRegistrations.put(service, serviceRegistration);
return true;
}
@Override
public boolean add(S service, Map properties) {
if (service == null) {
throw new IllegalArgumentException("Service is null");
}
properties = new HashMap<>(properties);
properties.putAll(_properties);
if ((_filter != null) && !_filter.matches(properties)) {
throw new IllegalArgumentException(
"Filter does not match properties " + properties);
}
Registry registry = RegistryUtil.getRegistry();
ServiceRegistration serviceRegistration = registry.registerService(
_clazz, service, properties);
_serviceRegistrations.put(service, serviceRegistration);
return true;
}
@Override
public boolean addAll(Collection extends S> services) {
boolean modified = false;
for (S service : services) {
if (add(service)) {
modified = true;
}
}
return modified;
}
@Override
public boolean addAll(int index, Collection extends S> services) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
Set>> set =
_serviceRegistrations.entrySet();
Iterator>> iterator = set.iterator();
while (iterator.hasNext()) {
Entry> entry = iterator.next();
ServiceRegistration serviceRegistration = entry.getValue();
serviceRegistration.unregister();
iterator.remove();
}
}
@Override
public void close() {
clear();
_serviceTracker.close();
}
@Override
public boolean contains(Object service) {
return _services.contains(service);
}
@Override
public boolean containsAll(Collection> services) {
throw new UnsupportedOperationException();
}
@Override
public S get(int index) {
EntryWrapper entryWrapper = _services.get(index);
return entryWrapper._service;
}
@Override
public int indexOf(Object service) {
return _services.indexOf(service);
}
@Override
public boolean isEmpty() {
return _services.isEmpty();
}
@Override
public Iterator iterator() {
return new ServiceTrackerIterator(_services.listIterator());
}
@Override
public int lastIndexOf(Object service) {
return _services.lastIndexOf(service);
}
@Override
public ListIterator listIterator() {
return new ServiceTrackerIterator(_services.listIterator());
}
@Override
public ListIterator listIterator(int index) {
return new ServiceTrackerIterator(_services.listIterator(index));
}
@Override
public void open() {
_serviceTracker.open();
}
@Override
public S remove(int index) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object service) {
ServiceRegistration serviceRegistration =
_serviceRegistrations.remove(service);
if (serviceRegistration == null) {
return false;
}
serviceRegistration.unregister();
return true;
}
@Override
public boolean removeAll(Collection> services) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection> services) {
throw new UnsupportedOperationException();
}
@Override
public S set(int index, S service) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return _services.size();
}
@Override
public List subList(int fromIndex, int toIndex) {
List list = new ArrayList<>();
List subList = _services.subList(fromIndex, toIndex);
for (EntryWrapper entryWrapper : subList) {
list.add(entryWrapper._service);
}
return list;
}
@Override
public Object[] toArray() {
return toArray(new Object[0]);
}
@Override
public T[] toArray(T[] services) {
if (services.length < _services.size()) {
Class> clazz = services.getClass();
services = (T[])Array.newInstance(
clazz.getComponentType(), _services.size());
}
for (int i = 0; i < _services.size(); i++) {
EntryWrapper entryWrapper = _services.get(i);
services[i] = (T)entryWrapper._service;
}
if (services.length > _services.size()) {
services[_services.size()] = null;
}
return services;
}
private Filter _getFilter(Filter filter, Class clazz) {
Map properties =
Collections.singletonMap(
"objectClass", clazz.getName());
if (filter.matches(properties)) {
return filter;
}
Registry registry = RegistryUtil.getRegistry();
StringBuilder sb = new StringBuilder(5);
sb.append("(&(objectClass=");
sb.append(clazz.getName());
sb.append(")");
sb.append(filter.toString());
sb.append(")");
return registry.getFilter(sb.toString());
}
private final Class _clazz;
private final Filter _filter;
private final Map _properties;
private final ServiceRegistrationMap _serviceRegistrations =
new ServiceRegistrationMapImpl<>();
private final List _services = new CopyOnWriteArrayList<>();
private final ServiceTracker _serviceTracker;
private class DefaultServiceTrackerCustomizer
implements ServiceTrackerCustomizer {
public DefaultServiceTrackerCustomizer(
ServiceTrackerCustomizer serviceTrackerCustomizer) {
_serviceTrackerCustomizer = serviceTrackerCustomizer;
}
@Override
public S addingService(ServiceReference serviceReference) {
S service = null;
if (_serviceTrackerCustomizer != null) {
service = _serviceTrackerCustomizer.addingService(
serviceReference);
}
else {
Registry registry = RegistryUtil.getRegistry();
service = registry.getService(serviceReference);
}
_update(serviceReference, service, false);
return service;
}
@Override
public void modifiedService(
ServiceReference serviceReference, S service) {
if (_serviceTrackerCustomizer != null) {
_serviceTrackerCustomizer.modifiedService(
serviceReference, service);
}
_update(serviceReference, service, false);
}
@Override
public void removedService(
ServiceReference serviceReference, S service) {
if (_serviceTrackerCustomizer != null) {
_serviceTrackerCustomizer.removedService(
serviceReference, service);
}
_update(serviceReference, service, true);
Registry registry = RegistryUtil.getRegistry();
registry.ungetService(serviceReference);
}
private void _update(
ServiceReference serviceReference, S service, boolean remove) {
if (service == null) {
return;
}
EntryWrapper entryWrapper = new EntryWrapper(
serviceReference, service);
synchronized(_services) {
int index = Collections.binarySearch(_services, entryWrapper);
if (remove) {
if (index >= 0) {
_services.remove(index);
}
}
else if (index < 0) {
_services.add(((-index) - 1), entryWrapper);
}
}
}
private final ServiceTrackerCustomizer _serviceTrackerCustomizer;
}
private class EntryWrapper implements Comparable {
public EntryWrapper(ServiceReference serviceReference, S service) {
_serviceReference = serviceReference;
_service = service;
}
@Override
public int compareTo(EntryWrapper entryWrapper) {
// The order is deliberately reversed
return entryWrapper._serviceReference.compareTo(_serviceReference);
}
private final S _service;
private final ServiceReference _serviceReference;
}
private class ServiceTrackerIterator implements ListIterator {
public ServiceTrackerIterator(ListIterator listIterator) {
_listIterator = listIterator;
}
@Override
public void add(S service) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasNext() {
return _listIterator.hasNext();
}
@Override
public boolean hasPrevious() {
return _listIterator.hasPrevious();
}
@Override
public S next() {
EntryWrapper entryWrapper = _listIterator.next();
return entryWrapper._service;
}
@Override
public int nextIndex() {
return _listIterator.nextIndex();
}
@Override
public S previous() {
EntryWrapper entryWrapper = _listIterator.previous();
return entryWrapper._service;
}
@Override
public int previousIndex() {
return _listIterator.previousIndex();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void set(S service) {
throw new UnsupportedOperationException();
}
private final ListIterator _listIterator;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy