You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ro...@apache.org on 2017/09/05 22:01:15 UTC
svn commit: r1807424 [3/8] - in /aries/trunk/cdi: ./ cdi-extender/
cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/
cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/
cdi-extender/src/main/java/org/apache/aries/...
Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Constants.java Tue Sep 5 22:01:11 2017
@@ -28,22 +28,26 @@ public class Constants {
public static final Set<String> CDI_URIS = Sets.immutableHashSet(CDI10_URI);
public static final String ARRAY_ELEMENT = "array";
- public static final String BEAN_CLASS_ATTRIBUTE = "beanClass";
- public static final String BEAN_ELEMENT = "bean";
- public static final String BEANS_ELEMENT = "beans";
+ public static final String CARDINALITY_ATTRIBUTE = "cardinality";
public static final String CLASS_ATTRIBUTE = "class";
+ public static final String COMPONENT_ELEMENT = "component";
public static final String CONFIGURATION_ELEMENT = "configuration";
+ public static final String CONFIGURATION_PID_ATTRIBUTE = "configuration-pid";
+ public static final String CONFIGURATION_POLICY_ATTRIBUTE = "configuration-policy";
public static final String INTERFACE_ATTRIBUTE = "interface";
public static final String LIST_ELEMENT = "list";
public static final String NAME_ATTRIBUTE = "name";
- public static final String PID_ATTRIBUTE = "pid";
+ public static final String POLICY_ATTRIBUTE = "policy";
+ public static final String POLICY_OPTION_ATTRIBUTE = "policy-option";
public static final String PROPERTY_ELEMENT = "property";
public static final String PROVIDE_ELEMENT = "provide";
public static final String REFERENCE_ELEMENT = "reference";
- public static final String REQUIRED_ATTRIBUTE = "required";
- public static final String SERVICE_ELEMENT = "service";
+ public static final String SCOPE_ATTRIBUTE= "scope";
+ public static final String SERVICE_ATTRIBUTE = "service";
+ public static final String SERVICE_SCOPE_ATTRIBUTE = "service-scope";
public static final String SET_ELEMENT = "set";
public static final String TARGET_ATTRIBUTE = "target";
+ public static final String TYPE_ATTRIBUTE = "type";
public static final String VALUE_ATTRIBUTE = "value";
public static final String VALUE_ELEMENT = "value";
public static final String VALUE_TYPE_ATTRIBUTE = "value-type";
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Context.java Tue Sep 5 22:01:11 2017
@@ -12,12 +12,17 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.model;
-public interface Phase {
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
- public void close();
+public abstract class Context {
- public void open();
+ public abstract <T> T getService(ServiceReference<T> reference);
+
+ public abstract <T> ServiceObjects<T> getServiceObjects(ServiceReference<T> reference);
+
+ public abstract <T> boolean ungetService(ServiceReference<T> reference);
}
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/AbstractModel.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/AbstractModel.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/AbstractModel.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Model.java Tue Sep 5 22:01:11 2017
@@ -16,9 +16,9 @@ package org.apache.aries.cdi.container.i
import org.xml.sax.Attributes;
-public class AbstractModel {
+public class Model {
- boolean getBoolean(String uri, String localName, Attributes attributes, boolean defaultValue) {
+ public static boolean getBoolean(String uri, String localName, Attributes attributes, boolean defaultValue) {
String value = getValue(uri, localName, attributes);
if (value == null) {
@@ -28,7 +28,11 @@ public class AbstractModel {
return Boolean.parseBoolean(value);
}
- String getValue(String uri, String localName, Attributes attributes) {
+ public static String getValue(String uri, String localName, Attributes attributes) {
+ return getValue(uri, localName, attributes, "");
+ }
+
+ public static String getValue(String uri, String localName, Attributes attributes, String defaultValue) {
String value = attributes.getValue(uri, localName);
if (value == null) {
@@ -39,7 +43,29 @@ public class AbstractModel {
value = value.trim();
}
+ if (value == null) {
+ return defaultValue;
+ }
+
return value;
}
+ public static String[] getValues(String uri, String localName, Attributes attributes) {
+ return getValues(uri, localName, attributes, new String[0]);
+ }
+
+ public static String[] getValues(String uri, String localName, Attributes attributes, String[] defaultValue) {
+ String value = getValue(uri, localName, attributes, "");
+
+ if (value.length() == 0) {
+ return defaultValue;
+ }
+
+ return value.split("\\s+");
+ }
+
+ private Model() {
+ // TODO Auto-generated constructor stub
+ }
+
}
Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java?rev=1807424&r1=1807423&r2=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/OSGiBeansHandler.java Tue Sep 5 22:01:11 2017
@@ -15,9 +15,10 @@
package org.apache.aries.cdi.container.internal.model;
import static org.apache.aries.cdi.container.internal.model.Constants.ARRAY_ELEMENT;
-import static org.apache.aries.cdi.container.internal.model.Constants.BEAN_ELEMENT;
-import static org.apache.aries.cdi.container.internal.model.Constants.CDI_URIS;
import static org.apache.aries.cdi.container.internal.model.Constants.CLASS_ATTRIBUTE;
+import static org.apache.aries.cdi.container.internal.model.Constants.CDI10_URI;
+import static org.apache.aries.cdi.container.internal.model.Constants.CDI_URIS;
+import static org.apache.aries.cdi.container.internal.model.Constants.COMPONENT_ELEMENT;
import static org.apache.aries.cdi.container.internal.model.Constants.CONFIGURATION_ELEMENT;
import static org.apache.aries.cdi.container.internal.model.Constants.INTERFACE_ATTRIBUTE;
import static org.apache.aries.cdi.container.internal.model.Constants.LIST_ELEMENT;
@@ -25,30 +26,37 @@ import static org.apache.aries.cdi.conta
import static org.apache.aries.cdi.container.internal.model.Constants.PROPERTY_ELEMENT;
import static org.apache.aries.cdi.container.internal.model.Constants.PROVIDE_ELEMENT;
import static org.apache.aries.cdi.container.internal.model.Constants.REFERENCE_ELEMENT;
-import static org.apache.aries.cdi.container.internal.model.Constants.SERVICE_ELEMENT;
+import static org.apache.aries.cdi.container.internal.model.Constants.SERVICE_ATTRIBUTE;
import static org.apache.aries.cdi.container.internal.model.Constants.SET_ELEMENT;
+import static org.apache.aries.cdi.container.internal.model.Constants.TYPE_ATTRIBUTE;
import static org.apache.aries.cdi.container.internal.model.Constants.VALUE_ATTRIBUTE;
import static org.apache.aries.cdi.container.internal.model.Constants.VALUE_ELEMENT;
import static org.apache.aries.cdi.container.internal.model.Constants.VALUE_TYPE_ATTRIBUTE;
import java.net.URL;
-import java.util.ArrayList;
import java.util.Formatter;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.configuration.ConfigurationModel;
+import org.apache.aries.cdi.container.internal.reference.ReferenceModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class OSGiBeansHandler extends DefaultHandler {
- public OSGiBeansHandler(List<URL> beanDescriptorURLs) {
+ public OSGiBeansHandler(List<URL> beanDescriptorURLs, ClassLoader classLoader) {
_beanDescriptorURLs = beanDescriptorURLs;
+ _classLoader = classLoader;
}
public BeansModel createBeansModel() {
- return new BeansModel(
- _beanClasses, _configurationModels, _referenceModels, _serviceModels, _beanDescriptorURLs);
+ return new BeansModel(_components, _beanDescriptorURLs);
}
@Override
@@ -65,14 +73,31 @@ public class OSGiBeansHandler extends De
if (matches(ARRAY_ELEMENT, uri, localName) && (_propertyValue == null)) {
_collectionType = CollectionType.ARRAY;
}
- if (matches(BEAN_ELEMENT, uri, localName)) {
- _beanClass = attributes.getValue(CLASS_ATTRIBUTE).trim();
- if (!_beanClasses.contains(_beanClass)) {
- _beanClasses.add(_beanClass);
+ if (matches(COMPONENT_ELEMENT, uri, localName)) {
+ try {
+ Class<?> clazz = _classLoader.loadClass(
+ Model.getValue(CDI10_URI, CLASS_ATTRIBUTE, attributes));
+
+ _componentModel = new ComponentModel.Builder(clazz).attributes(attributes);
+ }
+ catch (ClassNotFoundException cnfe) {
+ if (_log.isErrorEnabled()) {
+ _log.error("CDIe - {}", cnfe.getMessage(), cnfe);
+ }
}
}
if (matches(CONFIGURATION_ELEMENT, uri, localName)) {
- _configurationModel = new ConfigurationModel(attributes);
+ try {
+ Class<?> clazz = _classLoader.loadClass(
+ Model.getValue(CDI10_URI, TYPE_ATTRIBUTE, attributes));
+
+ _componentModel.configuration(new ConfigurationModel.Builder(clazz).attributes(attributes).build());
+ }
+ catch (ClassNotFoundException cnfe) {
+ if (_log.isErrorEnabled()) {
+ _log.error("CDIe - {}", cnfe.getMessage(), cnfe);
+ }
+ }
}
if (matches(LIST_ELEMENT, uri, localName) && (_propertyValue == null)) {
_collectionType = CollectionType.LIST;
@@ -93,12 +118,20 @@ public class OSGiBeansHandler extends De
}
if (matches(PROVIDE_ELEMENT, uri, localName)) {
String value = attributes.getValue(INTERFACE_ATTRIBUTE).trim();
- _serviceModel.addProvide(value); }
- if (matches(REFERENCE_ELEMENT, uri, localName)) {
- _referenceModel = new ReferenceModel(attributes);
+ _componentModel.provide(value);
}
- if (matches(SERVICE_ELEMENT, uri, localName)) {
- _serviceModel = new ServiceModel(_beanClass);
+ if (matches(REFERENCE_ELEMENT, uri, localName)) {
+ try {
+ Class<?> clazz = _classLoader.loadClass(
+ Model.getValue(CDI10_URI, SERVICE_ATTRIBUTE, attributes));
+
+ _referenceModel = new ReferenceModel.Builder(attributes).service(clazz).build();
+ }
+ catch (ClassNotFoundException cnfe) {
+ if (_log.isErrorEnabled()) {
+ _log.error("CDIe - {}", cnfe.getMessage(), cnfe);
+ }
+ }
}
if (matches(SET_ELEMENT, uri, localName) && (_propertyValue == null)) {
_collectionType = CollectionType.SET;
@@ -113,9 +146,10 @@ public class OSGiBeansHandler extends De
if (matches(ARRAY_ELEMENT, uri, localName)) {
_collectionType = null;
}
- if (matches(CONFIGURATION_ELEMENT, uri, localName)) {
- _configurationModels.add(_configurationModel);
- _configurationModel = null;
+ if (matches(COMPONENT_ELEMENT, uri, localName)) {
+ ComponentModel componentModel = _componentModel.build();
+ _components.put(componentModel.getBeanClass().getName(), componentModel);
+ _componentModel = null;
}
if (matches(LIST_ELEMENT, uri, localName)) {
_collectionType = null;
@@ -127,7 +161,7 @@ public class OSGiBeansHandler extends De
if (_propertyValue != null) {
try (Formatter f = new Formatter()) {
f.format("%s:%s=%s", _propertyName, _propertyType, _propertyValue);
- _serviceModel.addProperty(f.toString());
+ _componentModel.property(f.toString());
}
}
_propertySB = null;
@@ -136,14 +170,9 @@ public class OSGiBeansHandler extends De
_propertyValue = null;
}
if (matches(REFERENCE_ELEMENT, uri, localName)) {
- _referenceModels.add(_referenceModel);
+ _componentModel.reference(_referenceModel);
_referenceModel = null;
}
- if (matches(SERVICE_ELEMENT, uri, localName)) {
- _serviceModels.add(_serviceModel);
- _serviceModel = null;
- _beanClass = null;
- }
if (matches(SET_ELEMENT, uri, localName)) {
_collectionType = null;
}
@@ -167,7 +196,7 @@ public class OSGiBeansHandler extends De
sb.append("=");
sb.append(_propertySB.toString().trim());
- _serviceModel.addProperty(sb.toString());
+ _componentModel.property(sb.toString());
_propertySB = null;
}
}
@@ -183,19 +212,18 @@ public class OSGiBeansHandler extends De
ARRAY, LIST, SET
}
- private String _beanClass;
- private final List<String> _beanClasses = new ArrayList<String>();
+ private final static Logger _log = LoggerFactory.getLogger(
+ OSGiBeansHandler.class);
+
+ private final ClassLoader _classLoader;
+ private final Map<String, ComponentModel> _components = new HashMap<>();
private final List<URL> _beanDescriptorURLs;
- private ConfigurationModel _configurationModel;
- private final List<ConfigurationModel> _configurationModels = new ArrayList<>();
private String _propertyName;
private StringBuilder _propertySB;
private String _propertyType;
private String _propertyValue;
private CollectionType _collectionType;
private ReferenceModel _referenceModel;
- private final List<ReferenceModel> _referenceModels = new ArrayList<>();
- private ServiceModel _serviceModel;
- private final List<ServiceModel> _serviceModels = new ArrayList<>();
+ private ComponentModel.Builder _componentModel;
}
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ObserverMethodAnnotated.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,58 @@
+package org.apache.aries.cdi.container.internal.model;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.apache.aries.cdi.container.internal.util.Sets;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+
+public class ObserverMethodAnnotated implements Annotated {
+
+ public ObserverMethodAnnotated(ObserverMethod<ServiceEvent<?>> observerMethod) {
+ _observerMethod = observerMethod;
+ _qualifiers = _observerMethod.getObservedQualifiers();
+ }
+
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+ for (Annotation annotation : _qualifiers) {
+ if (annotationType.isInstance(annotation)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Set<Type> getTypeClosure() {
+ return Sets.immutableHashSet(getBaseType());
+ }
+
+ @Override
+ public Type getBaseType() {
+ return _observerMethod.getObservedType();
+ }
+
+ @Override
+ public Set<Annotation> getAnnotations() {
+ return _qualifiers;
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ for (Annotation annotation : _qualifiers) {
+ if (annotationType.isInstance(annotation)) {
+ return (T)annotation;
+ }
+ }
+ return null;
+ }
+
+ private final ObserverMethod<ServiceEvent<?>> _observerMethod;
+ private final Set<Annotation> _qualifiers;
+
+}
\ No newline at end of file
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Registrator.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,69 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.model;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class Registrator<T> {
+
+ public abstract void registerService(String[] classNames, T service, Dictionary<String, ?> properties);
+
+ public void registerService(T service, Object... keyValues) {
+ if ((keyValues.length % 2) != 0) throw new IllegalArgumentException("keyValues must be [String, Object]+");
+
+ Dictionary<String, Object> properties = new Hashtable<>();
+
+ if (keyValues.length > 0) {
+ for (int i = 0; i < keyValues.length; i += 2) {
+ properties.put(String.valueOf(keyValues[i]), keyValues[i + 1]);
+ }
+ }
+
+ registerService(null, service, properties);
+ }
+
+ public int size() {
+ return registrations.size();
+ }
+
+ public void close() {
+ registrations.removeIf(
+ r -> {
+ try {
+ r.unregister();
+ }
+ catch (IllegalStateException ise) {
+ if (_log.isTraceEnabled()) {
+ _log.trace("Service already unregistered {}", r);
+ }
+ }
+
+ return true;
+ }
+ );
+ }
+
+ private static final Logger _log = LoggerFactory.getLogger(Registrator.class);
+
+ protected final List<ServiceRegistration<?>> registrations = new CopyOnWriteArrayList<>();
+
+}
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceEventImpl.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,55 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.model;
+
+import org.osgi.service.cdi.annotations.ServiceEvent;
+
+public class ServiceEventImpl<T> implements ServiceEvent<T> {
+
+ public static enum Event { ADDING, MODIFIED, REMOVED }
+
+ private final T _t;
+ private final ServiceEventImpl.Event _event;
+
+ public ServiceEventImpl(T t, ServiceEventImpl.Event event) {
+ _t = t;
+ _event = event;
+ }
+
+ @Override
+ public ServiceEvent<T> adding(Consumer<T> consumer) {
+ if (_event == Event.ADDING) {
+ consumer.accept(_t);
+ };
+ return this;
+ }
+
+ @Override
+ public ServiceEvent<T> modified(Consumer<T> consumer) {
+ if (_event == Event.MODIFIED) {
+ consumer.accept(_t);
+ }
+ return this;
+ }
+
+ @Override
+ public ServiceEvent<T> removed(Consumer<T> consumer) {
+ if (_event == Event.REMOVED) {
+ consumer.accept(_t);
+ }
+ return this;
+ }
+
+}
\ No newline at end of file
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceModel.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceModel.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/ServiceModel.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/model/Tracker.java Tue Sep 5 22:01:11 2017
@@ -14,36 +14,34 @@
package org.apache.aries.cdi.container.internal.model;
-import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
-public class ServiceModel {
+import org.apache.aries.cdi.container.internal.reference.ReferenceCallback;
+import org.osgi.util.tracker.ServiceTracker;
- public ServiceModel(String beanClass) {
- _beanClass = beanClass;
- }
+public abstract class Tracker {
- public void addProvide(String className) {
- _provides.add(className);
- }
+ public abstract <T> void track(String targetFilter, ReferenceCallback callback);
- public void addProperty(String property) {
- _properties.add(property);
+ public int size() {
+ return trackers.size();
}
- public String getBeanClass() {
- return _beanClass;
- }
+ public void close() {
+ trackers.removeIf(
+ t -> {
+ t.close();
- public String[] getProperties() {
- return _properties.toArray(new String[0]);
+ return true;
+ }
+ );
}
- public List<String> getProvides() {
- return _provides;
+ public void open() {
+ trackers.stream().forEach(t -> t.open());
}
- private final String _beanClass;
- private List<String> _properties = new ArrayList<>();
- private List<String> _provides = new ArrayList<>();
+ protected final List<ServiceTracker<Object, ?>> trackers = new CopyOnWriteArrayList<>();
+
}
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase.java Tue Sep 5 22:01:11 2017
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.phase;
public interface Phase {
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Configuration.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,245 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.configuration.ConfigurationCallback;
+import org.apache.aries.cdi.container.internal.configuration.ConfigurationManagedService;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.osgi.framework.Constants;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.annotations.Configuration;
+import org.osgi.service.cdi.annotations.ConfigurationPolicy;
+
+public class Phase_Configuration implements Phase {
+
+ public Phase_Configuration(
+ ContainerState containerState,
+ Collection<Metadata<Extension>> extensions) {
+
+ _containerState = containerState;
+ _extensions = extensions;
+
+ _componentModels = _containerState.beansModel().getComponentModels();
+ }
+
+ @Override
+ public void close() {
+ _lock.lock();
+
+ try {
+ if (_nextPhase != null) {
+ _nextPhase.close();
+
+ _nextPhase = null;
+ }
+
+ _containerState.managedServiceRegistrator().close();
+
+ _containerState.configurationCallbacks().clear();
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ @Override
+
+ public void open() {
+ _lock.lock();
+
+ try {
+ _containerState.fire(CdiEvent.Type.WAITING_FOR_CONFIGURATIONS);
+
+ openConfigurations();
+
+ callbacksInit();
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ boolean callbacksExist() {
+ return _containerState.configurationCallbacks().values().stream().flatMap(
+ entry -> entry.values().stream()
+ ).findFirst().isPresent();
+ }
+
+ void callbacksInit() {
+ _containerState.configurationCallbacks().values().stream().flatMap(
+ valueMap -> valueMap.values().stream()
+ ).forEach(
+ cc -> cc.init()
+ );
+ }
+
+ boolean callbacksResolved() {
+ return !_containerState.configurationCallbacks().values().stream().flatMap(
+ valueMap -> valueMap.values().stream()
+ ).filter(
+ c -> !c.resolved()
+ ).findFirst().isPresent();
+ }
+
+ void openConfigurations() {
+ Consumer<ConfigurationCallback> onAdd = cc -> {
+ _lock.lock();
+ try {
+ if (callbacksResolved()) {
+ if ((_nextPhase != null)) {
+ _nextPhase.close();
+ _nextPhase = null;
+ }
+
+ if ((_nextPhase == null)) {
+ _nextPhase = new Phase_Reference(_containerState, _extensions);
+ _nextPhase.open();
+ }
+ }
+ }
+ finally {
+ _lock.unlock();
+ }
+ },
+ onUpdate = cc -> {
+ _lock.lock();
+ try {
+ _nextPhase.close();
+ _nextPhase = new Phase_Reference(_containerState, _extensions);
+ _nextPhase.open();
+ }
+ finally {
+ _lock.unlock();
+ }
+ },
+ onRemove = cc -> {
+ _lock.lock();
+ try {
+ if (_nextPhase != null) {
+ _nextPhase.close();
+ }
+ if (!callbacksResolved()) {
+ _nextPhase = null;
+ _containerState.fire(CdiEvent.Type.WAITING_FOR_CONFIGURATIONS);
+ }
+ else {
+ _nextPhase = new Phase_Reference(_containerState, _extensions);
+ _nextPhase.open();
+ }
+ }
+ finally {
+ _lock.unlock();
+ }
+ };
+
+ _componentModels.stream().forEach(
+ componentModel -> openConfigurations(componentModel, onAdd, onUpdate, onRemove)
+ );
+ }
+
+ void openConfigurations(
+ ComponentModel componentModel,
+ Consumer<ConfigurationCallback> onAdd,
+ Consumer<ConfigurationCallback> onUpdate,
+ Consumer<ConfigurationCallback> onRemove) {
+
+ _lock.lock();
+
+ try {
+ componentModel.getConfigurations().stream().forEach(
+ configurationModel -> Arrays.stream(configurationModel.getPid()).distinct().forEach(
+ pid -> {
+ if (Configuration.NAME.equals(pid)) {
+ pid = componentModel.getName();
+ }
+
+ registerConfigurationCallback(
+ componentModel, pid, onAdd, onUpdate, onRemove, configurationModel.getConfigurationPolicy());
+ }
+ )
+ );
+
+ if (!_containerState.configurationCallbacks().containsKey(componentModel)) {
+
+ // Add a default callback for every Component using it's name as pid.
+
+ registerConfigurationCallback(
+ componentModel, componentModel.getName(), onAdd, onUpdate, onRemove, ConfigurationPolicy.OPTIONAL);
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ void registerConfigurationCallback(
+ ComponentModel componentModel,
+ String pid,
+ Consumer<ConfigurationCallback> onAdd,
+ Consumer<ConfigurationCallback> onUpdate,
+ Consumer<ConfigurationCallback> onRemove,
+ ConfigurationPolicy policy) {
+
+ Map<String, ConfigurationCallback> valueMap = _containerState.configurationCallbacks().computeIfAbsent(
+ componentModel, k -> new LinkedHashMap<>());
+
+ ConfigurationCallback callback = valueMap.get(pid);
+
+ if ((callback == null) ||
+ (policy == ConfigurationPolicy.REQUIRE)) {
+
+ callback = new ConfigurationCallback.Builder().onAdd(
+ onAdd
+ ).onRemove(
+ onRemove
+ ).onUpdate(
+ onUpdate
+ ).pid(
+ pid
+ ).policy(
+ policy
+ ).build();
+
+ valueMap.put(pid, callback);
+ }
+
+ _containerState.managedServiceRegistrator().registerService(
+ new ConfigurationManagedService(pid, callback),
+ Constants.SERVICE_PID, pid, "component.id", _counter.incrementAndGet());
+ }
+
+ private final Collection<ComponentModel> _componentModels;
+ private final ContainerState _containerState;
+ private final AtomicInteger _counter = new AtomicInteger();
+ private final Collection<Metadata<Extension>> _extensions;
+ private final Lock _lock = new ReentrantLock();
+ private volatile Phase _nextPhase;
+}
\ No newline at end of file
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_Extension.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_Extension.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_Extension.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Extension.java Tue Sep 5 22:01:11 2017
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.phase;
import java.util.Comparator;
import java.util.List;
@@ -22,9 +22,14 @@ import java.util.concurrent.CopyOnWriteA
import javax.enterprise.inject.spi.Extension;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.extension.ExtensionDependency;
+import org.apache.aries.cdi.container.internal.extension.ExtensionMetadata;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
@@ -37,20 +42,20 @@ import org.slf4j.LoggerFactory;
public class Phase_Extension implements Phase {
- public Phase_Extension(CdiContainerState cdiContainerState) {
- _cdiContainerState = cdiContainerState;
- _bundleContext = _cdiContainerState.getBundle().getBundleContext();
- _extensionDependencies = findExtensionDependencies(
- _cdiContainerState.getBundle().adapt(BundleWiring.class));
+ public Phase_Extension(ContainerState containerState) {
+ _containerState = containerState;
+ _bundleContext = _containerState.bundle().getBundleContext();
+
+ BundleWiring bundleWiring = _containerState.bundle().adapt(BundleWiring.class);
+
+ _extensionDependencies = findExtensionDependencies(bundleWiring);
_extensions = new ConcurrentSkipListMap<>(Comparator.reverseOrder());
- _cdiContainerState.setExtensionDependencies(_extensionDependencies);
+ _containerState.setExtensionDependencies(_extensionDependencies);
}
@Override
public void close() {
- _cdiContainerState.fire(CdiEvent.Type.DESTROYING);
-
if (_extensionTracker != null) {
_extensionTracker.close();
@@ -61,32 +66,47 @@ public class Phase_Extension implements
_nextPhase = null;
}
-
- _cdiContainerState.fire(CdiEvent.Type.DESTROYED);
-
- _cdiContainerState.close();
}
@Override
public void open() {
- _cdiContainerState.fire(CdiEvent.Type.CREATING);
-
if (!_extensionDependencies.isEmpty()) {
- Filter filter = FilterBuilder.createExtensionFilter(_extensionDependencies);
+ _containerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS);
- _cdiContainerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS, filter.toString());
+ Filter filter = createExtensionFilter(_extensionDependencies);
_extensionTracker = new ServiceTracker<>(_bundleContext, filter, new ExtensionPhaseCustomizer());
_extensionTracker.open();
}
else {
- _nextPhase = new Phase_Configuration(_cdiContainerState, _extensions);
+ _nextPhase = new Phase_Configuration(_containerState, _extensions.values());
_nextPhase.open();
}
}
+ Filter createExtensionFilter(List<ExtensionDependency> extentionDependencies) {
+ try {
+ StringBuilder sb = new StringBuilder("(&(objectClass=" + Extension.class.getName() + ")");
+
+ if (extentionDependencies.size() > 1) sb.append("(|");
+
+ for (ExtensionDependency dependency : extentionDependencies) {
+ sb.append(dependency.toString());
+ }
+
+ if (extentionDependencies.size() > 1) sb.append(")");
+
+ sb.append(")");
+
+ return FrameworkUtil.createFilter(sb.toString());
+ }
+ catch (InvalidSyntaxException ise) {
+ throw new RuntimeException(ise);
+ }
+ }
+
List<ExtensionDependency> findExtensionDependencies(BundleWiring bundleWiring) {
List<ExtensionDependency> extensionDependencies = new CopyOnWriteArrayList<>();
List<BundleWire> requiredWires = bundleWiring.getRequiredWires(CdiConstants.CDI_EXTENSION_NAMESPACE);
@@ -110,9 +130,9 @@ public class Phase_Extension implements
private static final Logger _log = LoggerFactory.getLogger(Phase_Extension.class);
private final BundleContext _bundleContext;
- private final CdiContainerState _cdiContainerState;
- private final Map<ServiceReference<Extension>, Metadata<Extension>> _extensions;
+ private final ContainerState _containerState;
private final List<ExtensionDependency> _extensionDependencies;
+ private final Map<ServiceReference<Extension>, Metadata<Extension>> _extensions;
private Phase _nextPhase;
private ServiceTracker<Extension, ExtensionDependency> _extensionTracker;
@@ -137,7 +157,7 @@ public class Phase_Extension implements
}
if ((trackedDependency != null) && _extensionDependencies.isEmpty()) {
- _nextPhase = new Phase_Configuration(_cdiContainerState, _extensions);
+ _nextPhase = new Phase_Configuration(_containerState, _extensions.values());
_nextPhase.open();
}
@@ -154,13 +174,8 @@ public class Phase_Extension implements
@Override
public void removedService(ServiceReference<Extension> reference, ExtensionDependency extentionDependency) {
- if (_extensionDependencies.isEmpty()) {
- _nextPhase.close();
-
- _nextPhase = null;
+ _extensionDependencies.add(extentionDependency);
- _cdiContainerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS);
- }
_extensions.remove(reference);
try {
@@ -172,7 +187,13 @@ public class Phase_Extension implements
}
}
- _extensionDependencies.add(extentionDependency);
+ if (!_extensionDependencies.isEmpty()) {
+ _nextPhase.close();
+
+ _nextPhase = null;
+
+ _containerState.fire(CdiEvent.Type.WAITING_FOR_EXTENSIONS);
+ }
}
}
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Init.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,89 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.aries.cdi.container.internal.container.ContainerDiscovery;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.model.BeansModel;
+import org.apache.aries.cdi.container.internal.model.BeansModelBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_Init implements Phase {
+
+ public Phase_Init(Bundle bundle, ContainerState containerState) {
+ _containerState = containerState;
+
+ BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
+
+ BeansModel beansModel = new BeansModelBuilder(_containerState.classLoader(), bundleWiring).build();
+
+ _containerState.setBeansModel(beansModel);
+ }
+
+ @Override
+ public void close() {
+ _lock.lock();
+
+ try {
+ _extensionPhase.close();
+
+ _extensionPhase = null;
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ @Override
+ public void open() {
+ _lock.lock();
+
+ try {
+ if (_log.isDebugEnabled()) {
+ _log.debug("CDIe - Starting discovery phase on {}", _containerState);
+ }
+
+ ContainerDiscovery.discover(_containerState);
+
+ if (_log.isDebugEnabled()) {
+ _log.debug("CDIe - Finished discovery phase on {}", _containerState);
+ }
+
+ if (_log.isDebugEnabled()) {
+ _log.debug("CDIe - Begin extension phase on {}", _containerState);
+ }
+
+ _extensionPhase = new Phase_Extension(_containerState);
+
+ _extensionPhase.open();
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ private static final Logger _log = LoggerFactory.getLogger(Phase_Init.class);
+
+ private final ContainerState _containerState;
+ private volatile Phase _extensionPhase;
+ private final Lock _lock = new ReentrantLock();
+
+}
\ No newline at end of file
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Publish.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,103 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import java.util.Collection;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.apache.aries.cdi.container.internal.container.ContainerBootstrap;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.jboss.weld.bootstrap.WeldBootstrap;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.jboss.weld.manager.BeanManagerImpl;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.annotations.ServiceScope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_Publish implements Phase {
+
+ public Phase_Publish(
+ ContainerState containerState,
+ Collection<Metadata<Extension>> extensions) {
+
+ _containerState = containerState;
+ _extensions = extensions;
+ }
+
+ @Override
+ public void close() {
+ _containerState.serviceRegistrator().close();
+ _containerState.beanManagerRegistrator().close();
+ _containerState.serviceComponents().clear();
+ _cb.shutdown();
+ }
+
+ @Override
+ public void open() {
+ _containerState.fire(CdiEvent.Type.SATISFIED);
+
+ try {
+ _cb = new ContainerBootstrap(_containerState, _extensions);
+
+ BeanManagerImpl beanManagerImpl = _cb.getBeanManagerImpl();
+ WeldBootstrap bootstrap = _cb.getBootstrap();
+
+ bootstrap.validateBeans();
+ bootstrap.endInitialization();
+
+ _containerState.referenceCallbacks().values().stream().flatMap(
+ map -> map.values().stream()
+ ).forEach(
+ callback -> callback.flush()
+ );
+
+ processServices(beanManagerImpl);
+
+ _containerState.beanManagerRegistrator().registerService(beanManagerImpl);
+
+ _containerState.fire(CdiEvent.Type.CREATED);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void processServices(BeanManagerImpl beanManagerImpl) {
+ _containerState.serviceComponents().values().stream().filter(
+ serviceDeclaration ->
+ serviceDeclaration.getScope() == ServiceScope.BUNDLE ||
+ serviceDeclaration.getScope() == ServiceScope.PROTOTYPE ||
+ serviceDeclaration.getScope() == ServiceScope.SINGLETON
+ ).forEach(
+ s -> {
+ if (_log.isDebugEnabled()) {
+ _log.debug("CDIe - Publishing component {} as '{}' service.", s.getName(), s.getScope());
+ }
+
+ _containerState.serviceRegistrator().registerService(
+ s.getClassNames(), s.getServiceInstance(), s.getServiceProperties());
+ }
+ );
+ }
+
+ private static final Logger _log = LoggerFactory.getLogger(Phase_Publish.class);
+
+ private volatile ContainerBootstrap _cb;
+ private final ContainerState _containerState;
+ private final Collection<Metadata<Extension>> _extensions;
+
+}
\ No newline at end of file
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/phase/Phase_Reference.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,193 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.reference.ReferenceCallback;
+import org.apache.aries.cdi.container.internal.reference.ReferenceModel;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_Reference implements Phase {
+
+ public Phase_Reference(
+ ContainerState containerState,
+ Collection<Metadata<Extension>> extensions) {
+
+ _containerState = containerState;
+ _extensions = extensions;
+
+ _componentModels = _containerState.beansModel().getComponentModels();
+ }
+
+ @Override
+ public void close() {
+ _lock.lock();
+
+ try {
+ if (_nextPhase != null) {
+ _nextPhase.close();
+
+ _nextPhase = null;
+ }
+
+ _containerState.tracker().close();
+
+ _containerState.referenceCallbacks().clear();
+ _containerState.referenceObservers().clear();
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ @Override
+ public void open() {
+ _lock.lock();
+
+ try {
+ _containerState.fire(CdiEvent.Type.WAITING_FOR_SERVICES);
+
+ openReferences();
+
+ _containerState.tracker().open();
+
+ if (referencesResolved()) {
+ if (_log.isDebugEnabled()) {
+ _log.debug("CDIe - There are no service dependencies. Moving on!");
+ }
+
+ _nextPhase = new Phase_Publish(_containerState, _extensions);
+
+ _nextPhase.open();
+ }
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ void openReferences() {
+ Consumer<ReferenceCallback> onAdd = r -> {
+ if ((_nextPhase == null) && referencesResolved()) {
+ _nextPhase = new Phase_Publish(_containerState, _extensions);
+ _nextPhase.open();
+ }
+ },
+ onUpdate = r -> {
+ // TODO we may need to handle static greedy references by hard reset of _nextPhase
+ },
+ onRemove = r -> {
+ if ((_nextPhase != null) && !referencesResolved()) {
+ _nextPhase.close();
+ _nextPhase = null;
+ _containerState.fire(CdiEvent.Type.WAITING_FOR_SERVICES);
+ }
+ };
+
+ _componentModels.stream().forEach(
+ componentModel -> openReferences(componentModel, onAdd, onUpdate, onRemove)
+ );
+ }
+
+ private void openReferences(
+ ComponentModel componentModel,
+ Consumer<ReferenceCallback> onAdd,
+ Consumer<ReferenceCallback> onUpdate,
+ Consumer<ReferenceCallback> onRemove) {
+
+ _lock.lock();
+
+ try {
+ componentModel.getReferences().stream().forEach(
+ referenceModel -> {
+ Map<String, ReferenceCallback> map = _containerState.referenceCallbacks().computeIfAbsent(
+ componentModel, k -> new LinkedHashMap<>());
+
+ ReferenceCallback callback = new ReferenceCallback.Builder(
+ componentModel, _containerState, _containerState.context()
+ ).cardinality(
+ referenceModel.getCardinality()
+ ).collectionType(
+ referenceModel.getCollectionType()
+ ).name(
+ referenceModel.getName()
+ ).onAdd(
+ onAdd
+ ).onRemove(
+ onRemove
+ ).onUpdate(
+ onUpdate
+ ).build();
+
+ map.put(referenceModel.getName(), callback);
+
+ try {
+ String targetFilter = ReferenceModel.buildFilter(
+ referenceModel.getServiceClass(), referenceModel.getTarget(), referenceModel.getScope(), referenceModel.getQualifiers());
+
+ _containerState.tracker().track(targetFilter, callback);
+ }
+ catch (InvalidSyntaxException ise) {
+ if (_log.isErrorEnabled()) {
+ _log.error("CDIe - {}", ise.getMessage(), ise);
+ }
+ }
+ }
+ );
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ boolean referencesExist() {
+ return _containerState.referenceCallbacks().values().stream().flatMap(
+ entry -> entry.values().stream()
+ ).findFirst().isPresent();
+ }
+
+ boolean referencesResolved() {
+ return !_containerState.referenceCallbacks().values().stream().flatMap(
+ valueMap -> valueMap.values().stream()
+ ).filter(
+ c -> !c.resolved()
+ ).findFirst().isPresent();
+ }
+
+ private static final Logger _log = LoggerFactory.getLogger(Phase_Reference.class);
+
+ private final Collection<ComponentModel> _componentModels;
+ private final ContainerState _containerState;
+ private final Collection<Metadata<Extension>> _extensions;
+ private final Lock _lock = new ReentrantLock(true);
+ private volatile Phase _nextPhase;
+
+}
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/Multiplicity.java Tue Sep 5 22:01:11 2017
@@ -12,8 +12,10 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.container.internal.container;
+package org.apache.aries.cdi.container.internal.reference;
-public enum BindType {
- SERVICE, SERVICE_PROPERTIES, SERVICE_REFERENCE
-}
\ No newline at end of file
+public enum Multiplicity {
+
+ MULTIPLE, UNARY
+
+}
Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java (from r1806482, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ConfigurationBean.java)
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ConfigurationBean.java&r1=1806482&r2=1807424&rev=1807424&view=diff
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ConfigurationBean.java (original)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceBean.java Tue Sep 5 22:01:11 2017
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.container.internal.bean;
+package org.apache.aries.cdi.container.internal.reference;
import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
-import java.util.AbstractMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -26,52 +25,63 @@ import java.util.Set;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Named;
-import org.apache.aries.cdi.container.internal.container.ConfigurationDependency;
-import org.apache.aries.cdi.container.internal.literal.AnyLiteral;
-import org.apache.aries.cdi.container.internal.literal.DefaultLiteral;
-import org.apache.aries.cdi.container.internal.util.Conversions;
-import org.apache.aries.cdi.container.internal.util.Sets;
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
import org.jboss.weld.injection.CurrentInjectionPoint;
import org.jboss.weld.injection.EmptyInjectionPoint;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.util.Decorators;
+import org.osgi.service.cdi.annotations.ReferenceCardinality;
-public class ConfigurationBean implements Bean<Object> {
+public class ReferenceBean implements Bean<Object> {
- public ConfigurationBean(
- ConfigurationDependency configurationDependency, BeanManagerImpl beanManagerImpl, Type injectionPointType,
- Set<Annotation> qualifiers) {
-
- _configurationDependency = configurationDependency;
+ public ReferenceBean(
+ ContainerState containerState,
+ ReferenceModel referenceModel,
+ ComponentModel componentModel,
+ Annotated annotated,
+ Set<Annotation> qualifiers,
+ BeanManagerImpl beanManagerImpl) {
+
+ _containerState = containerState;
+ _referenceModel = referenceModel;
+ _componentModel = componentModel;
+ _qualifiers = qualifiers;
_beanManagerImpl = beanManagerImpl;
- _typesForMatchingBeansToInjectionPoints = Sets.immutableHashSet(injectionPointType, Object.class);
- _currentInjectionPoint = _beanManagerImpl.getServices().get(CurrentInjectionPoint.class);
- _qualifiers = Sets.hashSet(qualifiers, DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE);
-
- for (Annotation qualifier : _qualifiers) {
- if (qualifier.annotationType().equals(Named.class)) {
- _name = ((Named)qualifier).value();
- }
- }
+
+ Named named = annotated.getAnnotation(Named.class);
+
+ _name = named != null ? named.value() : null;
}
@Override
public Object create(CreationalContext<Object> creationalContext) {
- return create0(creationalContext);
+ Object instance = _getInjectedInstance();
+ InjectionPoint ip = _getInjectionPoint();
+ if (ip == null) {
+ return instance;
+ }
+ List<Decorator<?>> decorators = _getDecorators(ip);
+ if (decorators.isEmpty()) {
+ return instance;
+ }
+ return Decorators.getOuterDelegate(
+ cast(this), instance, creationalContext, cast(getBeanClass()), ip, _beanManagerImpl, decorators);
}
@Override
- public void destroy(Object arg0, CreationalContext<Object> arg1) {
+ public void destroy(Object instance, CreationalContext<Object> creationalContext) {
}
@Override
public Class<?> getBeanClass() {
- return _configurationDependency.getBeanClass();
+ return _referenceModel.getBeanClass();
}
@Override
@@ -81,7 +91,7 @@ public class ConfigurationBean implement
@Override
public String getName() {
- return _name;
+ return _name; //_referenceModel.getName();
}
@Override
@@ -101,7 +111,7 @@ public class ConfigurationBean implement
@Override
public Set<Type> getTypes() {
- return _typesForMatchingBeansToInjectionPoints;
+ return _referenceModel.getTypes();
}
@Override
@@ -111,51 +121,59 @@ public class ConfigurationBean implement
@Override
public boolean isNullable() {
- return false;
+ return _referenceModel.getCardinality() == ReferenceCardinality.OPTIONAL ? true : false;
}
@Override
public String toString() {
- return "ConfigurationBean[" + _currentInjectionPoint + "]";
+ return "ReferenceBean[" + _referenceModel + "]";
}
- protected <T> T create0(CreationalContext<T> creationalContext) {
- Map<String, Object> map = new AbstractMap<String, Object>() {
+ private List<Decorator<?>> _getDecorators(InjectionPoint ip) {
+ return _beanManagerImpl.resolveDecorators(Collections.singleton(ip.getType()), getQualifiers());
+ }
- @Override
- public Set<java.util.Map.Entry<String, Object>> entrySet() {
- return _configurationDependency.getConfiguration().entrySet();
- }
+ private Object _getInjectedInstance() {
+ Object instance = null;
- };
+ Map<String, ReferenceCallback> map = _containerState.referenceCallbacks().get(_componentModel);
- T instance = cast(Conversions.c().convert(map).to(_configurationDependency.getBeanClass()));
- InjectionPoint ip = getInjectionPoint(_currentInjectionPoint);
- if (ip == null) {
- return instance;
- }
- List<Decorator<?>> decorators = getDecorators(ip);
- if (decorators.isEmpty()) {
- return instance;
+ ReferenceCallback referenceCallback = map.get(_referenceModel.getName());
+
+ Type injectionPointType = _referenceModel.getInjectionPointType();
+
+ switch (_referenceModel.getCollectionType()) {
+ case PROPERTIES:
+ instance = referenceCallback.tracked().values().iterator().next();
+ break;
+ case REFERENCE:
+ instance = referenceCallback.tracked().values().iterator().next();
+ break;
+ case SERVICE:
+ instance = referenceCallback.tracked().values().iterator().next();
+ break;
+ case SERVICEOBJECTS:
+ instance = referenceCallback.tracked().values().iterator().next();
+ break;
+ case TUPLE:
+ instance = referenceCallback.tracked().values().iterator().next();
+ break;
}
- return Decorators.getOuterDelegate(
- cast(this), instance, creationalContext, cast(getBeanClass()), ip, _beanManagerImpl, decorators);
- }
- protected List<Decorator<?>> getDecorators(InjectionPoint ip) {
- return _beanManagerImpl.resolveDecorators(Collections.singleton(ip.getType()), getQualifiers());
+ return instance;
}
- protected InjectionPoint getInjectionPoint(CurrentInjectionPoint currentInjectionPoint) {
+ private InjectionPoint _getInjectionPoint() {
+ CurrentInjectionPoint currentInjectionPoint = _beanManagerImpl.getServices().get(CurrentInjectionPoint.class);
InjectionPoint ip = currentInjectionPoint.peek();
return EmptyInjectionPoint.INSTANCE.equals(ip) ? null : ip;
}
private final BeanManagerImpl _beanManagerImpl;
- private final ConfigurationDependency _configurationDependency;
- private final CurrentInjectionPoint _currentInjectionPoint;
- private String _name;
+ private final ComponentModel _componentModel;
+ private final ContainerState _containerState;
+ private final String _name;
private final Set<Annotation> _qualifiers;
- private final Set<Type> _typesForMatchingBeansToInjectionPoints;
+ private final ReferenceModel _referenceModel;
-}
+}
\ No newline at end of file
Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java?rev=1807424&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/reference/ReferenceCallback.java Tue Sep 5 22:01:11 2017
@@ -0,0 +1,408 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.reference;
+
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import javax.enterprise.inject.spi.ObserverMethod;
+
+import org.apache.aries.cdi.container.internal.component.ComponentModel;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.model.CollectionType;
+import org.apache.aries.cdi.container.internal.model.Context;
+import org.apache.aries.cdi.container.internal.model.ServiceEventImpl;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.annotations.ReferenceCardinality;
+import org.osgi.service.cdi.annotations.ServiceEvent;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ReferenceCallback implements ServiceTrackerCustomizer<Object, Object> {
+
+ public static class Builder {
+
+ public Builder(Context context) {
+ this(null, null, context);
+ }
+
+ public Builder(
+ ComponentModel componentModel,
+ ContainerState containerState,
+ Context context) {
+
+ Objects.requireNonNull(context);
+ _componentModel = componentModel;
+ _containerState = containerState;
+ _context = context;
+ }
+
+ public ReferenceCallback build() {
+ Objects.requireNonNull(_cardinality);
+ Objects.requireNonNull(_collectionType);
+ return new ReferenceCallback(_componentModel, _containerState, _context, _name, _cardinality, _collectionType, _onAdd, _onUpdate, _onRemove);
+ }
+
+ public Builder cardinality(ReferenceCardinality cardinality) {
+ _cardinality = cardinality;
+ return this;
+ }
+
+ public Builder collectionType(CollectionType collectionType) {
+ _collectionType = collectionType;
+ return this;
+ }
+
+ public Builder name(String name) {
+ _name = name;
+ return this;
+ }
+
+ public Builder onAdd(Consumer<ReferenceCallback> onAdd) {
+ _onAdd = onAdd;
+ return this;
+ }
+
+ public Builder onUpdate(Consumer<ReferenceCallback> onUpdate) {
+ _onUpdate = onUpdate;
+ return this;
+ }
+
+ public Builder onRemove(Consumer<ReferenceCallback> onRemove) {
+ _onRemove = onRemove;
+ return this;
+ }
+
+ private ReferenceCardinality _cardinality;
+ private CollectionType _collectionType;
+ private ComponentModel _componentModel;
+ private ContainerState _containerState;
+ private Context _context;
+ private String _name;
+ private Consumer<ReferenceCallback> _onAdd;
+ private Consumer<ReferenceCallback> _onUpdate;
+ private Consumer<ReferenceCallback> _onRemove;
+
+ }
+
+ private ReferenceCallback(
+ ComponentModel componentModel,
+ ContainerState containerState,
+ Context context,
+ String name,
+ ReferenceCardinality cardinality,
+ CollectionType collectionType,
+ Consumer<ReferenceCallback> onAdd,
+ Consumer<ReferenceCallback> onUpdate,
+ Consumer<ReferenceCallback> onRemove) {
+
+ _componentModel = Optional.ofNullable(componentModel);
+ _containerState = Optional.ofNullable(containerState);
+ _context = context;
+ _name = Optional.ofNullable(name);
+ _cardinality = cardinality;
+ _collectionType = collectionType;
+ _onAdd = Optional.ofNullable(onAdd);
+ _onUpdate = Optional.ofNullable(onUpdate);
+ _onRemove = Optional.ofNullable(onRemove);
+ }
+
+ Optional<ObserverMethod<ServiceEvent<?>>> observer() {
+ return _componentModel.flatMap(
+ cm -> _containerState.flatMap(
+ cs -> _name.flatMap(
+ n -> {
+ Map<String, ObserverMethod<ServiceEvent<?>>> map = cs.referenceObservers().computeIfAbsent(
+ cm, k -> new LinkedHashMap<>());
+
+ return Optional.ofNullable(map.get(n));
+ }
+ )
+ )
+ );
+ }
+
+ @Override
+ public Object addingService(ServiceReference<Object> reference) {
+ _lock.lock();
+
+ try {
+ Object instance;
+
+ switch (_collectionType) {
+ case PROPERTIES:
+ instance = new UnmodifiableMap(reference);
+ break;
+ case REFERENCE:
+ instance = reference;
+ break;
+ case SERVICEOBJECTS:
+ instance = _context.getServiceObjects(reference);
+ break;
+ case TUPLE:
+ instance = new AbstractMap.SimpleImmutableEntry<Map<String, Object>, Object>(
+ new UnmodifiableMap(reference), _context.getService(reference));
+ break;
+ default:
+ instance = _context.getService(reference);
+ break;
+ }
+
+ final Object object = instance;
+
+ if (_queueing.get()) {
+ _queue.put(reference, object);
+ }
+ else {
+ _tracked.put(reference, object);
+
+ observer().ifPresent(o -> o.notify(event(object, ServiceEventImpl.Event.ADDING)));
+ }
+
+ _onAdd.ifPresent(f -> f.accept(this));
+
+ return instance;
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ public void flush() {
+ _lock.lock();
+
+ try {
+ _queueing.set(false);
+
+ _queue.entrySet().removeIf(
+ entry -> {
+ _tracked.put(entry.getKey(), entry.getValue());
+
+ observer().ifPresent(o -> o.notify(event(entry.getValue(), ServiceEventImpl.Event.ADDING)));
+
+ return true;
+ }
+ );
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<Object> reference, Object service) {
+ _lock.lock();
+
+ try {
+ Object instance = null;
+
+ switch (_collectionType) {
+ case PROPERTIES:
+ instance = new UnmodifiableMap(reference);
+ break;
+ case REFERENCE:
+ instance = reference;
+ break;
+ case SERVICEOBJECTS:
+ break;
+ case TUPLE:
+ @SuppressWarnings("unchecked")
+ Map.Entry<Map<String, Object>, Object> entry = (Map.Entry<Map<String, Object>, Object>)service;
+
+ instance = new AbstractMap.SimpleImmutableEntry<Map<String, Object>, Object>(
+ new UnmodifiableMap(reference), entry.getValue());
+ break;
+ default:
+ break;
+ }
+
+ if (instance != null) {
+ final Object object = instance;
+
+ if (_queueing.get()) {
+ _queue.put(reference, object);
+ }
+ else {
+ _tracked.put(reference, object);
+
+ observer().ifPresent(o -> o.notify(event(object, ServiceEventImpl.Event.MODIFIED)));
+ }
+ }
+
+ _onUpdate.ifPresent(f -> f.accept(this));
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ @Override
+ public void removedService(ServiceReference<Object> reference, Object service) {
+ _lock.lock();
+
+ try {
+ _context.ungetService(reference);
+
+ if (_queueing.get()) {
+ _queue.remove(reference);
+ }
+ else {
+ final Object instance = _tracked.remove(reference);
+
+ observer().ifPresent(o -> o.notify(event(instance, ServiceEventImpl.Event.REMOVED)));
+ }
+
+ _onRemove.ifPresent(f -> f.accept(this));
+ }
+ finally {
+ _lock.unlock();
+ }
+ }
+
+ <T> ServiceEvent<T> event(T t, ServiceEventImpl.Event event) {
+ return new ServiceEventImpl<T>(t, event);
+ }
+
+ public boolean resolved() {
+ if (((_cardinality == ReferenceCardinality.MANDATORY) ||
+ (_cardinality == ReferenceCardinality.AT_LEAST_ONE))) {
+
+ if (_queue.size() + _tracked.size() >= 1) {
+ return true;
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ public Map<ServiceReference<?>, Object> tracked() {
+ return _tracked;
+ }
+
+ private final ReferenceCardinality _cardinality;
+ private final CollectionType _collectionType;
+ private final Optional<ComponentModel> _componentModel;
+ private final Optional<ContainerState> _containerState;
+ private final Context _context;
+ private final Lock _lock = new ReentrantLock();
+ private final Optional<String> _name;
+ private final Optional<Consumer<ReferenceCallback>> _onAdd;
+ private final Optional<Consumer<ReferenceCallback>> _onUpdate;
+ private final Optional<Consumer<ReferenceCallback>> _onRemove;
+ private final AtomicBoolean _queueing = new AtomicBoolean(true);
+ private final Map<ServiceReference<?>, Object> _queue = new ConcurrentHashMap<>();
+ private final Map<ServiceReference<?>, Object> _tracked = new ConcurrentHashMap<>();
+
+ private static class UnmodifiableMap implements Map<String, Object> {
+
+ public UnmodifiableMap(ServiceReference<?> sr) {
+ _sr = sr;;
+ _keys = Arrays.asList(_sr.getPropertyKeys());
+ }
+
+ @Override
+ public int size() {
+ return _keys.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return _keys.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return _keys.contains(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return values().contains(value);
+ }
+
+ @Override
+ public Object get(Object key) {
+ return _sr.getProperty((String)key);
+ }
+
+ @Override
+ public Object put(String key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends Object> m) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> keySet() {
+ return new HashSet<>(_keys);
+ }
+
+ @Override
+ public Collection<Object> values() {
+ List<Object> values = new ArrayList<>();
+
+ for (String key : _keys) {
+ values.add(_sr.getProperty(key));
+ }
+
+ return Collections.unmodifiableCollection(values);
+ }
+
+ @Override
+ public Set<Entry<String, Object>> entrySet() {
+ Set<Map.Entry<String, Object>> entries = new HashSet<>();
+
+ for (String key : _keys) {
+ entries.add(new AbstractMap.SimpleImmutableEntry<>(key, _sr.getProperty(key)));
+ }
+
+ return Collections.unmodifiableSet(entries);
+ }
+
+ private final ServiceReference<?> _sr;
+ private List<String> _keys;
+
+ }
+
+}