001
014
015 package com.liferay.portal.kernel.display.context;
016
017 import com.liferay.registry.Filter;
018 import com.liferay.registry.Registry;
019 import com.liferay.registry.RegistryUtil;
020 import com.liferay.registry.ServiceReference;
021 import com.liferay.registry.ServiceTracker;
022 import com.liferay.registry.ServiceTrackerCustomizer;
023
024 import java.util.Iterator;
025 import java.util.SortedSet;
026 import java.util.concurrent.ConcurrentHashMap;
027 import java.util.concurrent.ConcurrentMap;
028 import java.util.concurrent.ConcurrentSkipListSet;
029
030
033 public class BaseDisplayContextProvider<T extends DisplayContextFactory>
034 implements DisplayContextProvider {
035
036 public BaseDisplayContextProvider(Class<T> displayContextFactoryClass) {
037 Registry registry = RegistryUtil.getRegistry();
038
039 Filter filter = registry.getFilter(
040 "(objectClass=" + displayContextFactoryClass.getName() + ")");
041
042 _serviceTracker = registry.trackServices(
043 filter, new DisplayContextFactoryServiceTrackerCustomizer());
044
045 _serviceTracker.open();
046 }
047
048 public void destroy() {
049 _serviceTracker.close();
050 }
051
052 public Iterable<T> getDisplayContextFactories() {
053 return new DisplayContextFactoriesIterable<>(
054 _displayContextFactoryReferences);
055 }
056
057 private final SortedSet<DisplayContextFactoryReference<T>>
058 _displayContextFactoryReferences = new ConcurrentSkipListSet<>();
059 private final ConcurrentMap<T, DisplayContextFactoryReference<T>>
060 _displayContextFactoryReferencesMap = new ConcurrentHashMap<>();
061 private final ServiceTracker<T, T> _serviceTracker;
062
063 private static class DisplayContextFactoriesIterable
064 <T extends DisplayContextFactory>
065 implements Iterable<T>, Iterator<T> {
066
067 public DisplayContextFactoriesIterable(
068 Iterable<DisplayContextFactoryReference<T>> iterable) {
069
070 _iterator = iterable.iterator();
071 }
072
073 @Override
074 public boolean hasNext() {
075 return _iterator.hasNext();
076 }
077
078 @Override
079 public Iterator<T> iterator() {
080 return this;
081 }
082
083 @Override
084 public T next() {
085 DisplayContextFactoryReference<T> displayContextFactoryReference =
086 _iterator.next();
087
088 return displayContextFactoryReference.getDisplayContextFactory();
089 }
090
091 @Override
092 public void remove() {
093 throw new UnsupportedOperationException("Iterator is read-only");
094 }
095
096 private final Iterator<DisplayContextFactoryReference<T>> _iterator;
097
098 }
099
100 private class DisplayContextFactoryServiceTrackerCustomizer
101 implements ServiceTrackerCustomizer<T, T> {
102
103 @Override
104 public T addingService(ServiceReference<T> serviceReference) {
105 Registry registry = RegistryUtil.getRegistry();
106
107 T displayContextFactory = registry.getService(serviceReference);
108
109 DisplayContextFactoryReference<T> displayContextFactoryReference =
110 new DisplayContextFactoryReference<>(
111 displayContextFactory, serviceReference);
112
113 _displayContextFactoryReferences.add(
114 displayContextFactoryReference);
115
116 _displayContextFactoryReferencesMap.put(
117 displayContextFactory, displayContextFactoryReference);
118
119 return displayContextFactory;
120 }
121
122 @Override
123 public void modifiedService(
124 ServiceReference<T> serviceReference, T displayContextFactory) {
125
126 DisplayContextFactoryReference<T> displayContextFactoryReference =
127 _displayContextFactoryReferencesMap.get(displayContextFactory);
128
129 removedService(
130 displayContextFactoryReference.getServiceReference(),
131 displayContextFactoryReference.getDisplayContextFactory());
132
133 addingService(serviceReference);
134 }
135
136 @Override
137 public void removedService(
138 ServiceReference<T> serviceReference, T displayContextFactory) {
139
140 DisplayContextFactoryReference<T> displayContextFactoryReference =
141 _displayContextFactoryReferencesMap.remove(
142 displayContextFactory);
143
144 _displayContextFactoryReferences.remove(
145 displayContextFactoryReference);
146 }
147
148 }
149
150 }