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;
+
+}