You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by da...@apache.org on 2017/01/25 00:08:05 UTC

svn commit: r1780127 [2/5] - in /aries/trunk/cdi: ./ cdi-api-provider-fragment/ cdi-api-provider-fragment/src/ cdi-api-provider-fragment/src/main/ cdi-api-provider-fragment/src/main/resources/ cdi-api-provider-fragment/src/main/resources/META-INF/ cdi-...

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/BundleContextBean.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/BundleContextBean.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/BundleContextBean.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/BundleContextBean.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,98 @@
+/**
+ * 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.bean;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Set;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+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.Sets;
+import org.osgi.framework.BundleContext;
+
+public class BundleContextBean implements Bean<BundleContext> {
+
+	public BundleContextBean(BundleContext bundleContext) {
+		_bundleContext = bundleContext;
+	}
+
+	@Override
+	public BundleContext create(CreationalContext<BundleContext> creationalContext) {
+		return _bundleContext;
+	}
+
+	@Override
+	public void destroy(BundleContext instance, CreationalContext<BundleContext> creationalContext) {
+	}
+
+	@Override
+	public Class<?> getBeanClass() {
+		return BundleContext.class;
+	}
+
+	@Override
+	public Set<InjectionPoint> getInjectionPoints() {
+		return Collections.emptySet();
+	}
+
+	@Override
+	public String getName() {
+		return "BundleContext";
+	}
+
+	@Override
+	public Set<Annotation> getQualifiers() {
+		return DEFAULT_QUALIFIERS;
+	}
+
+	@Override
+	public Class<? extends Annotation> getScope() {
+		return Dependent.class;
+	}
+
+	@Override
+	public Set<Class<? extends Annotation>> getStereotypes() {
+		return Collections.emptySet();
+	}
+
+	@Override
+	public Set<Type> getTypes() {
+		return TYPES;
+	}
+
+	@Override
+	public boolean isAlternative() {
+		return false;
+	}
+
+	@Override
+	public boolean isNullable() {
+		return false;
+	}
+
+	private static final Set<Annotation> DEFAULT_QUALIFIERS = Sets.hashSet(
+		DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE);
+	private static final Set<Type> TYPES = Sets.immutableHashSet(BundleContext.class, Object.class);
+
+	private final BundleContext _bundleContext;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ReferenceBean.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,203 @@
+/**
+ * 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.bean;
+
+import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.Decorator;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.apache.aries.cdi.container.internal.container.BindType;
+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.Sets;
+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.framework.BundleContext;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReferenceBean implements Bean<Object> {
+
+	public ReferenceBean(
+		BeanManagerImpl beanManagerImpl, BundleContext bundleContext, Type injectionPointType, Class<?> beanClass,
+		BindType bindType, ServiceReference<?> serviceReference) {
+
+		_beanManagerImpl = beanManagerImpl;
+		_bundleContext = bundleContext;
+
+		_typesForMatchingBeansToInjectionPoints = Sets.immutableHashSet(injectionPointType, Object.class);
+		_beanClass = beanClass;
+		_bindType = bindType;
+		_serviceReference = serviceReference;
+
+		_currentInjectionPoint = _beanManagerImpl.getServices().get(CurrentInjectionPoint.class);
+		_qualifiers = Sets.hashSet(DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE);
+	}
+
+	public void addQualifier(Annotation annotation) {
+		_qualifiers.add(annotation);
+	}
+
+	public void addQualifiers(Set<Annotation> qualifiers) {
+		_qualifiers.addAll(qualifiers);
+	}
+
+	@Override
+	public Object create(CreationalContext<Object> creationalContext) {
+		return create0(creationalContext);
+	}
+
+	@Override
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	public void destroy(Object instance, CreationalContext creationalContext) {
+		if (_serviceObjects == null) {
+			return;
+		}
+
+		try {
+			_serviceObjects.ungetService(instance);
+		}
+		catch (Throwable t) {
+			if (_log.isWarnEnabled()) {
+				_log.warn("CDIe - UngetService resulted in error", t);
+			}
+		}
+	}
+
+	@Override
+	public Class<?> getBeanClass() {
+		return _beanClass;
+	}
+
+	public BindType getBindType() {
+		return _bindType;
+	}
+
+	@Override
+	public Set<InjectionPoint> getInjectionPoints() {
+		return Collections.emptySet();
+	}
+
+	@Override
+	public String getName() {
+		return toString() + "#" + System.identityHashCode(this);
+	}
+
+	@Override
+	public Set<Annotation> getQualifiers() {
+		return _qualifiers;
+	}
+
+	@Override
+	public Class<? extends Annotation> getScope() {
+		return Dependent.class;
+	}
+
+	@Override
+	public Set<Class<? extends Annotation>> getStereotypes() {
+		return Collections.emptySet();
+	}
+
+	@Override
+	public Set<Type> getTypes() {
+		return _typesForMatchingBeansToInjectionPoints;
+	}
+
+	@Override
+	public boolean isAlternative() {
+		return false;
+	}
+
+	@Override
+	public boolean isNullable() {
+		return false;
+	}
+
+	@Override
+	public String toString() {
+		return "ReferenceBean(" + _serviceReference + ")";
+	}
+
+	protected <T> T create0(CreationalContext<T> creationalContext) {
+		InjectionPoint ip = getInjectionPoint(_currentInjectionPoint);
+		List<Decorator<?>> decorators = getDecorators(ip);
+		T instance = cast(getServiceImpl());
+		if (decorators.isEmpty()) {
+			return instance;
+		}
+		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());
+	}
+
+	protected InjectionPoint getInjectionPoint(CurrentInjectionPoint currentInjectionPoint) {
+		InjectionPoint ip = currentInjectionPoint.peek();
+		return EmptyInjectionPoint.INSTANCE.equals(ip) ? null : ip;
+	}
+
+	protected Object getServiceImpl() {
+		if (ServiceReference.class.equals(_beanClass)) {
+			return _serviceReference;
+		}
+		else if (Map.class.equals(_beanClass)) {
+			Map<String, Object> properties = new HashMap<>();
+
+			for (String key : _serviceReference.getPropertyKeys()) {
+				properties.put(key, _serviceReference.getProperty(key));
+			}
+
+			return properties;
+		}
+
+		if (_serviceObjects == null) {
+			_serviceObjects = _bundleContext.getServiceObjects(_serviceReference);
+		}
+
+		return _serviceObjects.getService();
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(ReferenceBean.class);
+
+	private final Class<?> _beanClass;
+	private final BindType _bindType;
+	private final BundleContext _bundleContext;
+	private final CurrentInjectionPoint _currentInjectionPoint;
+	private final BeanManagerImpl _beanManagerImpl;
+	private final Set<Annotation> _qualifiers;
+	@SuppressWarnings("rawtypes")
+	private volatile ServiceObjects _serviceObjects;
+	private final ServiceReference<?> _serviceReference;
+	private final Set<Type> _typesForMatchingBeansToInjectionPoints;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CdiCommand.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CdiCommand.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CdiCommand.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/command/CdiCommand.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,77 @@
+/**
+ * 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.command;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.aries.cdi.container.internal.container.CdiContainerState;
+import org.apache.aries.cdi.container.internal.container.ExtensionDependency;
+import org.apache.aries.cdi.container.internal.container.ReferenceDependency;
+
+public class CdiCommand {
+
+	public CdiCommand() {
+
+	}
+
+	public void list() {
+		for (CdiContainerState cdiContainerState : _states.values()) {
+			System.out.printf("[%s] %s\n", cdiContainerState.getId(), cdiContainerState.getLastState());
+		}
+	}
+
+	public void info(long bundleId) {
+		CdiContainerState cdiContainerState = _states.get(bundleId);
+
+		if (cdiContainerState == null) {
+			System.out.println("No matching CDI bundle found.");
+
+			return;
+		}
+
+		System.out.printf("[%s] %s\n", cdiContainerState.getId(), cdiContainerState.getLastState());
+		List<ExtensionDependency> extensionDependencies = cdiContainerState.getExtensionDependencies();
+		if (!extensionDependencies.isEmpty()) {
+			System.out.println("  [EXTENSIONS]");
+			for (ExtensionDependency extensionDependency : extensionDependencies) {
+				System.out.printf("    %s%s\n", extensionDependency.toString(), " ???is this resolved???");
+			}
+		}
+		List<ReferenceDependency> referenceDependencies = cdiContainerState.getReferenceDependencies();
+		if (!referenceDependencies.isEmpty()) {
+			System.out.println("  [REFERENCES]");
+			for (ReferenceDependency referenceDependency : referenceDependencies) {
+				System.out.printf(
+					"    %s\n      Status: %s\n      Min Cardinality: %s\n",
+					referenceDependency.toString(),
+					!referenceDependency.isResolved() ? " UNRESOLVED" : "resolved",
+					referenceDependency.getMinCardinality());
+			}
+		}
+	}
+
+	public void add(Long bundleId, CdiContainerState cdiContainerState) {
+		_states.put(bundleId, cdiContainerState);
+	}
+
+	public void remove(Long bundleId) {
+		_states.remove(bundleId);
+	}
+
+	private final Map<Long, CdiContainerState> _states = new ConcurrentHashMap<>();
+
+}
\ No newline at end of file

Added: 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/container/BindType.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BindType.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,5 @@
+package org.apache.aries.cdi.container.internal.container;
+
+public enum BindType {
+	SERVICE, SERVICE_PROPERTIES, SERVICE_REFERENCE
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeployment.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeployment.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeployment.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeployment.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,66 @@
+/**
+ * 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.container;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.jboss.weld.bootstrap.api.ServiceRegistry;
+import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
+import org.jboss.weld.bootstrap.spi.CDI11Deployment;
+import org.jboss.weld.bootstrap.spi.Metadata;
+
+public class BundleDeployment implements CDI11Deployment {
+
+	public BundleDeployment(Iterable<Metadata<Extension>> extensions, BeanDeploymentArchive beanDeploymentArchive) {
+		_extensions = extensions;
+		_beanDeploymentArchive = beanDeploymentArchive;
+
+		_beanDeploymentArchives = new ArrayList<BeanDeploymentArchive>();
+		_beanDeploymentArchives.add(beanDeploymentArchive);
+	}
+
+	@Override
+	public BeanDeploymentArchive getBeanDeploymentArchive(Class<?> beanClass) {
+		return _beanDeploymentArchive;
+	}
+
+	@Override
+	public Collection<BeanDeploymentArchive> getBeanDeploymentArchives() {
+		return _beanDeploymentArchives;
+	}
+
+	@Override
+	public Iterable<Metadata<Extension>> getExtensions() {
+		return _extensions;
+	}
+
+	@Override
+	public ServiceRegistry getServices() {
+		return _beanDeploymentArchive.getServices();
+	}
+
+	@Override
+	public BeanDeploymentArchive loadBeanDeploymentArchive(Class<?> aClass) {
+		return _beanDeploymentArchive;
+	}
+
+	private final BeanDeploymentArchive _beanDeploymentArchive;
+	private final Collection<BeanDeploymentArchive> _beanDeploymentArchives;
+	private final Iterable<Metadata<Extension>> _extensions;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeploymentArchive.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeploymentArchive.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeploymentArchive.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleDeploymentArchive.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,87 @@
+/**
+ * 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.container;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader;
+import org.jboss.weld.bootstrap.api.ServiceRegistry;
+import org.jboss.weld.bootstrap.api.helpers.SimpleServiceRegistry;
+import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
+import org.jboss.weld.bootstrap.spi.BeansXml;
+import org.jboss.weld.ejb.spi.EjbDescriptor;
+import org.jboss.weld.resources.spi.ResourceLoader;
+import org.jboss.weld.serialization.spi.ProxyServices;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class BundleDeploymentArchive implements BeanDeploymentArchive {
+
+	public BundleDeploymentArchive(
+		BundleWiring bundleWiring, String id, Collection<String> beanClassNames, BeansXml beansXml,
+		Bundle extenderBundle) {
+
+		_id = id;
+		_beanClassNames = beanClassNames;
+		_beanDeploymentArchives = Collections.emptyList();
+		_beansXml = beansXml;
+		_ejbs = Collections.emptyList();
+		_services = new SimpleServiceRegistry();
+
+		BundleResourcesLoader loader = new BundleResourcesLoader(bundleWiring, extenderBundle);
+
+		_services.add(ResourceLoader.class, loader);
+		_services.add(ProxyServices.class, loader);
+	}
+
+	@Override
+	public Collection<String> getBeanClasses() {
+		return _beanClassNames;
+	}
+
+	@Override
+	public Collection<BeanDeploymentArchive> getBeanDeploymentArchives() {
+		return _beanDeploymentArchives;
+	}
+
+	@Override
+	public BeansXml getBeansXml() {
+		return _beansXml;
+	}
+
+	@Override
+	public Collection<EjbDescriptor<?>> getEjbs() {
+		return _ejbs;
+	}
+
+	@Override
+	public String getId() {
+		return _id;
+	}
+
+	@Override
+	public ServiceRegistry getServices() {
+		return _services;
+	}
+
+	private final Collection<String> _beanClassNames;
+	private final Collection<BeanDeploymentArchive> _beanDeploymentArchives;
+	private final BeansXml _beansXml;
+	private final Collection<EjbDescriptor<?>> _ejbs;
+	private final String _id;
+	private final ServiceRegistry _services;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerService.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerService.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerService.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerService.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,20 @@
+package org.apache.aries.cdi.container.internal.container;
+
+import javax.enterprise.inject.spi.BeanManager;
+
+import org.osgi.service.cdi.CdiContainer;
+
+public class CdiContainerService implements CdiContainer {
+
+	@Override
+	public BeanManager getBeanManager() {
+		return _beanManager;
+	}
+
+	public void setBeanManager(BeanManager beanManager) {
+		_beanManager = beanManager;
+	}
+
+	private volatile BeanManager _beanManager;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerState.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerState.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerState.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/CdiContainerState.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,206 @@
+/**
+ * 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.container;
+
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.util.AnnotationLiteral;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cdi.CdiContainer;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.CdiExtenderConstants;
+import org.osgi.service.cdi.CdiListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CdiContainerState {
+
+	public static final AnnotationLiteral<Any> ANY = new AnnotationLiteral<Any>() {
+		private static final long serialVersionUID = 1L;
+	};
+
+	public CdiContainerState(
+		Bundle bundle, Bundle extenderBundle, Map<ServiceReference<CdiListener>, CdiListener> listeners) {
+
+		_bundle = bundle;
+		_extenderBundle = extenderBundle;
+		_listeners = listeners;
+
+		_cdiContainerService = new CdiContainerService();
+
+		Hashtable<String, Object> properties = new Hashtable<>();
+
+		properties.put(CdiExtenderConstants.CDI_EXTENDER_CONTAINER_STATE, CdiEvent.State.CREATING);
+
+		_cdiContainerRegistration = _bundle.getBundleContext().registerService(
+			CdiContainer.class, _cdiContainerService, properties);
+	}
+
+	public void close() {
+		try {
+			_lock.lock();
+
+			_cdiContainerRegistration.unregister();
+		}
+		catch (Exception e) {
+			if (_log.isTraceEnabled()) {
+				_log.trace("Service already unregistered {}", _cdiContainerRegistration);
+			}
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	public BeanManager getBeanManager() {
+		return _beanManager;
+	}
+
+	public Bundle getBundle() {
+		return _bundle;
+	}
+
+	public Bundle getExtenderBundle() {
+		return _extenderBundle;
+	}
+
+	public List<ExtensionDependency> getExtensionDependencies() {
+		return _extensionDependencies;
+	}
+
+	public String getId() {
+		return _bundle.getSymbolicName() + ":" + _bundle.getBundleId();
+	}
+
+	public CdiEvent.State getLastState() {
+		return _lastState.get();
+	}
+
+	public List<ReferenceDependency> getReferenceDependencies() {
+		return _referenceDependencies;
+	}
+
+	public void fire(CdiEvent event) {
+		try {
+			_lock.lock();
+
+			if ((_lastState.get() == CdiEvent.State.DESTROYING) &&
+				((event.getState() == CdiEvent.State.WAITING_FOR_EXTENSIONS) ||
+				(event.getState() == CdiEvent.State.WAITING_FOR_SERVICES))) {
+
+				return;
+			}
+
+			if (_log.isDebugEnabled()) {
+				_log.debug("CDIe - Event {}", event, event.getCause());
+			}
+
+			updateState(event);
+
+			if (_beanManager != null) {
+				_beanManager.fireEvent(event);
+			}
+
+			for (CdiListener listener : _listeners.values()) {
+				try {
+					listener.cdiEvent(event);
+				}
+				catch (Throwable t) {
+					if (_log.isErrorEnabled()) {
+						_log.error("CDIe - CdiListener failed", t);
+					}
+				}
+			}
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	public void fire(CdiEvent.State state) {
+		fire(new CdiEvent(state, _bundle, _extenderBundle));
+	}
+
+	public void fire(CdiEvent.State state, String payload) {
+		fire(new CdiEvent(state, _bundle, _extenderBundle, payload, null));
+	}
+
+	public void fire(CdiEvent.State state, Throwable cause) {
+		fire(new CdiEvent(state, _bundle, _extenderBundle, null, cause));
+	}
+
+	public void setBeanManager(BeanManager beanManager) {
+		_beanManager = beanManager;
+		_cdiContainerService.setBeanManager(beanManager);
+	}
+
+	public void setExtensionDependencies(List<ExtensionDependency> extensionDependencies) {
+		_extensionDependencies = extensionDependencies;
+	}
+
+	public void setReferenceDependency(List<ReferenceDependency> referenceDependencies) {
+		_referenceDependencies = referenceDependencies;
+	}
+
+	private void updateState(CdiEvent event) {
+		try {
+			_lock.lock();
+
+			ServiceReference<CdiContainer> reference = _cdiContainerRegistration.getReference();
+
+			if (event.getState() == reference.getProperty(CdiExtenderConstants.CDI_EXTENDER_CONTAINER_STATE)) {
+				return;
+			}
+
+			_lastState.set(event.getState());
+
+			Hashtable<String, Object> properties = new Hashtable<>();
+
+			for (String key : reference.getPropertyKeys()) {
+				properties.put(key, reference.getProperty(key));
+			}
+
+			properties.put(CdiExtenderConstants.CDI_EXTENDER_CONTAINER_STATE, event.getState());
+
+			_cdiContainerRegistration.setProperties(properties);
+		}
+		finally {
+			_lock.unlock();
+		}
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(CdiContainerState.class);
+
+	private volatile BeanManager _beanManager;
+	private final Bundle _bundle;
+	private final ServiceRegistration<CdiContainer> _cdiContainerRegistration;
+	private final CdiContainerService _cdiContainerService;
+	private final Bundle _extenderBundle;
+	private List<ExtensionDependency> _extensionDependencies;
+	private AtomicReference<CdiEvent.State> _lastState = new AtomicReference<CdiEvent.State>(CdiEvent.State.CREATING);
+	private final Map<ServiceReference<CdiListener>, CdiListener> _listeners;
+	private final ReentrantLock _lock = new ReentrantLock();
+	private List<ReferenceDependency> _referenceDependencies;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionDependency.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionDependency.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionDependency.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionDependency.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,51 @@
+/**
+ * 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.container;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.CdiExtenderConstants;
+
+public class ExtensionDependency {
+
+	public ExtensionDependency(BundleContext bundleContext, Long bundleId, String name) {
+		_string = "(&(" + org.osgi.framework.Constants.SERVICE_BUNDLEID + "=" + bundleId + ")(" +
+			CdiExtenderConstants.CDI_EXTENSION + "=" + name + "))";
+
+		try {
+			_filter = bundleContext.createFilter(_string);
+		}
+		catch (InvalidSyntaxException ise) {
+			throw new RuntimeException(ise);
+		}
+	}
+
+	public boolean matches(ServiceReference<Extension> reference) {
+		return _filter.match(reference);
+	}
+
+	@Override
+	public String toString() {
+		return _string;
+	}
+
+	private final Filter _filter;
+	private final String _string;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,41 @@
+/**
+ * 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.container;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.jboss.weld.bootstrap.spi.Metadata;
+
+public class ExtensionMetadata implements Metadata<Extension> {
+
+	public ExtensionMetadata(Extension extension, String location) {
+		_extension = extension;
+		_location = location;
+	}
+
+	@Override
+	public Extension getValue() {
+		return _extension;
+	}
+
+	@Override
+	public String getLocation() {
+		return _location;
+	}
+
+	private final Extension _extension;
+	private final String _location;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/FilterBuilder.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/FilterBuilder.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/FilterBuilder.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/FilterBuilder.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,67 @@
+/**
+ * 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.container;
+
+import java.util.List;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class FilterBuilder {
+
+	public static 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);
+		}
+	}
+
+	public static Filter createReferenceFilter(List<ReferenceDependency> referenceDependencies) {
+		try {
+			StringBuilder sb = new StringBuilder();
+
+			if (referenceDependencies.size() > 1) sb.append("(|");
+
+			for (ReferenceDependency dependency : referenceDependencies) {
+				sb.append(dependency.toString());
+			}
+
+			if (referenceDependencies.size() > 1) sb.append(")");
+
+			return FrameworkUtil.createFilter(sb.toString());
+		}
+		catch (InvalidSyntaxException ise) {
+			throw new RuntimeException(ise);
+		}
+	}
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_1_Init.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_1_Init.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_1_Init.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_1_Init.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,49 @@
+/**
+ * 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.container;
+
+import java.util.Collection;
+
+import org.apache.aries.cdi.container.internal.locate.ClassLocater;
+import org.apache.aries.cdi.container.internal.locate.ClassLocaterResult;
+import org.jboss.weld.bootstrap.spi.BeansXml;
+import org.jboss.weld.xml.BeansXmlParser;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+
+public class Phase_1_Init {
+
+	public Phase_1_Init(Bundle bundle, CdiContainerState cdiContainerState) {
+		BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
+
+		ClassLocaterResult locatorResult = ClassLocater.locate(bundleWiring);
+		Collection<String> beanClassNames = locatorResult.getBeanClassNames();
+		BeansXmlParser beansXmlParser = new BeansXmlParser();
+		BeansXml beansXml = beansXmlParser.parse(locatorResult.getBeanDescriptorURLs());
+
+		_extensionPhase = new Phase_2_Extension(bundle, cdiContainerState, beanClassNames, beansXml);
+	}
+
+	public void close() {
+		_extensionPhase.close();
+	}
+
+	public void open() {
+		_extensionPhase.open();
+	}
+
+	private final Phase_2_Extension _extensionPhase;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_2_Extension.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_2_Extension.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_2_Extension.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_2_Extension.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,188 @@
+/**
+ * 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.container;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.enterprise.inject.spi.Extension;
+
+import org.jboss.weld.bootstrap.spi.BeansXml;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.service.cdi.CdiExtenderConstants;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_2_Extension {
+
+	public Phase_2_Extension(
+		Bundle bundle, CdiContainerState cdiContainerState, Collection<String> beanClassNames, BeansXml beansXml) {
+
+		_bundle = bundle;
+		_cdiContainerState = cdiContainerState;
+		_bundleContext = bundle.getBundleContext();
+		_extensionDependencies = findExtensionDependencies(bundle.adapt(BundleWiring.class));
+		_extensions = new ConcurrentSkipListMap<>(Comparator.reverseOrder());
+		_beanClassNames = beanClassNames;
+		_beansXml = beansXml;
+
+		_cdiContainerState.setExtensionDependencies(_extensionDependencies);
+	}
+
+	public void close() {
+		_cdiContainerState.fire(CdiEvent.State.DESTROYING);
+
+		if (_extensionTracker != null) {
+			_extensionTracker.close();
+
+			_extensionTracker = null;
+		}
+		else {
+			_referencePhase.close();
+
+			_referencePhase = null;
+		}
+
+		_cdiContainerState.fire(CdiEvent.State.DESTROYED);
+
+		_cdiContainerState.close();
+	}
+
+	public void open() {
+		_cdiContainerState.fire(CdiEvent.State.CREATING);
+
+		if (!_extensionDependencies.isEmpty()) {
+			Filter filter = FilterBuilder.createExtensionFilter(_extensionDependencies);
+
+			_cdiContainerState.fire(CdiEvent.State.WAITING_FOR_EXTENSIONS, filter.toString());
+
+			_extensionTracker = new ServiceTracker<>(_bundleContext, filter, new ExtensionPhaseCustomizer());
+
+			_extensionTracker.open();
+		}
+		else {
+			_referencePhase = new Phase_3_Reference(_bundle, _cdiContainerState, _extensions, _beanClassNames, _beansXml);
+
+			_referencePhase.open();
+		}
+	}
+
+	List<ExtensionDependency> findExtensionDependencies(BundleWiring bundleWiring) {
+		List<ExtensionDependency> extensionDependencies = new CopyOnWriteArrayList<>();
+		List<BundleWire> requiredWires = bundleWiring.getRequiredWires(CdiExtenderConstants.CDI_EXTENSION);
+
+		for (BundleWire wire : requiredWires) {
+			Map<String, Object> attributes = wire.getCapability().getAttributes();
+
+			String extension = (String)attributes.get(CdiExtenderConstants.CDI_EXTENSION);
+
+			if (extension != null) {
+				ExtensionDependency extensionDependency = new ExtensionDependency(
+					_bundleContext, wire.getProvider().getBundle().getBundleId(), extension);
+
+				extensionDependencies.add(extensionDependency);
+			}
+		}
+
+		return extensionDependencies;
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Phase_2_Extension.class);
+
+	private final Collection<String> _beanClassNames;
+	private final BeansXml _beansXml;
+	private final Bundle _bundle;
+	private final BundleContext _bundleContext;
+	private final CdiContainerState _cdiContainerState;
+	private final Map<ServiceReference<Extension>, Metadata<Extension>> _extensions;
+	private final List<ExtensionDependency> _extensionDependencies;
+	private Phase_3_Reference _referencePhase;
+
+	private ServiceTracker<Extension, ExtensionDependency> _extensionTracker;
+
+	private class ExtensionPhaseCustomizer implements ServiceTrackerCustomizer<Extension, ExtensionDependency> {
+
+		@Override
+		public ExtensionDependency addingService(ServiceReference<Extension> reference) {
+			ExtensionDependency trackedDependency = null;
+
+			for (ExtensionDependency extensionDependency : _extensionDependencies) {
+				if (extensionDependency.matches(reference)) {
+					_extensionDependencies.remove(extensionDependency);
+					trackedDependency = extensionDependency;
+
+					Extension extension = _bundleContext.getService(reference);
+
+					_extensions.put(reference, new ExtensionMetadata(extension, reference.getBundle().toString()));
+
+					break;
+				}
+			}
+
+			if ((trackedDependency != null) && _extensionDependencies.isEmpty()) {
+				_referencePhase = new Phase_3_Reference(_bundle, _cdiContainerState, _extensions, _beanClassNames, _beansXml);
+
+				_referencePhase.open();
+			}
+			else if (_log.isDebugEnabled()) {
+				_log.debug("CDIe - Still waiting for extensions {}", _extensionDependencies);
+			}
+
+			return trackedDependency;
+		}
+
+		@Override
+		public void modifiedService(ServiceReference<Extension> reference, ExtensionDependency extentionDependency) {
+		}
+
+		@Override
+		public void removedService(ServiceReference<Extension> reference, ExtensionDependency extentionDependency) {
+			if (_extensionDependencies.isEmpty()) {
+				_referencePhase.close();
+
+				_referencePhase = null;
+
+				_cdiContainerState.fire(CdiEvent.State.WAITING_FOR_EXTENSIONS);
+			}
+			_extensions.remove(reference);
+
+			try {
+				_bundleContext.ungetService(reference);
+			}
+			catch (IllegalStateException ise) {
+				if (_log.isWarnEnabled()) {
+					_log.warn("CDIe - UngetService resulted in error", ise);
+				}
+			}
+
+			_extensionDependencies.add(extentionDependency);
+		}
+
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_3_Reference.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_3_Reference.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_3_Reference.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_3_Reference.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,337 @@
+/**
+ * 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.container;
+
+import static org.osgi.namespace.extender.ExtenderNamespace.EXTENDER_NAMESPACE;
+import static org.osgi.service.cdi.CdiExtenderConstants.CDI_EXTENDER;
+import static org.osgi.service.cdi.CdiExtenderConstants.REQUIREMENT_REFERENCES_DIRECTIVE;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.apache.aries.cdi.container.internal.literal.AnyLiteral;
+import org.apache.aries.cdi.container.internal.literal.ReferenceLiteral;
+import org.jboss.weld.bootstrap.WeldBootstrap;
+import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive;
+import org.jboss.weld.bootstrap.spi.BeansXml;
+import org.jboss.weld.bootstrap.spi.Deployment;
+import org.jboss.weld.bootstrap.spi.Metadata;
+import org.jboss.weld.manager.BeanManagerImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.cdi.CdiEvent;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_3_Reference {
+
+	public Phase_3_Reference(
+		Bundle bundle, CdiContainerState cdiContainerState, Map<ServiceReference<Extension>,
+		Metadata<Extension>> extensions, Collection<String> beanClassNames, BeansXml beansXml) {
+
+		_bundle = bundle;
+		_cdiContainerState = cdiContainerState;
+		_extensions = extensions;
+		_bundleContext = _bundle.getBundleContext();
+		_bundleWiring = _bundle.adapt(BundleWiring.class);
+		_beanClassNames = beanClassNames;
+		_beansXml = beansXml;
+
+		_cdiContainerState.setReferenceDependency(_referenceDependencies);
+	}
+
+	public void close() {
+		if (_serviceTracker != null) {
+			_serviceTracker.close();
+
+			_serviceTracker = null;
+		}
+		else {
+			_lock.lock();
+
+			try {
+				if (_publishPhase != null) {
+					_publishPhase.close();
+
+					_publishPhase = null;
+				}
+			}
+			finally {
+				_lock.unlock();
+			}
+		}
+	}
+
+	public void open() {
+		BeanDeploymentArchive beanDeploymentArchive = new BundleDeploymentArchive(
+			_bundleWiring, _cdiContainerState.getId(), _beanClassNames, _beansXml,
+			_cdiContainerState.getExtenderBundle());
+
+		WeldBootstrap bootstrap = new WeldBootstrap();
+
+		List<Metadata<Extension>> extensions = new ArrayList<>();
+
+		// Add the internal extensions
+		extensions.add(
+			new ExtensionMetadata(new ReferenceExtension(_referenceDependencies, _bundleContext), _bundle.toString()));
+		extensions.add(new ExtensionMetadata(new ServiceExtension(_services), _bundle.toString()));
+
+		// Add extensions found from the bundle's classloader, such as those in the Bundle-ClassPath
+		for (Metadata<Extension> meta : bootstrap.loadExtensions(_bundleWiring.getClassLoader())) {
+			extensions.add(meta);
+		}
+
+		// Add external extensions
+		for (Metadata<Extension> meta : _extensions.values()) {
+			extensions.add(meta);
+		}
+
+		Deployment deployment = new BundleDeployment(extensions, beanDeploymentArchive);
+
+		bootstrap.startContainer(_cdiContainerState.getId(), new SimpleEnvironment(), deployment);
+
+		BeanManager beanManager = bootstrap.getManager(beanDeploymentArchive);
+
+		_cdiContainerState.setBeanManager(beanManager);
+
+		bootstrap.startInitialization();
+		bootstrap.deployBeans();
+
+		processRequirementDefinedReferences((BeanManagerImpl)beanManager);
+
+		if (!_referenceDependencies.isEmpty()) {
+			Filter filter = FilterBuilder.createReferenceFilter(_referenceDependencies);
+
+			_cdiContainerState.fire(CdiEvent.State.WAITING_FOR_SERVICES, filter.toString());
+
+			_serviceTracker = new ServiceTracker<>(_bundleContext, filter, new ReferencePhaseCustomizer(bootstrap));
+
+			_serviceTracker.open();
+		}
+
+		_lock.lock();
+
+		try {
+			if ((_publishPhase == null) && dependenciesAreEmptyOrAllOptional()) {
+				_publishPhase = new Phase_4_Publish(this, bootstrap);
+
+				_publishPhase.open();
+			}
+		}
+		finally {
+			_lock.unlock();
+		}
+
+	}
+
+	private boolean dependenciesAreEmptyOrAllOptional() {
+		if (_referenceDependencies.isEmpty()) {
+			return true;
+		}
+
+		for (ReferenceDependency referenceDependency : _referenceDependencies) {
+			if (referenceDependency.getMinCardinality() > 0) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	private List<String> getReferenceClassNames() {
+		List<String> referenceClassNames = new ArrayList<>();
+
+		BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class);
+		List<BundleWire> requiredBundleWires = bundleWiring.getRequiredWires(EXTENDER_NAMESPACE);
+
+		for (BundleWire bundleWire : requiredBundleWires) {
+			Map<String, Object> attributes = bundleWire.getCapability().getAttributes();
+
+			if (attributes.containsKey(EXTENDER_NAMESPACE) &&
+				attributes.get(EXTENDER_NAMESPACE).equals(CDI_EXTENDER)) {
+
+				BundleRequirement requirement = bundleWire.getRequirement();
+
+				Map<String, String> directives = requirement.getDirectives();
+
+				if (directives.containsKey(REQUIREMENT_REFERENCES_DIRECTIVE)) {
+					String string = directives.get(REQUIREMENT_REFERENCES_DIRECTIVE);
+
+					List<String> references = Arrays.asList(string.split("\\s*,\\s*"));
+
+					if (!references.isEmpty()) {
+						referenceClassNames.addAll(references);
+					}
+				}
+			}
+		}
+
+		return referenceClassNames;
+	}
+
+	private void processReferenceClass(String referenceClassName, BeanManagerImpl beanManagerImpl) {
+		try {
+			Class<?> beanClass = _bundle.loadClass(referenceClassName);
+
+			Set<Bean<?>> beans = beanManagerImpl.getBeans(beanClass, AnyLiteral.INSTANCE);
+
+			if (beans.isEmpty()) {
+				_log.error(
+					"CDIe - MANIFEST reference processing cannot find bean for class {}", referenceClassName);
+
+				return;
+			}
+
+			Bean<?> bean = beanManagerImpl.resolve(beans);
+
+			for (InjectionPoint injectionPoint : bean.getInjectionPoints()) {
+				try {
+					ReferenceDependency referenceDependency = new ReferenceDependency(
+						beanManagerImpl, ReferenceLiteral.INSTANCE, injectionPoint);
+
+					_referenceDependencies.add(referenceDependency);
+				}
+				catch (InvalidSyntaxException ise) {
+					_log.error("CDIe - MANIFEST reference processing error", ise);
+				}
+			}
+		}
+		catch (ClassNotFoundException cnfe) {
+			_log.error("CDIe - MANIFEST reference processing cannot load class {}", referenceClassName, cnfe);
+		}
+	}
+
+	private void processRequirementDefinedReferences(BeanManagerImpl beanManagerImpl) {
+		List<String> referenceClassNames = getReferenceClassNames();
+
+		for (String referenceClassName : referenceClassNames) {
+			processReferenceClass(referenceClassName, beanManagerImpl);
+		}
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Phase_3_Reference.class);
+
+	private final Collection<String> _beanClassNames;
+	private final BeansXml _beansXml;
+	final Bundle _bundle;
+	private final BundleContext _bundleContext;
+	private final BundleWiring _bundleWiring;
+	final CdiContainerState _cdiContainerState;
+	private final Map<ServiceReference<Extension>, Metadata<Extension>> _extensions;
+	private final Lock _lock = new ReentrantLock(true);
+	private Phase_4_Publish _publishPhase;
+	final List<ReferenceDependency> _referenceDependencies = new CopyOnWriteArrayList<>();
+	final List<ServiceDeclaration> _services = new CopyOnWriteArrayList<>();
+
+	ServiceTracker<?, ?> _serviceTracker;
+
+	private class ReferencePhaseCustomizer implements ServiceTrackerCustomizer<Object, Object> {
+
+		public ReferencePhaseCustomizer(WeldBootstrap bootstrap) {
+			_bootstrap = bootstrap;
+		}
+
+		@Override
+		public Object addingService(ServiceReference<Object> reference) {
+			_lock.lock();
+
+			try {
+				if (_publishPhase != null) {
+					return null;
+				}
+
+				boolean matches = false;
+				boolean resolved = true;
+
+				for (ReferenceDependency referenceDependency : _referenceDependencies) {
+					if (referenceDependency.matches(reference)) {
+						referenceDependency.resolve(reference);
+						matches = true;
+					}
+					if (!referenceDependency.isResolved()) {
+						resolved = false;
+					}
+				}
+
+				if (!matches) {
+					return null;
+				}
+
+				if (resolved) {
+					_publishPhase = new Phase_4_Publish(Phase_3_Reference.this, _bootstrap);
+
+					_publishPhase.open();
+				}
+
+				return new Object();
+			}
+			finally {
+				_lock.unlock();
+			}
+		}
+
+		@Override
+		public void modifiedService(ServiceReference<Object> reference, Object object) {
+		}
+
+		@Override
+		public void removedService(ServiceReference<Object> reference, Object object) {
+			_lock.lock();
+
+			try {
+				if (_publishPhase != null) {
+					_publishPhase.close();
+
+					_publishPhase = null;
+
+					_cdiContainerState.fire(CdiEvent.State.WAITING_FOR_SERVICES);
+				}
+
+				for (ReferenceDependency referenceDependency : _referenceDependencies) {
+					if (referenceDependency.matches(reference)) {
+						referenceDependency.unresolve(reference);
+					}
+				}
+			}
+			finally {
+				_lock.unlock();
+			}
+		}
+
+		private final WeldBootstrap _bootstrap;
+
+	}
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_4_Publish.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_4_Publish.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_4_Publish.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase_4_Publish.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,255 @@
+/**
+ * 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.container;
+
+import static org.osgi.namespace.extender.ExtenderNamespace.EXTENDER_NAMESPACE;
+import static org.osgi.service.cdi.CdiExtenderConstants.CDI_EXTENDER;
+import static org.osgi.service.cdi.CdiExtenderConstants.REQUIREMENT_SERVICES_DIRECTIVE;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.naming.spi.ObjectFactory;
+
+import org.apache.aries.cdi.container.internal.bean.ReferenceBean;
+import org.apache.aries.cdi.container.internal.literal.AnyLiteral;
+import org.apache.aries.cdi.container.internal.literal.ServiceLiteral;
+import org.jboss.weld.bootstrap.api.Bootstrap;
+import org.jboss.weld.manager.BeanManagerImpl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.cdi.CdiEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Phase_4_Publish {
+
+	public Phase_4_Publish(
+		Phase_3_Reference referencePhase, Bootstrap bootstrap) {
+
+		_referencePhase = referencePhase;
+		_bootstrap = bootstrap;
+		_bundle = _referencePhase._bundle;
+		_bundleContext = _referencePhase._bundle.getBundleContext();
+	}
+
+	public void close() {
+		for (ServiceRegistration<?> registration : _registrations) {
+			try {
+				registration.unregister();
+			}
+			catch (IllegalStateException ise) {
+				if (_log.isTraceEnabled()) {
+					_log.trace("Service already unregistered {}", registration);
+				}
+			}
+		}
+
+		_registrations.clear();
+
+		if (_beanManagerRegistration != null) {
+			try {
+				_beanManagerRegistration.unregister();
+			}
+			catch (Exception e) {
+				if (_log.isTraceEnabled()) {
+					_log.trace("Service already unregistered {}", _beanManagerRegistration);
+				}
+			}
+		}
+
+		if (_objectFactoryRegistration != null) {
+			try {
+				_objectFactoryRegistration.unregister();
+			}
+			catch (Exception e) {
+				if (_log.isTraceEnabled()) {
+					_log.trace("Service already unregistered {}", _objectFactoryRegistration);
+				}
+			}
+		}
+
+		_bootstrap.shutdown();
+	}
+
+	public void open() {
+		_referencePhase._cdiContainerState.fire(CdiEvent.State.SATISFIED);
+
+		BeanManager beanManager = _referencePhase._cdiContainerState.getBeanManager();
+
+		processReferenceDependencies((BeanManagerImpl)beanManager);
+
+		_bootstrap.validateBeans();
+		_bootstrap.endInitialization();
+
+		processRequirementDefinedServices((BeanManagerImpl)beanManager);
+		processServiceDeclarations();
+
+		_beanManagerRegistration = _bundleContext.registerService(
+			BeanManager.class, beanManager, null);
+
+		_referencePhase._cdiContainerState.fire(CdiEvent.State.CREATED);
+	}
+
+	private List<String> getServiceClassNames() {
+		List<String> serviceClassNames = new ArrayList<>();
+
+		BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class);
+		List<BundleWire> requiredBundleWires = bundleWiring.getRequiredWires(EXTENDER_NAMESPACE);
+
+		for (BundleWire bundleWire : requiredBundleWires) {
+			Map<String, Object> attributes = bundleWire.getCapability().getAttributes();
+
+			if (attributes.containsKey(EXTENDER_NAMESPACE) &&
+				attributes.get(EXTENDER_NAMESPACE).equals(CDI_EXTENDER)) {
+
+				BundleRequirement requirement = bundleWire.getRequirement();
+
+				Map<String, String> directives = requirement.getDirectives();
+
+				if (directives.containsKey(REQUIREMENT_SERVICES_DIRECTIVE)) {
+					String string = directives.get(REQUIREMENT_SERVICES_DIRECTIVE);
+
+					List<String> services = Arrays.asList(string.split("\\s*,\\s*"));
+
+					if (!services.isEmpty()) {
+						serviceClassNames.addAll(services);
+					}
+				}
+			}
+		}
+
+		return serviceClassNames;
+	}
+
+	private void processReferenceDependencies(BeanManagerImpl beanManagerImpl) {
+		Map<ServiceReference<?>, Set<ReferenceBean>> beans = new HashMap<>();
+
+		for (ReferenceDependency referenceDependency : _referencePhase._referenceDependencies) {
+			for (ServiceReference<?> matchingReference : referenceDependency.getMatchingReferences()) {
+				Set<ReferenceBean> set = beans.get(matchingReference);
+
+				if (set == null) {
+					set = new HashSet<>();
+
+					beans.put(matchingReference, set);
+				}
+
+				ReferenceBean existingBean = null;
+
+				for (ReferenceBean bean : set) {
+					if (bean.getBindType() == referenceDependency.getBindType() &&
+						bean.getBeanClass().equals(referenceDependency.getBeanClass()) &&
+						bean.getTypes().contains(referenceDependency.getInjectionPointType())) {
+
+						existingBean = bean;
+					}
+				}
+
+				if (existingBean != null) {
+					existingBean.addQualifier(referenceDependency.getReference());
+					existingBean.addQualifiers(referenceDependency.getInjectionPoint().getQualifiers());
+				}
+				else {
+					ReferenceBean bean = new ReferenceBean(
+						beanManagerImpl, _bundleContext, referenceDependency.getInjectionPointType(),
+						referenceDependency.getBeanClass(), referenceDependency.getBindType(), matchingReference);
+
+					bean.addQualifier(referenceDependency.getReference());
+					bean.addQualifiers(referenceDependency.getInjectionPoint().getQualifiers());
+
+					set.add(bean);
+
+					beanManagerImpl.addBean(bean);
+				}
+			}
+		}
+	}
+
+	private void processRequirementDefinedServices(BeanManagerImpl beanManagerImpl) {
+		List<String> serviceClassNames = getServiceClassNames();
+
+		for (String serviceClassName : serviceClassNames) {
+			try {
+				Class<?> beanClass = _bundle.loadClass(serviceClassName);
+
+				Set<Bean<?>> beans = beanManagerImpl.getBeans(beanClass, AnyLiteral.INSTANCE);
+
+				if (beans.isEmpty()) {
+					_log.error(
+						"CDIe - MANIFEST service processing cannot find bean for class {}", serviceClassName);
+
+					continue;
+				}
+
+				Bean<?> bean = beanManagerImpl.resolve(beans);
+				CreationalContext<?> creationalContext = beanManagerImpl.createCreationalContext(bean);
+				ServiceDeclaration serviceDeclaration = new ServiceDeclaration(
+					ServiceLiteral.INSTANCE, bean, creationalContext);
+
+				processServiceDeclaration(serviceDeclaration);
+			}
+			catch (ClassNotFoundException cnfe) {
+				_log.error("CDIe - MANIFEST service processing cannot load class {}", serviceClassName, cnfe);
+			}
+		}
+	}
+
+	private void processServiceDeclarations() {
+		for (ServiceDeclaration serviceDeclaration : _referencePhase._services) {
+			processServiceDeclaration(serviceDeclaration);
+		}
+	}
+
+	private void processServiceDeclaration(ServiceDeclaration serviceDeclaration) {
+		if (_log.isDebugEnabled()) {
+			_log.debug("CDIe - Publishing bean {} as service.", serviceDeclaration);
+		}
+
+		String[] classNames = serviceDeclaration.getClassNames();
+		Object serviceInstance = serviceDeclaration.getServiceInstance();
+		Dictionary<String,Object> properties = serviceDeclaration.getProperties();
+
+		_registrations.add(
+			_bundleContext.registerService(classNames, serviceInstance, properties));
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(Phase_4_Publish.class);
+
+	private final Bootstrap _bootstrap;
+	private final Bundle _bundle;
+	private final BundleContext _bundleContext;
+	private final Phase_3_Reference _referencePhase;
+	private final List<ServiceRegistration<?>> _registrations = new CopyOnWriteArrayList<>();
+
+	private ServiceRegistration<BeanManager> _beanManagerRegistration;
+	private ServiceRegistration<ObjectFactory> _objectFactoryRegistration;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceDependency.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceDependency.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceDependency.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceDependency.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,341 @@
+/**
+ * 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.container;
+
+import static org.apache.aries.cdi.container.internal.util.Reflection.cast;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.apache.aries.cdi.container.internal.util.Strings;
+import org.jboss.weld.manager.BeanManagerImpl;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cdi.annotations.MinCardinality;
+import org.osgi.service.cdi.annotations.Reference;
+import org.osgi.service.cdi.annotations.ReferenceFilterQualifier;
+import org.osgi.service.cdi.annotations.ReferenceScope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ReferenceDependency {
+
+	public ReferenceDependency(
+			BeanManagerImpl beanManagerImpl, Reference reference, InjectionPoint injectionPoint)
+		throws InvalidSyntaxException {
+
+		_beanManagerImpl = beanManagerImpl;
+		_reference = reference;
+		_injectionPoint = injectionPoint;
+
+		_bindType = getBindType(_injectionPoint.getType());
+		_minCardinality = getMinCardinality(_injectionPoint);
+		_serviceClass = getServiceType();
+
+		_string = buildFilter(_serviceClass, _injectionPoint.getQualifiers());
+		_filter = FrameworkUtil.createFilter(_string);
+	}
+
+	public Class<?> getBeanClass() {
+		if (_bindType == BindType.SERVICE_REFERENCE) {
+			return ServiceReference.class;
+		}
+		else if (_bindType == BindType.SERVICE_PROPERTIES) {
+			return Map.class;
+		}
+
+		return _serviceClass;
+	}
+
+	public BindType getBindType() {
+		return _bindType;
+	}
+
+	public InjectionPoint getInjectionPoint() {
+		return _injectionPoint;
+	}
+
+	public int getMinCardinality() {
+		return _minCardinality;
+	}
+
+	public BeanManagerImpl getManager() {
+		return _beanManagerImpl;
+	}
+
+	public Reference getReference() {
+		return _reference;
+	}
+
+	public Set<ServiceReference<?>> getMatchingReferences() {
+		return _matchingReferences;
+	}
+
+	public Type getInjectionPointType() {
+		Type type = _injectionPoint.getType();
+
+		if ((type instanceof ParameterizedType)) {
+			ParameterizedType pType = (ParameterizedType)type;
+
+			if (Instance.class.isAssignableFrom(cast(pType.getRawType()))) {
+				type = pType.getActualTypeArguments()[0];
+			}
+		}
+
+		return type;
+	}
+
+	public boolean isResolved() {
+		return (_matchingReferences.size() >= _minCardinality);
+	}
+
+	public boolean matches(ServiceReference<?> reference) {
+		return _filter.match(reference);
+	}
+
+	public void resolve(ServiceReference<?> reference) {
+		_matchingReferences.add(reference);
+	}
+
+	public void unresolve(ServiceReference<?> reference) {
+		_matchingReferences.remove(reference);
+	}
+
+	@Override
+	public String toString() {
+		return _string;
+	}
+
+	private String buildFilter(Class<?> serviceType, Set<Annotation> qualifiers) throws InvalidSyntaxException {
+		String targetFilter = _reference.target();
+
+		int targetFilterLength = targetFilter.length();
+
+		if (targetFilterLength > 0) {
+			FrameworkUtil.createFilter(targetFilter);
+		}
+
+		StringBuilder sb = new StringBuilder();
+
+		sb.append("(&(");
+		sb.append(Constants.OBJECTCLASS);
+		sb.append("=");
+		sb.append(serviceType.getName());
+		sb.append(")");
+
+		// TODO add Bundle scope?
+
+		if (_reference.scope() == ReferenceScope.PROTOTYPE) {
+			sb.append("(");
+			sb.append(Constants.SERVICE_SCOPE);
+			sb.append("=");
+			sb.append(Constants.SCOPE_PROTOTYPE);
+			sb.append(")");
+		}
+		else if (_reference.scope() == ReferenceScope.SINGLETON) {
+			sb.append("(");
+			sb.append(Constants.SERVICE_SCOPE);
+			sb.append("=");
+			sb.append(Constants.SCOPE_SINGLETON);
+			sb.append(")");
+		}
+
+		if ((targetFilterLength > 0)) {
+			sb.append(targetFilter);
+		}
+
+		for (Annotation qualifier : qualifiers) {
+			if (qualifier.annotationType().isAnnotationPresent(ReferenceFilterQualifier.class)) {
+				Class<?> clazz = qualifier.annotationType();
+				try {
+					Method methodValue = clazz.getDeclaredMethod("value");
+					String value = String.valueOf(methodValue.invoke(qualifier));
+					append(sb, clazz.getSimpleName(), value);
+				}
+				catch (ReflectiveOperationException roe) {
+					Method[] methods = clazz.getDeclaredMethods();
+
+					for (Method method : methods) {
+						try {
+							String value = String.valueOf(method.invoke(qualifier));
+							append(sb, method.getName(), value);
+						} catch (ReflectiveOperationException roe2) {
+							if (_log.isDebugEnabled()) {
+								_log.debug("CDIe - Failure in reference filter qualifier processing", roe2);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		sb.append(")");
+
+		return sb.toString();
+	}
+
+	private void append(StringBuilder sb, String simpleName, String value) {
+		sb.append("(");
+		sb.append(Strings.camelCase(simpleName));
+		sb.append("=");
+		sb.append(value);
+		sb.append(")");
+	}
+
+	private BindType getBindType(Type type) {
+		if (type instanceof ParameterizedType) {
+			ParameterizedType parameterizedType = cast(type);
+
+			Type rawType = parameterizedType.getRawType();
+
+			if (Instance.class.isAssignableFrom(cast(rawType))) {
+				_instance = true;
+
+				Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+
+				return getBindType(actualTypeArguments[0]);
+			}
+			else if (Map.class.isAssignableFrom(cast(rawType))) {
+				Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+
+				Type first = actualTypeArguments[0];
+				Type second = actualTypeArguments[1];
+
+				if (!(first instanceof ParameterizedType) &&
+					String.class.isAssignableFrom(cast(first))) {
+
+					if ((!(second instanceof ParameterizedType) && (second == Object.class)) ||
+						(second instanceof WildcardType)) {
+
+						return BindType.SERVICE_PROPERTIES;
+					}
+				}
+
+				return BindType.SERVICE;
+			}
+			else if (ServiceReference.class.isAssignableFrom(cast(rawType))) {
+				return BindType.SERVICE_REFERENCE;
+			}
+
+			return BindType.SERVICE;
+		}
+		else if (ServiceReference.class.isAssignableFrom(cast(type))) {
+			return BindType.SERVICE_REFERENCE;
+		}
+
+		return BindType.SERVICE;
+	}
+
+	private int getMinCardinality(InjectionPoint injectionPoint) {
+		int value = 1;
+
+		if (_instance) {
+			MinCardinality minCardinality = injectionPoint.getAnnotated().getAnnotation(MinCardinality.class);
+
+			if ((minCardinality != null) && (minCardinality.value() >= 0)) {
+				value = minCardinality.value();
+			}
+		}
+
+		return value;
+	}
+
+	private Class<?> getServiceType() {
+		if (_reference.service() != Object.class) {
+			return _reference.service();
+		}
+
+		Type type = _injectionPoint.getType();
+
+		if (_bindType == BindType.SERVICE_PROPERTIES) {
+			throw new IllegalArgumentException(
+				"A @Reference cannot bind service properties to a Map<String, Object> without " +
+					"specifying the @Reference.service property: " + _injectionPoint);
+		}
+		else if ((_bindType == BindType.SERVICE_REFERENCE) && !(type instanceof ParameterizedType)) {
+			throw new IllegalArgumentException(
+				"A @Reference cannot bind a ServiceReference without specifying either the " +
+					"@Reference.service property or a generic type argument (e.g. ServiceReference<Foo>: " +
+						_injectionPoint);
+		}
+
+		if (!(type instanceof ParameterizedType)) {
+			return cast(type);
+		}
+
+		ParameterizedType parameterizedType = cast(type);
+
+		Type rawType = parameterizedType.getRawType();
+
+		if (Instance.class.isAssignableFrom(cast(rawType))) {
+			Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+
+			type = actualTypeArguments[0];
+
+			if (type instanceof ParameterizedType) {
+				parameterizedType = (ParameterizedType)type;
+
+				rawType = parameterizedType.getRawType();
+			}
+			else {
+				rawType = type;
+			}
+		}
+
+		if (!ServiceReference.class.isAssignableFrom(cast(rawType))) {
+			return cast(rawType);
+		}
+
+		Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+
+		Type first = actualTypeArguments[0];
+
+		if (first instanceof ParameterizedType) {
+			ParameterizedType parameterizedType1 = cast(first);
+
+			return cast(parameterizedType1.getRawType());
+		}
+
+		return cast(first);
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(ReferenceDependency.class);
+
+	private final BeanManagerImpl _beanManagerImpl;
+	private final BindType _bindType;
+	private final int _minCardinality;
+	private final Filter _filter;
+	private final InjectionPoint _injectionPoint;
+	private final Reference _reference;
+	private final Set<ServiceReference<?>> _matchingReferences = new ConcurrentSkipListSet<>(Comparator.reverseOrder());
+	private final Class<?> _serviceClass;
+	private final String _string;
+
+	private boolean _instance = false;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceExtension.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceExtension.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceExtension.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceExtension.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,94 @@
+/**
+ * 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.container;
+
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessInjectionPoint;
+
+import org.apache.aries.cdi.container.internal.bean.BundleContextBean;
+import org.jboss.weld.bean.builtin.BeanManagerProxy;
+import org.jboss.weld.manager.BeanManagerImpl;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cdi.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@ApplicationScoped
+public class ReferenceExtension implements Extension {
+
+	public ReferenceExtension(List<ReferenceDependency> referenceDependencies, BundleContext bundleContext) {
+		_referenceDependencies = referenceDependencies;
+		_bundleContext = bundleContext;
+	}
+
+	void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager manager) {
+		abd.addBean(new BundleContextBean(_bundleContext));
+
+		if (_log.isDebugEnabled()) {
+			_log.debug("CDIe - Bean discovery complete");
+		}
+	}
+
+	void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
+		if (_log.isDebugEnabled()) {
+			_log.debug("CDIe - Bean discovery started");
+		}
+	}
+
+	void processInjectionTarget(
+		@Observes @SuppressWarnings("rawtypes") ProcessInjectionPoint pip, BeanManager manager) {
+
+		InjectionPoint injectionPoint = pip.getInjectionPoint();
+		Annotated annotated = injectionPoint.getAnnotated();
+		Reference reference = annotated.getAnnotation(Reference.class);
+
+		if (reference == null) {
+			return;
+		}
+
+		try {
+			BeanManagerImpl beanManagerImpl = ((BeanManagerProxy)manager).delegate();
+
+			ReferenceDependency referenceDependency = new ReferenceDependency(
+				beanManagerImpl, reference, injectionPoint);
+
+			_referenceDependencies.add(referenceDependency);
+
+			if (_log.isDebugEnabled()) {
+				_log.debug("CDIe - Found OSGi service reference {}", referenceDependency);
+			}
+		}
+		catch (Exception e) {
+			if (_log.isErrorEnabled()) {
+				_log.error("CDIe - Error on reference {}", reference, e);
+			}
+		}
+	}
+
+	private static final Logger _log = LoggerFactory.getLogger(ReferenceExtension.class);
+
+	private final BundleContext _bundleContext;
+	private final List<ReferenceDependency> _referenceDependencies;
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceDeclaration.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceDeclaration.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceDeclaration.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceDeclaration.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,184 @@
+/**
+ * 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.container;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.inject.Singleton;
+
+import org.apache.aries.cdi.container.internal.util.Strings;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.PrototypeServiceFactory;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cdi.annotations.Service;
+import org.osgi.service.cdi.annotations.ServiceProperty;
+import org.osgi.service.cdi.annotations.ServicePropertyQualifier;
+import org.osgi.util.converter.Converter;
+import org.osgi.util.converter.StandardConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ServiceDeclaration {
+
+	@SuppressWarnings({ "rawtypes"})
+	public ServiceDeclaration(Service service, Bean bean, CreationalContext creationalContext) {
+		_service = service;
+		_bean = bean;
+		_creationalContext = creationalContext;
+
+		Dictionary<String, Object> properties = new Hashtable<>();
+
+		for (Object object : bean.getQualifiers()) {
+			Annotation qualifier = (Annotation)object;
+			if (qualifier.annotationType().isAnnotationPresent(ServicePropertyQualifier.class)) {
+				Class<?> clazz = qualifier.annotationType();
+				try {
+					Method methodValue = clazz.getDeclaredMethod("value");
+					put(properties, clazz.getSimpleName(), methodValue.invoke(qualifier));
+				}
+				catch (ReflectiveOperationException roe) {
+					Method[] methods = clazz.getDeclaredMethods();
+
+					for (Method method : methods) {
+						try {
+							put(properties, method.getName(), method.invoke(qualifier));
+						} catch (ReflectiveOperationException roe2) {
+							if (_log.isDebugEnabled()) {
+								_log.debug("CDIe - Failure in service property qualifier processing", roe2);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		for (ServiceProperty serviceProperty : _service.properties()) {
+			Type type = serviceProperty.type().getType();
+			String[] value = serviceProperty.value().split("\\s*,\\s*");
+
+			@SuppressWarnings("deprecation")
+			Object object = _converter.convert(value).to(type);
+
+			properties.put(serviceProperty.key(), object);
+		}
+
+		_properties = properties;
+	}
+
+	private void put(Dictionary<String, Object> properties, String simpleName, Object value) {
+		properties.put(Strings.camelCase(simpleName), value);
+	}
+
+	@SuppressWarnings("rawtypes")
+	public Bean getBean() {
+		return _bean;
+	}
+
+	public String[] getClassNames() {
+		List<String> classNames = new ArrayList<>();
+
+		Class<?>[] types = _service.type();
+
+		if (types.length > 0) {
+			for (Type type : types) {
+				classNames.add(type.getTypeName());
+			}
+		}
+		else {
+			types = _bean.getBeanClass().getInterfaces();
+
+			if (types.length > 0) {
+				for (Type type : types) {
+					classNames.add(type.getTypeName());
+				}
+			}
+			else {
+				classNames.add(_bean.getBeanClass().getName());
+			}
+		}
+
+		return classNames.toArray(new String[0]);
+	}
+
+	public Dictionary<String, Object> getProperties() {
+		return _properties;
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	public Object getServiceInstance() {
+		Class<?> scope = _bean.getScope();
+		if (Singleton.class.isAssignableFrom(scope)) {
+			return _bean.create(_creationalContext);
+		}
+		else if (ApplicationScoped.class.isAssignableFrom(scope)) {
+			return new BundleScopeWrapper();
+		}
+
+		return new PrototypeScopeWrapper();
+	}
+
+	@SuppressWarnings("deprecation")
+	private static final Converter _converter = new StandardConverter();
+
+	private static final Logger _log = LoggerFactory.getLogger(ServiceDeclaration.class);
+
+	@SuppressWarnings("rawtypes")
+	private final Bean _bean;
+	@SuppressWarnings("rawtypes")
+	private final CreationalContext _creationalContext;
+	private final Dictionary<String, Object> _properties;
+	private final Service _service;
+
+	@SuppressWarnings({"rawtypes", "unchecked"})
+	private class BundleScopeWrapper implements ServiceFactory {
+
+		@Override
+		public Object getService(Bundle bundle, ServiceRegistration registration) {
+			return _bean.create(_creationalContext);
+		}
+
+		@Override
+		public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+			_bean.destroy(service, _creationalContext);
+		}
+
+	}
+
+	@SuppressWarnings({"rawtypes", "unchecked"})
+	private class PrototypeScopeWrapper implements PrototypeServiceFactory {
+
+		@Override
+		public Object getService(Bundle bundle, ServiceRegistration registration) {
+			return _bean.create(_creationalContext);
+		}
+
+		@Override
+		public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+			_bean.destroy(service, _creationalContext);
+		}
+
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceExtension.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceExtension.java?rev=1780127&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceExtension.java (added)
+++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceExtension.java Wed Jan 25 00:08:04 2017
@@ -0,0 +1,51 @@
+/**
+ * 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.container;
+
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessBean;
+
+import org.osgi.service.cdi.annotations.Service;
+
+@ApplicationScoped
+public class ServiceExtension implements Extension {
+
+	public ServiceExtension(List<ServiceDeclaration> services) {
+		_services = services;
+	}
+
+	void processBean(@Observes ProcessBean<?> processBean, BeanManager beanManager) {
+		Service service = processBean.getAnnotated().getAnnotation(Service.class);
+
+		if (service == null) {
+			return;
+		}
+
+		Bean<?> bean = processBean.getBean();
+		CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
+
+		_services.add(new ServiceDeclaration(service, bean, creationalContext));
+	}
+
+	private final List<ServiceDeclaration> _services;
+
+}