Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationListener.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,310 @@ +/** + * 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.Arrays; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.aries.cdi.container.internal.container.Op.Mode; +import org.apache.aries.cdi.container.internal.container.Op.Type; +import org.apache.aries.cdi.container.internal.model.Component; +import org.apache.aries.cdi.container.internal.model.ExtendedComponentInstanceDTO; +import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationDTO; +import org.apache.aries.cdi.container.internal.util.Maps; +import org.apache.aries.cdi.container.internal.util.Predicates; +import org.apache.aries.cdi.container.internal.util.Throw; +import org.jboss.weld.exceptions.IllegalArgumentException; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.cdi.MaximumCardinality; +import org.osgi.service.cdi.runtime.dto.ComponentInstanceDTO; +import org.osgi.service.cdi.runtime.dto.template.ConfigurationTemplateDTO; +import org.osgi.service.cm.ConfigurationEvent; +import org.osgi.service.log.Logger; +import org.osgi.util.promise.Promise; + +public class ConfigurationListener extends Phase implements org.osgi.service.cm.ConfigurationListener { + + public static class Builder { + + public Builder(ContainerState containerState) { + _containerState = containerState; + } + + public Builder component(Component component) { + _component = component; + return this; + } + + public ConfigurationListener build() { + Objects.requireNonNull(_component); + return new ConfigurationListener(_containerState, _component); + } + + private Component _component; + private final ContainerState _containerState; + + } + + protected ConfigurationListener( + ContainerState containerState, + Component component) { + + super(containerState, component); + _component = component; + _log = containerState.containerLogs().getLogger(getClass()); + } + + @Override + public boolean close() { + if (_listenerService != null) { + _listenerService.unregister(); + _listenerService = null; + } + + return next.map( + next -> { + submit(next.closeOp(), next::close).onFailure( + f -> { + _log.error(l -> l.error("CCR Failure in configuration listener close on {}", next, f)); + + error(f); + } + ); + + return true; + } + ).orElse(true); + } + + @Override + public Op closeOp() { + return Op.of(Mode.CLOSE, Type.CONFIGURATION_LISTENER, _component.template().name); + } + + @Override + public void configurationEvent(ConfigurationEvent event) { + next.map(next -> (Component)next).ifPresent( + next -> next.configurationTemplates().stream().filter( + t -> Predicates.isMatchingConfiguration(event).test(t) + ).findFirst().ifPresent( + t -> { + String eventString = Arrays.asList(event.getPid(), event.getFactoryPid(), type(event)).toString(); + + Promise<Boolean> result = containerState.submit( + Op.of(Mode.OPEN, Type.CONFIGURATION_EVENT, eventString), + () -> { + _log.debug(l -> l.debug("CCR Event {} matched {} because of {}", eventString, _component.template().name, _component.template().configurations)); + processEvent(next, t, event); + return true; + } + ); + + try { + result.getValue(); + } + catch (Exception e) { + Throw.exception(e); + } + } + ) + ); + } + + @Override + public boolean open() { + Dictionary<String, Object> properties = new Hashtable<>(); + properties.put("name", toString()); + _listenerService = containerState.bundleContext().registerService( + org.osgi.service.cm.ConfigurationListener.class, this, properties); + + return next.map(next -> (Component)next).map( + component -> { + component.configurationTemplates().stream().filter( + ct -> Objects.nonNull(ct.pid) + ).forEach( + template -> { + if (template.maximumCardinality == MaximumCardinality.ONE) { + containerState.findConfig(template.pid).ifPresent( + c -> processEvent( + component, + template, + new ConfigurationEvent( + containerState.caTracker().getServiceReference(), + ConfigurationEvent.CM_UPDATED, + null, + c.getPid())) + ); + } + else { + containerState.findConfigs(template.pid, true).ifPresent( + arr -> Arrays.stream(arr).forEach( + c -> processEvent( + component, + template, + new ConfigurationEvent( + containerState.caTracker().getServiceReference(), + ConfigurationEvent.CM_UPDATED, + c.getFactoryPid(), + c.getPid()))) + ); + } + } + ); + + submit(component.openOp(), component::open).onFailure( + f -> { + _log.error(l -> l.error("CCR Failure during configuration start on {}", next, f)); + + error(f); + } + ); + + return true; + } + ).orElse(true); + } + + @Override + public Op openOp() { + return Op.of(Mode.OPEN, Type.CONFIGURATION_LISTENER, _component.template().name); + } + + @Override + public String toString() { + return Arrays.asList(getClass().getSimpleName(), _component).toString(); + } + + private void processEvent(Component component, ConfigurationTemplateDTO t, ConfigurationEvent event) { + final AtomicBoolean needToRefresh = new AtomicBoolean(false); + + List<ComponentInstanceDTO> instances = component.instances(); + + instances.stream().forEach( + instance -> instance.configurations.stream().filter( + c -> c.template.equals(t) + ).map(ExtendedConfigurationDTO.class::cast).filter( + c -> c.pid.equals(event.getPid()) + ).forEach( + c -> { + instance.configurations.remove(c); + needToRefresh.set(true); + } + ) + ); + + switch (event.getType()) { + case ConfigurationEvent.CM_DELETED: + if (t.maximumCardinality == MaximumCardinality.MANY) { + instances.stream().map( + instance -> (ExtendedComponentInstanceDTO)instance + ).filter( + instance -> event.getPid().equals(instance.pid) + ).forEach( + instance -> { + if (instances.remove(instance)) { + submit(instance.closeOp(), instance::close).onFailure( + f -> { + _log.error(l -> l.error("CCR Error closing {} on {}", instance.ident(), bundle())); + } + ); + } + } + ); + } + break; + case ConfigurationEvent.CM_LOCATION_CHANGED: + case ConfigurationEvent.CM_UPDATED: + if ((t.maximumCardinality == MaximumCardinality.MANY) && + !instances.stream().map( + instance -> (ExtendedComponentInstanceDTO)instance + ).filter( + instance -> event.getPid().equals(instance.pid) + ).findFirst().isPresent()) { + + ExtendedComponentInstanceDTO instanceDTO = new ExtendedComponentInstanceDTO( + containerState, _component.activatorBuilder()); + instanceDTO.activations = new CopyOnWriteArrayList<>(); + instanceDTO.configurations = new CopyOnWriteArrayList<>(); + instanceDTO.pid = event.getPid(); + instanceDTO.properties = null; + instanceDTO.references = new CopyOnWriteArrayList<>(); + instanceDTO.template = component.template(); + + instances.add(instanceDTO); + } + + containerState.findConfig(event.getPid()).ifPresent( + configuration -> { + ExtendedConfigurationDTO configurationDTO2 = new ExtendedConfigurationDTO(); + + configurationDTO2.configuration = configuration; + configurationDTO2.pid = event.getPid(); + configurationDTO2.properties = Maps.of(configuration.getProcessedProperties(event.getReference())); + configurationDTO2.template = t; + + instances.stream().forEach( + instance -> { + instance.configurations.add(configurationDTO2); + needToRefresh.set(true); + } + ); + } + ); + break; + } + + if (needToRefresh.get()) { + startComponent(component); + } + } + + private String type(ConfigurationEvent event) { + if (event.getType() == ConfigurationEvent.CM_DELETED) + return "DELETED"; + if (event.getType() == ConfigurationEvent.CM_LOCATION_CHANGED) + return "LOCATION_CHANGED"; + if (event.getType() == ConfigurationEvent.CM_UPDATED) + return "UPDATED"; + throw new IllegalArgumentException("CM Event type " + event.getType()); + } + + private void startComponent(Component component) { + submit(component.closeOp(), component::close).then( + s -> submit(component.openOp(), component::open).onFailure( + f -> { + _log.error(l -> l.error("CCR Error in configuration listener start on {}", component, f)); + + error(f); + } + ), + f -> { + _log.error(l -> l.error("CCR Error in configuration listener close on {}", component, f.getFailure())); + + error(f.getFailure()); + } + ); + } + + private volatile ServiceRegistration<org.osgi.service.cm.ConfigurationListener> _listenerService; + + private final Component _component; + private final Logger _log; + +} \ No newline at end of file
Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java?rev=1829115&r1=1829114&r2=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerBootstrap.java Sat Apr 14 01:10:27 2018 @@ -14,88 +14,128 @@ package org.apache.aries.cdi.container.internal.container; -import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; -import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; -import org.apache.aries.cdi.container.internal.context.BundleContextExtension; -import org.apache.aries.cdi.container.internal.extension.ExtensionMetadata; -import org.apache.aries.cdi.container.internal.model.BeansModel; +import org.apache.aries.cdi.container.internal.container.Op.Mode; +import org.apache.aries.cdi.container.internal.container.Op.Type; +import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO; +import org.apache.aries.cdi.container.internal.model.FactoryComponent; +import org.apache.aries.cdi.container.internal.model.SingleComponent; +import org.apache.aries.cdi.container.internal.util.Syncro; import org.jboss.weld.bootstrap.WeldBootstrap; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; import org.jboss.weld.bootstrap.spi.Deployment; import org.jboss.weld.bootstrap.spi.Metadata; import org.jboss.weld.util.ServiceLoader; +import org.osgi.service.log.Logger; -public class ContainerBootstrap { +public class ContainerBootstrap extends Phase { public ContainerBootstrap( ContainerState containerState, - Collection<Metadata<Extension>> externalExtensions) { - - _containerState = containerState; - _externalExtensions = externalExtensions; - - BeansModel beansModel = _containerState.beansModel(); + ConfigurationListener.Builder configurationBuilder, + SingleComponent.Builder singleBuilder, + FactoryComponent.Builder factoryBuilder) { + + super(containerState, null); + + _configurationBuilder = configurationBuilder; + _singleBuilder = singleBuilder; + _factoryBuilder = factoryBuilder; + _log = containerState.containerLogs().getLogger(getClass()); + } - List<Metadata<Extension>> extensions = new CopyOnWriteArrayList<>(); + @Override + public boolean close() { + try (Syncro syncro = _lock.open()) { + if (_bootstrap != null) { + _log.debug(l -> l.debug("CCR container bootstrap shutdown on {}", _bootstrap)); + _bootstrap.shutdown(); + _bootstrap = null; + } - // Add the internal extensions - extensions.add( - new ExtensionMetadata( - new BundleContextExtension(_containerState.bundleContext()), - _containerState.id())); -// extensions.add( -// new ExtensionMetadata( -// new ComponentRuntimeExtension(_containerState), -// _containerState.id())); - - // Add extensions found from the bundle's classloader, such as those in the Bundle-ClassPath - for (Metadata<Extension> meta : ServiceLoader.load(Extension.class, _containerState.classLoader())) { - extensions.add(meta); + return true; } + catch (Throwable t) { + _log.error(l -> l.error("CCR Failure in container bootstrap shutdown on {}", _bootstrap, t)); - // Add external extensions - for (Metadata<Extension> meta : _externalExtensions) { - extensions.add(meta); + return false; } - - BeanDeploymentArchive beanDeploymentArchive = new ContainerDeploymentArchive( - _containerState.loader(), _containerState.id(), beansModel.getBeanClassNames(), - beansModel.getBeansXml()); - - Deployment deployment = new ContainerDeployment(extensions, beanDeploymentArchive); - - _bootstrap = new WeldBootstrap(); - - _bootstrap.startExtensions(extensions); - _bootstrap.startContainer(_containerState.id(), new ContainerEnvironment(), deployment); - - _beanManager = _bootstrap.getManager(beanDeploymentArchive); -// _containerState.setBeanManager(_beanManager); - - _bootstrap.startInitialization(); - _bootstrap.deployBeans(); } - public BeanManager getBeanManager() { - return _beanManager; + @Override + public Op closeOp() { + return Op.of(Mode.CLOSE, Type.CONTAINER_BOOTSTRAP, containerState.id()); } - public WeldBootstrap getBootstrap() { - return _bootstrap; + @Override + public boolean open() { + try (Syncro syncro = _lock.open()) { + if (_bootstrap != null) { + return true; + } + + List<Metadata<Extension>> extensions = new CopyOnWriteArrayList<>(); + + // Add the internal extensions + extensions.add( + new ExtensionMetadata( + new BundleContextExtension(containerState.bundleContext()), + containerState.id())); + extensions.add( + new ExtensionMetadata( + new RuntimeExtension(containerState, _configurationBuilder, _singleBuilder, _factoryBuilder), + containerState.id())); + extensions.add( + new ExtensionMetadata( + new LoggerExtension(containerState), + containerState.id())); + + // Add extensions found from the bundle's class loader, such as those in the Bundle-ClassPath + ServiceLoader.load(Extension.class, containerState.classLoader()).forEach(extensions::add); + + // Add external extensions + containerState.containerDTO().extensions.stream().map( + ExtendedExtensionDTO.class::cast + ).map( + e -> new ExtensionMetadata(e.extension.getService(), e.template.serviceFilter) + ).forEach(extensions::add); + + _bootstrap = new WeldBootstrap(); + + BeanDeploymentArchive beanDeploymentArchive = new ContainerDeploymentArchive( + containerState.loader(), + containerState.id(), + containerState.beansModel().getBeanClassNames(), + containerState.beansModel().getBeansXml()); + + Deployment deployment = new ContainerDeployment(extensions, beanDeploymentArchive); + + _bootstrap.startExtensions(extensions); + _bootstrap.startContainer(containerState.id(), new ContainerEnvironment(), deployment); + _bootstrap.startInitialization(); + _bootstrap.deployBeans(); + _bootstrap.validateBeans(); + _bootstrap.endInitialization(); + + return true; + } } - public void shutdown() { - _bootstrap.shutdown(); + @Override + public Op openOp() { + return Op.of(Mode.OPEN, Type.CONTAINER_BOOTSTRAP, containerState.id()); } - private final BeanManager _beanManager; - private final WeldBootstrap _bootstrap; - private final ContainerState _containerState; - private final Collection<Metadata<Extension>> _externalExtensions; + + private volatile WeldBootstrap _bootstrap; + private final ConfigurationListener.Builder _configurationBuilder; + private final FactoryComponent.Builder _factoryBuilder; + private final SingleComponent.Builder _singleBuilder; + private final Syncro _lock = new Syncro(true); + private final Logger _log; } \ No newline at end of file Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java?rev=1829115&r1=1829114&r2=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDeploymentArchive.java Sat Apr 14 01:10:27 2018 @@ -33,9 +33,7 @@ public class ContainerDeploymentArchive _id = id; _beanClassNames = beanClassNames; - _beanDeploymentArchives = Collections.emptyList(); _beansXml = beansXml; - _ejbs = Collections.emptyList(); _services = new SimpleServiceRegistry(); if (loader != null) { @@ -51,7 +49,7 @@ public class ContainerDeploymentArchive @Override public Collection<BeanDeploymentArchive> getBeanDeploymentArchives() { - return _beanDeploymentArchives; + return Collections.emptyList(); } @Override @@ -61,7 +59,7 @@ public class ContainerDeploymentArchive @Override public Collection<EjbDescriptor<?>> getEjbs() { - return _ejbs; + return Collections.emptyList(); } @Override @@ -75,9 +73,7 @@ public class ContainerDeploymentArchive } 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; Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java?rev=1829115&r1=1829114&r2=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerDiscovery.java Sat Apr 14 01:10:27 2018 @@ -17,13 +17,9 @@ package org.apache.aries.cdi.container.i import java.util.Collections; import java.util.List; -import javax.enterprise.inject.spi.DefinitionException; import javax.enterprise.inject.spi.Extension; -import org.apache.aries.cdi.container.internal.component.DiscoveryExtension; -import org.apache.aries.cdi.container.internal.extension.ExtensionMetadata; import org.apache.aries.cdi.container.internal.model.BeansModel; -import org.apache.aries.cdi.container.internal.v2.component.ContainerComponent; import org.jboss.weld.bootstrap.WeldBootstrap; import org.jboss.weld.bootstrap.spi.BeanDeploymentArchive; import org.jboss.weld.bootstrap.spi.Deployment; @@ -31,7 +27,7 @@ import org.jboss.weld.bootstrap.spi.Meta public class ContainerDiscovery { - public static void discover(ContainerState containerState) { + public ContainerDiscovery(ContainerState containerState) { String id = containerState.id() + "-discovery"; BeansModel beansModel = containerState.beansModel(); @@ -40,10 +36,8 @@ public class ContainerDiscovery { containerState.loader(), id, beansModel.getBeanClassNames(), beansModel.getBeansXml()); - ContainerComponent containerComponent = new ContainerComponent(id); - ExtensionMetadata extension = new ExtensionMetadata( - new DiscoveryExtension(beansModel, containerComponent), id); + new DiscoveryExtension(containerState), id); List<Metadata<Extension>> extensions = Collections.singletonList(extension); @@ -52,31 +46,11 @@ public class ContainerDiscovery { WeldBootstrap _bootstrap = new WeldBootstrap(); - try { - _bootstrap.startExtensions(extensions); - _bootstrap.startContainer(id, new ContainerEnvironment(), deployment); - _bootstrap.startInitialization(); - _bootstrap.deployBeans(); - _bootstrap.shutdown(); - } - catch (DefinitionException de) { - throw de; - } - - validate(containerState); - } - - private static void validate(ContainerState containerState) { - containerState.beansModel().getOSGiBeans().stream().forEach( - osgiBean -> { - if (!osgiBean.found()) { - throw new DefinitionException( - String.format( - "Did not find bean for <component> description %s", - osgiBean)); - } - } - ); + _bootstrap.startExtensions(extensions); + _bootstrap.startContainer(id, new ContainerEnvironment(), deployment); + _bootstrap.startInitialization(); + _bootstrap.deployBeans(); + _bootstrap.shutdown(); } } \ No newline at end of file Modified: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java?rev=1829115&r1=1829114&r2=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ContainerState.java Sat Apr 14 01:10:27 2018 @@ -14,42 +14,58 @@ package org.apache.aries.cdi.container.internal.container; -import java.util.Dictionary; +import static org.apache.aries.cdi.container.internal.util.Filters.*; +import static org.osgi.namespace.extender.ExtenderNamespace.*; +import static org.osgi.service.cdi.CDIConstants.*; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; +import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; import javax.enterprise.inject.Any; import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.ObserverMethod; import javax.enterprise.util.AnnotationLiteral; -import org.apache.aries.cdi.container.internal.component.OSGiBean; -import org.apache.aries.cdi.container.internal.configuration.ConfigurationCallback; -import org.apache.aries.cdi.container.internal.extension.ExtensionDependency; +import org.apache.aries.cdi.container.internal.ChangeCount; import org.apache.aries.cdi.container.internal.loader.BundleClassLoader; import org.apache.aries.cdi.container.internal.loader.BundleResourcesLoader; import org.apache.aries.cdi.container.internal.model.BeansModel; -import org.apache.aries.cdi.container.internal.model.Context; -import org.apache.aries.cdi.container.internal.model.Registrator; -import org.apache.aries.cdi.container.internal.model.Tracker; -import org.apache.aries.cdi.container.internal.reference.ReferenceCallback; -import org.apache.aries.cdi.container.internal.service.ServiceDeclaration; +import org.apache.aries.cdi.container.internal.model.BeansModelBuilder; +import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO; +import org.apache.aries.cdi.container.internal.model.ExtendedExtensionTemplateDTO; +import org.apache.aries.cdi.container.internal.util.Logs; +import org.apache.aries.cdi.container.internal.util.Throw; import org.jboss.weld.resources.spi.ResourceLoader; import org.jboss.weld.serialization.spi.ProxyServices; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; -import org.osgi.framework.Filter; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceObjects; -import org.osgi.framework.ServiceReference; +import org.osgi.framework.dto.BundleDTO; +import org.osgi.framework.namespace.PackageNamespace; +import org.osgi.framework.wiring.BundleCapability; +import org.osgi.framework.wiring.BundleRequirement; +import org.osgi.framework.wiring.BundleWire; import org.osgi.framework.wiring.BundleWiring; -import org.osgi.service.cdi.reference.ReferenceEvent; -import org.osgi.service.cm.ManagedService; +import org.osgi.service.cdi.ComponentType; +import org.osgi.service.cdi.ConfigurationPolicy; +import org.osgi.service.cdi.MaximumCardinality; +import org.osgi.service.cdi.runtime.dto.ContainerDTO; +import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO; +import org.osgi.service.cdi.runtime.dto.template.ContainerTemplateDTO; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.log.Logger; +import org.osgi.util.promise.Deferred; +import org.osgi.util.promise.Promise; +import org.osgi.util.promise.PromiseFactory; import org.osgi.util.tracker.ServiceTracker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class ContainerState { @@ -57,86 +73,131 @@ public class ContainerState { private static final long serialVersionUID = 1L; }; + @SuppressWarnings("unchecked") public ContainerState( - Bundle bundle, Bundle extenderBundle) { + Bundle bundle, + Bundle extenderBundle, + ChangeCount ccrChangeCount, + PromiseFactory promiseFactory, + ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker, + Logs ccrLogs) { - _bundle = Optional.ofNullable(bundle); + _bundle = bundle; _extenderBundle = extenderBundle; + _ccrLogs = ccrLogs; + _log = _ccrLogs.getLogger(getClass()); + _containerLogs = new Logs.Builder(_bundle.getBundleContext()).build(); - _bundle.ifPresent( - b -> { - _classLoader = new BundleClassLoader( - BundleResourcesLoader.getBundles(bundle, extenderBundle)); - } - ); + _changeCount = new ChangeCount(); + _changeCount.addObserver(ccrChangeCount); - _context = new Context() { + _promiseFactory = promiseFactory; + _caTracker = caTracker; - @Override - public <T> T getService(ServiceReference<T> reference) { - return bundleContext().getService(reference); - } + BundleWiring bundleWiring = _bundle.adapt(BundleWiring.class); - @Override - public <T> ServiceObjects<T> getServiceObjects(ServiceReference<T> reference) { - return bundleContext().getServiceObjects(reference); - } - - @Override - public <T> boolean ungetService(ServiceReference<T> reference) { - return bundleContext().ungetService(reference); - } + List<BundleWire> wires = bundleWiring.getRequiredWires(EXTENDER_NAMESPACE); - }; + Map<String, Object> cdiAttributes = Collections.emptyMap(); - _msRegistrator = new Registrator<ManagedService>() { + for (BundleWire wire : wires) { + BundleCapability capability = wire.getCapability(); + Map<String, Object> attributes = capability.getAttributes(); + String extender = (String)attributes.get(EXTENDER_NAMESPACE); - @Override - public void registerService(String[] classNames, ManagedService service, Dictionary<String, ?> properties) { - registrations.add(bundleContext().registerService(ManagedService.class, service, properties)); + if (extender.equals(CDI_CAPABILITY_NAME)) { + BundleRequirement requirement = wire.getRequirement(); + cdiAttributes = requirement.getAttributes(); + break; } + } - }; + _containerDTO = new ContainerDTO(); + _containerDTO.bundle = _bundle.adapt(BundleDTO.class); + _containerDTO.changeCount = _changeCount.get(); + _containerDTO.components = new CopyOnWriteArrayList<>(); + _containerDTO.errors = new CopyOnWriteArrayList<>(); + _containerDTO.extensions = new CopyOnWriteArrayList<>(); + _containerDTO.template = new ContainerTemplateDTO(); + _containerDTO.template.components = new CopyOnWriteArrayList<>(); + _containerDTO.template.extensions = new CopyOnWriteArrayList<>(); + _containerDTO.template.id = Optional.ofNullable( + (String)cdiAttributes.get(CDI_CONTAINER_ID) + ).orElse( + _bundle.getSymbolicName() + ); - _bmRegistrator = new Registrator<BeanManager>() { + Optional.ofNullable( + (List<String>)cdiAttributes.get(REQUIREMENT_EXTENSIONS_ATTRIBUTE) + ).ifPresent( + list -> list.stream().forEach( + extensionFilter -> { + ExtendedExtensionTemplateDTO extensionTemplateDTO = new ExtendedExtensionTemplateDTO(); + + try { + extensionTemplateDTO.filter = asFilter(extensionFilter); + extensionTemplateDTO.serviceFilter = extensionFilter; - @Override - public void registerService(String[] classNames, BeanManager service, Dictionary<String, ?> properties) { - registrations.add(bundleContext().registerService(BeanManager.class, service, properties)); - } + _containerDTO.template.extensions.add(extensionTemplateDTO); + } + catch (Exception e) { + _containerDTO.errors.add(Throw.asString(e)); + } + } + ) + ); + + _containerComponentTemplateDTO = new ComponentTemplateDTO(); + _containerComponentTemplateDTO.activations = new CopyOnWriteArrayList<>(); + _containerComponentTemplateDTO.beans = new CopyOnWriteArrayList<>(); + _containerComponentTemplateDTO.configurations = new CopyOnWriteArrayList<>(); + _containerComponentTemplateDTO.name = _containerDTO.template.id; + _containerComponentTemplateDTO.properties = Collections.emptyMap(); + _containerComponentTemplateDTO.references = new CopyOnWriteArrayList<>(); + _containerComponentTemplateDTO.type = ComponentType.CONTAINER; + + ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO(); + configurationTemplate.componentConfiguration = true; + configurationTemplate.maximumCardinality = MaximumCardinality.ONE; + configurationTemplate.pid = Optional.ofNullable( + (String)cdiAttributes.get(CDI_CONTAINER_ID) + ).orElse( + "osgi.cdi." + _bundle.getSymbolicName() + ); + configurationTemplate.policy = ConfigurationPolicy.OPTIONAL; - }; + _containerComponentTemplateDTO.configurations.add(configurationTemplate); - _serviceRegistrator = new Registrator<Object>() { + _containerDTO.template.components.add(_containerComponentTemplateDTO); - @Override - public void registerService(String[] classNames, Object service, Dictionary<String, ?> properties) { - registrations.add(bundleContext().registerService(classNames, service, properties)); - } + _aggregateClassLoader = new BundleClassLoader(getBundles(_bundle, _extenderBundle)); - }; + _beansModel = new BeansModelBuilder(this, _aggregateClassLoader, bundleWiring, cdiAttributes).build(); - _tracker = new Tracker() { + _bundleClassLoader = bundleWiring.getClassLoader(); - @Override - public <T> void track(String targetFilter, ReferenceCallback callback) { - try { - Filter filter = bundleContext().createFilter(targetFilter); + try { + new ContainerDiscovery(this); + } + catch (Exception e) { + _log.error(l -> l.error("CCR Discovery resulted in errors on {}", bundle, e)); - trackers.add(new ServiceTracker<>(bundleContext(), filter, callback)); - } - catch (InvalidSyntaxException ise) { - if (_log.isErrorEnabled()) { - _log.error("CDIe - Invalid filter syntax in {}", targetFilter, ise); - } - } - } + _containerDTO.errors.add(Throw.asString(e)); + } + } - }; + public <T, R> Promise<R> addCallback(CheckedCallback<T, R> checkedCallback) { + Deferred<R> deferred = _promiseFactory.deferred(); + _callbacks.put(checkedCallback, deferred); + return deferred.getPromise(); } - public Registrator<BeanManager> beanManagerRegistrator() { - return _bmRegistrator; + public BeanManager beanManager() { + return _beanManager; + } + + public void beanManager(BeanManager beanManager) { + _beanManager = beanManager; } public BeansModel beansModel() { @@ -144,93 +205,186 @@ public class ContainerState { } public Bundle bundle() { - return _bundle.orElse(null); + return _bundle; } public ClassLoader bundleClassLoader() { - return _bundle.map(b -> b.adapt(BundleWiring.class).getClassLoader()).orElse(getClass().getClassLoader()); + return _bundleClassLoader; } public BundleContext bundleContext() { - return _bundle.map(b -> b.getBundleContext()).orElse(null); + return _bundle.getBundleContext(); + } + + public ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker() { + return _caTracker; + } + + public Logs ccrLogs() { + return _ccrLogs; } public ClassLoader classLoader() { - return _bundle.map(b -> _classLoader).orElse(getClass().getClassLoader()); + return _aggregateClassLoader; } - public Map<OSGiBean, Map<String, ConfigurationCallback>> configurationCallbacks() { - return _configurationCallbacksMap; + public void closing() { + try { + _closing.set(_promiseFactory.submit(() -> Boolean.TRUE).getValue()); + } catch (InvocationTargetException | InterruptedException e) { + e.printStackTrace(); + } } - public Context context() { - return _context; + public ComponentContext componentContext() { + return _componentContext; } - public Bundle extenderBundle() { - return _extenderBundle; + public ComponentTemplateDTO containerComponentTemplateDTO() { + return _containerComponentTemplateDTO; } - public List<ExtensionDependency> extensionDependencies() { - return _extensionDependencies; + public ContainerDTO containerDTO() { + _containerDTO.changeCount = _changeCount.get(); + return _containerDTO; } - public String id() { - return _bundle.map(b -> b.getSymbolicName() + ":" + b.getBundleId()).orElse("null"); + public Logs containerLogs() { + return _containerLogs; } - @SuppressWarnings("unchecked") - public <T extends ResourceLoader & ProxyServices> T loader() { - return (T)_bundle.map(b -> new BundleResourcesLoader(b, _extenderBundle)).orElse(null); + public void error(Throwable t) { + containerDTO().errors.add(Throw.asString(t)); } - public Registrator<ManagedService> managedServiceRegistrator() { - return _msRegistrator; + public Bundle extenderBundle() { + return _extenderBundle; } - public Map<OSGiBean, Map<String, ReferenceCallback>> referenceCallbacks() { - return _referenceCallbacksMap; + public Optional<Configuration> findConfig(String pid) { + return findConfigs(pid, false).map(arr -> arr[0]); } - public Map<OSGiBean, Map<String, ObserverMethod<ReferenceEvent<?>>>> referenceObservers() { - return _referenceObserversMap; + public Optional<Configuration[]> findConfigs(String pid, boolean factory) { + try { + String query = "(service.pid=".concat(pid).concat(")"); + + if (factory) { + query = "(factory.pid=".concat(pid).concat(")"); + } + + return Optional.ofNullable( + _caTracker.getService().listConfigurations(query) + ); + } + catch (Exception e) { + _log.error(l -> l.error("CCR unexpected failure fetching configuration for {}", pid, e)); + + return Throw.exception(e); + } } - public Map<OSGiBean, ServiceDeclaration> serviceComponents() { - return _serviceComponents; + public String id() { + return _containerDTO.template.id; } - public Registrator<Object> serviceRegistrator() { - return _serviceRegistrator; + public void incrementChangeCount() { + _changeCount.incrementAndGet(); } - public void setBeansModel(BeansModel beansModel) { - _beansModel = beansModel; + @SuppressWarnings("unchecked") + public <T extends ResourceLoader & ProxyServices> T loader() { + return (T)new BundleResourcesLoader(_bundle, _extenderBundle); } - public void setExtensionDependencies(List<ExtensionDependency> extensionDependencies) { - _extensionDependencies = extensionDependencies; + public PromiseFactory promiseFactory() { + return _promiseFactory; } - public Tracker tracker() { - return _tracker; + @SuppressWarnings("unchecked") + public <T, R> Promise<T> submit(Op op, Callable<T> task) { + try { + switch (op.mode) { + case CLOSE: { + // always perform close synchronously + _log.debug(l -> l.debug("CCR submit {}", op)); + return _promiseFactory.resolved(task.call()); + } + case OPEN: + // when closing don't do perform any opens + // also, don't log it since it's just going to be noise + if (_closing.get()) { + return _promiseFactory.resolved((T)new Object()); + } + } + } + catch (Exception e) { + return _promiseFactory.failed(e); + } + + _log.debug(l -> l.debug("CCR submit {}", op)); + + Promise<T> promise = _promiseFactory.submit(task); + + for (Entry<CheckedCallback<?, ?>, Deferred<?>> entry : _callbacks.entrySet()) { + CheckedCallback<T, R> cc = (CheckedCallback<T, R>)entry.getKey(); + if (cc.test(op)) { + ((Deferred<R>)entry.getValue()).resolveWith(promise.then(cc, cc)).then( + s -> { + _callbacks.remove(cc); + return s; + }, + f -> _callbacks.remove(cc) + ); + } + } + + return promise; } - private static final Logger _log = LoggerFactory.getLogger(ContainerState.class); + private static Bundle[] getBundles(Bundle bundle, Bundle extenderBundle) { + List<Bundle> bundles = new ArrayList<>(); + + bundles.add(bundle); + bundles.add(extenderBundle); + + BundleWiring extenderWiring = extenderBundle.adapt(BundleWiring.class); + + List<BundleWire> requiredWires = extenderWiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE); + + for (BundleWire bundleWire : requiredWires) { + BundleCapability capability = bundleWire.getCapability(); + Map<String, Object> attributes = capability.getAttributes(); + String packageName = (String)attributes.get(PackageNamespace.PACKAGE_NAMESPACE); + if (!packageName.startsWith("org.jboss.weld.")) { + continue; + } + + Bundle wireBundle = bundleWire.getProvider().getBundle(); + if (!bundles.contains(wireBundle)) { + bundles.add(wireBundle); + } + } + + return bundles.toArray(new Bundle[0]); + } - private BeansModel _beansModel; - private final Registrator<BeanManager> _bmRegistrator; - private final Optional<Bundle> _bundle; - private ClassLoader _classLoader; - private final Map<OSGiBean, Map<String, ConfigurationCallback>> _configurationCallbacksMap = new ConcurrentHashMap<>(); - private final Context _context; + private final ClassLoader _aggregateClassLoader; + private volatile BeanManager _beanManager; + private final BeansModel _beansModel; + private final Bundle _bundle; + private final ClassLoader _bundleClassLoader; + private final Map<CheckedCallback<?, ?>, Deferred<?>> _callbacks = new ConcurrentHashMap<>(); + private final ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> _caTracker; + private final Logger _log; + private final Logs _ccrLogs; + private final ChangeCount _changeCount; + private final AtomicBoolean _closing = new AtomicBoolean(false); + private final ComponentContext _componentContext = new ComponentContext(); + private final ContainerDTO _containerDTO; + private final Logs _containerLogs; + private final ComponentTemplateDTO _containerComponentTemplateDTO; private final Bundle _extenderBundle; - private List<ExtensionDependency> _extensionDependencies; - private final Registrator<ManagedService> _msRegistrator; - private final Map<OSGiBean, Map<String, ReferenceCallback>> _referenceCallbacksMap = new ConcurrentHashMap<>(); - private final Map<OSGiBean, Map<String, ObserverMethod<ReferenceEvent<?>>>> _referenceObserversMap = new ConcurrentHashMap<>(); - private final Map<OSGiBean, ServiceDeclaration> _serviceComponents = new ConcurrentHashMap<>(); - private final Registrator<Object> _serviceRegistrator; - private final Tracker _tracker; + private final PromiseFactory _promiseFactory; } \ No newline at end of file Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/DiscoveryExtension.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,596 @@ +/** + * 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.Executable; +import java.lang.reflect.Parameter; +import java.util.AbstractMap.SimpleEntry; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Dependent; +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.Annotated; +import javax.enterprise.inject.spi.AnnotatedField; +import javax.enterprise.inject.spi.AnnotatedMethod; +import javax.enterprise.inject.spi.AnnotatedParameter; +import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.DefinitionException; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.inject.spi.ObserverMethod; +import javax.enterprise.inject.spi.ProcessAnnotatedType; +import javax.enterprise.inject.spi.ProcessBean; +import javax.enterprise.inject.spi.ProcessInjectionPoint; +import javax.enterprise.inject.spi.ProcessManagedBean; +import javax.enterprise.inject.spi.ProcessObserverMethod; +import javax.enterprise.inject.spi.ProcessProducerField; +import javax.enterprise.inject.spi.ProcessProducerMethod; +import javax.enterprise.inject.spi.ProcessSessionBean; +import javax.enterprise.inject.spi.ProcessSyntheticBean; + +import org.apache.aries.cdi.container.internal.model.BeansModel; +import org.apache.aries.cdi.container.internal.model.ConfigurationModel; +import org.apache.aries.cdi.container.internal.model.ExtendedActivationTemplateDTO; +import org.apache.aries.cdi.container.internal.model.ExtendedComponentTemplateDTO; +import org.apache.aries.cdi.container.internal.model.ExtendedConfigurationTemplateDTO; +import org.apache.aries.cdi.container.internal.model.OSGiBean; +import org.apache.aries.cdi.container.internal.model.ReferenceModel; +import org.apache.aries.cdi.container.internal.model.ReferenceModel.Builder; +import org.apache.aries.cdi.container.internal.util.Maps; +import org.apache.aries.cdi.container.internal.util.Types; +import org.osgi.service.cdi.ComponentType; +import org.osgi.service.cdi.ConfigurationPolicy; +import org.osgi.service.cdi.MaximumCardinality; +import org.osgi.service.cdi.ServiceScope; +import org.osgi.service.cdi.annotations.Bundle; +import org.osgi.service.cdi.annotations.ComponentScoped; +import org.osgi.service.cdi.annotations.Configuration; +import org.osgi.service.cdi.annotations.FactoryComponent; +import org.osgi.service.cdi.annotations.PID; +import org.osgi.service.cdi.annotations.Prototype; +import org.osgi.service.cdi.annotations.Reference; +import org.osgi.service.cdi.annotations.SingleComponent; +import org.osgi.service.cdi.reference.ReferenceEvent; +import org.osgi.service.cdi.runtime.dto.template.ComponentTemplateDTO; + +public class DiscoveryExtension implements Extension { + + public DiscoveryExtension(ContainerState containerState) { + _containerState = containerState; + _beansModel = _containerState.beansModel(); + _containerTemplate = _containerState.containerDTO().template.components.get(0); + } + + static Entry<Class<?>, Annotated> getBeanClassAndAnnotated(ProcessBean<?> pb) { + Annotated annotated = null; + Class<?> annotatedClass = null; + + if (pb instanceof ProcessManagedBean) { + ProcessManagedBean<?> bean = (ProcessManagedBean<?>)pb; + + annotated = bean.getAnnotated(); + annotatedClass = bean.getAnnotatedBeanClass().getJavaClass(); + } + else if (pb instanceof ProcessSessionBean) { + ProcessSessionBean<?> bean = (ProcessSessionBean<?>)pb; + + annotated = bean.getAnnotated(); + annotatedClass = bean.getAnnotatedBeanClass().getJavaClass(); + } + else if (pb instanceof ProcessProducerMethod) { + ProcessProducerMethod<?, ?> producer = (ProcessProducerMethod<?, ?>)pb; + + annotated = producer.getAnnotated(); + annotatedClass = producer.getAnnotatedProducerMethod().getDeclaringType().getJavaClass(); + } + else if (pb instanceof ProcessProducerField) { + ProcessProducerField<?, ?> producer = (ProcessProducerField<?, ?>)pb; + + annotated = producer.getAnnotated(); + annotatedClass = producer.getAnnotatedProducerField().getDeclaringType().getJavaClass(); + } + else if (pb instanceof ProcessSyntheticBean) { + ProcessSyntheticBean<?> synthetic = (ProcessSyntheticBean<?>)pb; + + annotated = synthetic.getAnnotated(); + annotatedClass = synthetic.getBean().getBeanClass(); + } + else { + annotated = pb.getAnnotated(); + annotatedClass = pb.getBean().getBeanClass(); + } + + return new SimpleEntry<>(annotatedClass, annotated); + } + + static Class<?> getDeclaringClass(InjectionPoint injectionPoint) { + Annotated annotated = injectionPoint.getAnnotated(); + + Class<?> declaringClass = null; + + if (annotated instanceof AnnotatedParameter) { + AnnotatedParameter<?> ap = (AnnotatedParameter<?>)annotated; + + Parameter javaParameter = ap.getJavaParameter(); + + Executable executable = javaParameter.getDeclaringExecutable(); + + declaringClass = executable.getDeclaringClass(); + } + else { + AnnotatedField<?> af = (AnnotatedField<?>)annotated; + + declaringClass = af.getDeclaringType().getJavaClass(); + } + + return declaringClass; + } + + void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager beanManager) { + _containerState.containerDTO().template.components.stream().filter( + template -> template.type != ComponentType.CONTAINER + ).map( + template -> (ExtendedComponentTemplateDTO)template + ).forEach( + template -> { + Set<Bean<?>> visited = new HashSet<>(); + scanComponentBean(template, template.bean, beanManager, visited); + } + ); + + _beansModel.getOSGiBeans().stream().forEach( + osgiBean -> { + if (!osgiBean.found()) { + abd.addDefinitionError( + new DefinitionException( + String.format( + "Did not find bean for <cdi:bean class=\"%s\">", + osgiBean.getBeanClass()))); + } + } + ); + } + + <X> void processAnnotatedType(@Observes ProcessAnnotatedType<X> pat, BeanManager beanManager) { + final AnnotatedType<X> at = pat.getAnnotatedType(); + + Class<X> annotatedClass = at.getJavaClass(); + + final String className = annotatedClass.getName(); + + OSGiBean osgiBean = _beansModel.getOSGiBean(className); + + if (osgiBean == null) { + return; + } + + osgiBean.found(true); + } + + @SuppressWarnings("rawtypes") + void processBean(@Observes ProcessBean<?> pb) { + Entry<Class<?>, Annotated> beanClassAndAnnotated = getBeanClassAndAnnotated(pb); + + final Class<?> annotatedClass = beanClassAndAnnotated.getKey(); + + String className = annotatedClass.getName(); + + OSGiBean osgiBean = _beansModel.getOSGiBean(className); + + if (osgiBean == null) { + return; + } + + osgiBean.found(true); + + final Annotated annotated = beanClassAndAnnotated.getValue(); + + try { + List<Class<?>> serviceTypes = Types.collectServiceTypes(annotated); + + if ((annotated instanceof AnnotatedType) && + Optional.ofNullable( + annotated.getAnnotation(SingleComponent.class)).isPresent()) { + + ExtendedComponentTemplateDTO componentTemplate = new ExtendedComponentTemplateDTO(); + componentTemplate.activations = new CopyOnWriteArrayList<>(); + + ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO(); + activationTemplate.declaringClass = annotatedClass; + activationTemplate.properties = Collections.emptyMap(); + activationTemplate.scope = getScope(annotated); + activationTemplate.serviceClasses = serviceTypes.stream().map( + st -> st.getName() + ).collect(Collectors.toList()); + + componentTemplate.activations.add(activationTemplate); + + componentTemplate.bean = pb.getBean(); + componentTemplate.beans = new CopyOnWriteArrayList<>(); + componentTemplate.configurations = new CopyOnWriteArrayList<>(); + componentTemplate.name = pb.getBean().getName(); + componentTemplate.properties = Maps.componentProperties(annotated); + componentTemplate.references = new CopyOnWriteArrayList<>(); + componentTemplate.type = ComponentType.SINGLE; + + annotated.getAnnotations(PID.class).stream().forEach( + PID -> { + ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO(); + + configurationTemplate.componentConfiguration = true; + configurationTemplate.declaringClass = annotatedClass; + configurationTemplate.maximumCardinality = MaximumCardinality.ONE; + configurationTemplate.pid = Optional.of(PID.value()).map( + s -> { + if (s.equals("$") || s.equals("")) { + return componentTemplate.name; + } + return s; + } + ).orElse(componentTemplate.name); + + if (PID.value().equals("$") || PID.value().equals("")) { + configurationTemplate.pid = componentTemplate.name; + } + else { + configurationTemplate.pid = PID.value(); + } + + configurationTemplate.policy = PID.policy(); + + componentTemplate.configurations.add(configurationTemplate); + } + ); + + if (componentTemplate.configurations.isEmpty()) { + ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO(); + + configurationTemplate.componentConfiguration = true; + configurationTemplate.declaringClass = annotatedClass; + configurationTemplate.maximumCardinality = MaximumCardinality.ONE; + configurationTemplate.pid = componentTemplate.name; + configurationTemplate.policy = ConfigurationPolicy.OPTIONAL; + + componentTemplate.configurations.add(configurationTemplate); + } + + componentTemplate.beans.add(className); + + _containerState.containerDTO().template.components.add(componentTemplate); + + osgiBean.setComponent(componentTemplate); + } + else if ((annotated instanceof AnnotatedType) && + Optional.ofNullable( + annotated.getAnnotation(FactoryComponent.class)).isPresent()) { + + ExtendedComponentTemplateDTO componentTemplate = new ExtendedComponentTemplateDTO(); + componentTemplate.activations = new CopyOnWriteArrayList<>(); + + ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO(); + activationTemplate.declaringClass = annotatedClass; + activationTemplate.properties = Collections.emptyMap(); + activationTemplate.scope = getScope(annotated); + activationTemplate.serviceClasses = serviceTypes.stream().map( + st -> st.getName() + ).collect(Collectors.toList()); + + componentTemplate.activations.add(activationTemplate); + + componentTemplate.bean = pb.getBean(); + componentTemplate.beans = new CopyOnWriteArrayList<>(); + componentTemplate.configurations = new CopyOnWriteArrayList<>(); + componentTemplate.name = pb.getBean().getName(); + componentTemplate.properties = Maps.componentProperties(annotated); + componentTemplate.references = new CopyOnWriteArrayList<>(); + componentTemplate.type = ComponentType.FACTORY; + + annotated.getAnnotations(PID.class).stream().forEach( + PID -> { + ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO(); + + configurationTemplate.componentConfiguration = true; + configurationTemplate.declaringClass = annotatedClass; + configurationTemplate.maximumCardinality = MaximumCardinality.ONE; + configurationTemplate.pid = Optional.of(PID.value()).map( + s -> { + if (s.equals("$") || s.equals("")) { + return componentTemplate.name; + } + return s; + } + ).orElse(componentTemplate.name); + + configurationTemplate.policy = PID.policy(); + + componentTemplate.configurations.add(configurationTemplate); + } + ); + + ExtendedConfigurationTemplateDTO configurationTemplate = new ExtendedConfigurationTemplateDTO(); + + configurationTemplate.componentConfiguration = true; + configurationTemplate.declaringClass = annotatedClass; + configurationTemplate.maximumCardinality = MaximumCardinality.MANY; + configurationTemplate.pid = Optional.ofNullable( + annotated.getAnnotation(FactoryComponent.class) + ).map(fc -> { + if (fc.value().equals("$") || fc.value().equals("")) { + return componentTemplate.name; + } + return fc.value(); + }).orElse(componentTemplate.name); + configurationTemplate.policy = ConfigurationPolicy.REQUIRED; + + componentTemplate.configurations.add(configurationTemplate); + componentTemplate.beans.add(className); + + _containerState.containerDTO().template.components.add(componentTemplate); + + osgiBean.setComponent(componentTemplate); + } + else if ((annotated instanceof AnnotatedType) && + Optional.ofNullable( + annotated.getAnnotation(ComponentScoped.class)).isPresent()) { + + // Explicitly ignore this case + } + else { + if (!_containerTemplate.beans.contains(className)) { + _containerTemplate.beans.add(className); + } + + if (!serviceTypes.isEmpty()) { + Class<? extends Annotation> scope = pb.getBean().getScope(); + if (!scope.equals(ApplicationScoped.class) && + !scope.equals(Dependent.class)) { + + pb.addDefinitionError( + new IllegalStateException( + String.format( + "@Service can only be used on @ApplicationScoped, @Dependent, @SingleComponent, and @FactoryComponent: %s", + pb.getBean()))); + return; + } + + ExtendedActivationTemplateDTO activationTemplate = new ExtendedActivationTemplateDTO(); + activationTemplate.cdiScope = scope; + activationTemplate.declaringClass = annotatedClass; + if (pb instanceof ProcessProducerField) { + activationTemplate.producer = ((ProcessProducerField) pb).getAnnotatedProducerField(); + } + else if (pb instanceof ProcessProducerMethod) { + activationTemplate.producer = ((ProcessProducerMethod) pb).getAnnotatedProducerMethod(); + } + activationTemplate.properties = Maps.componentProperties(annotated); + activationTemplate.scope = getScope(annotated); + activationTemplate.serviceClasses = serviceTypes.stream().map( + st -> st.getName() + ).collect(Collectors.toList()); + + _containerTemplate.activations.add(activationTemplate); + } + + osgiBean.setComponent(_containerTemplate); + } + } + catch (Exception e) { + pb.addDefinitionError(e); + } + } + + void processInjectionPoint(@Observes ProcessInjectionPoint<?, ?> pip) { + InjectionPoint injectionPoint = pip.getInjectionPoint(); + + Class<?> declaringClass = getDeclaringClass(injectionPoint); + + String className = declaringClass.getName(); + + OSGiBean osgiBean = _beansModel.getOSGiBean(className); + + if (osgiBean == null) { + return; + } + + Annotated annotated = injectionPoint.getAnnotated(); + Reference reference = annotated.getAnnotation(Reference.class); + Configuration configuration = annotated.getAnnotation(Configuration.class); + + if (reference != null) { + if (configuration != null) { + _containerState.error( + new IllegalArgumentException( + String.format( + "Cannot use @Reference and @Configuration on the same injection point {}", + injectionPoint)) + ); + + return; + } + + Builder builder = null; + + if (annotated instanceof AnnotatedParameter) { + builder = new ReferenceModel.Builder((AnnotatedParameter<?>)annotated); + } + else { + builder = new ReferenceModel.Builder((AnnotatedField<?>)annotated); + } + + try { + ReferenceModel referenceModel = builder.type(injectionPoint.getType()).build(); + + osgiBean.addReference(referenceModel.toDTO()); + } + catch (Exception e) { + _containerState.error(e); + } + } + else if (configuration != null) { + try { + ConfigurationModel configurationModel = new ConfigurationModel.Builder( + injectionPoint.getType() + ).declaringClass( + declaringClass + ).injectionPoint( + injectionPoint + ).build(); + + osgiBean.addConfiguration(configurationModel.toDTO()); + } + catch (Exception e) { + _containerState.error(e); + } + } + } + + void processObserverMethod(@Observes ProcessObserverMethod<ReferenceEvent<?>, ?> pom) { + ObserverMethod<ReferenceEvent<?>> observerMethod = pom.getObserverMethod(); + + AnnotatedMethod<?> annotatedMethod = pom.getAnnotatedMethod(); + + Configuration configuration = annotatedMethod.getAnnotation(Configuration.class); + + if (configuration != null) { + pom.addDefinitionError( + new IllegalArgumentException( + String.format( + "Cannot use @Configuration on ReferenceEvent observer method {}", + observerMethod)) + ); + + return; + } + + Class<?> beanClass = observerMethod.getBeanClass(); + + final String className = beanClass.getName(); + + OSGiBean osgiBean = _beansModel.getOSGiBean(className); + + if (osgiBean == null) { + pom.addDefinitionError( + new DefinitionException( + String.format( + "The observer method %s was not declared as <cdi:bean class=\"%s\">", + observerMethod, className)) + ); + + return; + } + + try { + ReferenceModel referenceModel = new ReferenceModel.Builder( + pom.getAnnotatedMethod().getParameters().get(0) + ).type(observerMethod.getObservedType()).build(); + + osgiBean.addReference(referenceModel.toDTO()); + } + catch (Exception e) { + pom.addDefinitionError(e); + } + } + + ServiceScope getScope(Annotated annotated) { + Prototype prototype = annotated.getAnnotation(Prototype.class); + Bundle bundle = annotated.getAnnotation(Bundle.class); + + if (prototype != null) { + if (bundle != null) { + throw new IllegalArgumentException( + String.format( + "@Prototype and @Bundle must not be used to gether: %s", + annotated)); + } + + return ServiceScope.PROTOTYPE; + } + + if (bundle != null) { + return ServiceScope.BUNDLE; + } + + return ServiceScope.SINGLETON; + } + + void scanComponentBean( + ExtendedComponentTemplateDTO template, + Bean<?> bean, + BeanManager beanManager, + Set<Bean<?>> visited) { + + if (visited.contains(bean)) { + return; + } + + visited.add(bean); + + Class<?> beanClass = bean.getBeanClass(); + + String className = beanClass.getName(); + + OSGiBean osgiBean = _beansModel.getOSGiBean(className); + + ComponentTemplateDTO currentTemplate = osgiBean.getComponent(); + + if (currentTemplate == null) { + osgiBean.setComponent(template); + } + else if (!currentTemplate.equals(template)) { + throw new IllegalStateException("Something is wrong here"); + } + + if (!template.beans.contains(className)) { + template.beans.add(className); + } + + for (InjectionPoint injectionPoint : bean.getInjectionPoints()) { + if ((injectionPoint.getAnnotated().getAnnotation(Configuration.class) != null) || + (injectionPoint.getAnnotated().getAnnotation(Reference.class) != null)) { + + continue; + } + + Set<Bean<?>> beans = beanManager.getBeans( + injectionPoint.getType(), + injectionPoint.getQualifiers().toArray(new Annotation[0])); + + Bean<?> next = beanManager.resolve(beans); + + if ((next == null) || next.getScope() != ComponentScoped.class) { + continue; + } + + scanComponentBean(template, next, beanManager, visited); + } + } + + private final BeansModel _beansModel; + private final ComponentTemplateDTO _containerTemplate; + private final ContainerState _containerState; + +} Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java (from r1829114, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/extension/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?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/extension/ExtensionMetadata.java&r1=1829114&r2=1829115&rev=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/extension/ExtensionMetadata.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionMetadata.java Sat Apr 14 01:10:27 2018 @@ -12,7 +12,7 @@ * limitations under the License. */ -package org.apache.aries.cdi.container.internal.extension; +package org.apache.aries.cdi.container.internal.container; import javax.enterprise.inject.spi.Extension; Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ExtensionPhase.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,278 @@ +/** + * 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.Filters.*; + +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; +import java.util.concurrent.ConcurrentSkipListSet; + +import javax.enterprise.inject.spi.Extension; + +import org.apache.aries.cdi.container.internal.container.Op.Mode; +import org.apache.aries.cdi.container.internal.container.Op.Type; +import org.apache.aries.cdi.container.internal.model.ExtendedExtensionDTO; +import org.apache.aries.cdi.container.internal.model.ExtendedExtensionTemplateDTO; +import org.apache.aries.cdi.container.internal.util.Conversions; +import org.apache.aries.cdi.container.internal.util.SRs; +import org.apache.aries.cdi.container.internal.util.Throw; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Filter; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cdi.runtime.dto.ExtensionDTO; +import org.osgi.service.cdi.runtime.dto.template.ExtensionTemplateDTO; +import org.osgi.service.log.Logger; +import org.osgi.util.promise.Promise; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; + +public class ExtensionPhase extends Phase { + + public ExtensionPhase(ContainerState containerState, Phase next) { + super(containerState, next); + _log = containerState.containerLogs().getLogger(getClass()); + } + + @Override + public boolean close() { + if (!extensionTemplates().isEmpty()) { + if (_extensionTracker != null) { + _extensionTracker.close(); + + _extensionTracker = null; + } + + return true; + } + else { + return next.map( + next -> { + submit(next.closeOp(), next::close).onFailure( + f -> { + _log.error(l -> l.error("CCR Error in extension CLOSE on {}", bundle(), f)); + + error(f); + } + ); + + return true; + } + ).orElse(true); + } + } + + @Override + public Op closeOp() { + return Op.of(Mode.CLOSE, Type.EXTENSION, containerState.id()); + } + + @Override + public boolean open() { + if (!extensionTemplates().isEmpty()) { + _extensionTracker = new ServiceTracker<>( + containerState.bundleContext(), createExtensionFilter(), new ExtensionPhaseCustomizer()); + + _extensionTracker.open(); + + return true; + } + else { + return next.map( + next -> { + submit(next.openOp(), next::open).then( + null, + f -> { + _log.error(l -> l.error("CCR Error in extension OPEN on {}", bundle(), f.getFailure())); + + error(f.getFailure()); + } + ); + + return true; + } + ).orElse(true); + } + } + + @Override + public Op openOp() { + return Op.of(Mode.OPEN, Type.EXTENSION, containerState.id()); + } + + Filter createExtensionFilter() { + final List<ExtensionTemplateDTO> templates = extensionTemplates(); + + StringBuilder sb = new StringBuilder("(&(objectClass=" + Extension.class.getName() + ")"); + + if (templates.size() > 1) sb.append("(|"); + + for (ExtensionTemplateDTO tmpl : templates) { + sb.append(tmpl.serviceFilter); + } + + if (templates.size() > 1) sb.append(")"); + + sb.append(")"); + + return asFilter(sb.toString()); + } + + List<ExtensionTemplateDTO> extensionTemplates() { + return containerState.containerDTO().template.extensions; + } + + List<ExtensionDTO> snapshots() { + return containerState.containerDTO().extensions; + } + + + private ServiceTracker<Extension, ExtendedExtensionDTO> _extensionTracker; + private final Logger _log; + private final SortedSet<ExtendedExtensionDTO> _references = new ConcurrentSkipListSet<>( + (e1, e2) -> e1.serviceReference.compareTo(e2.serviceReference) + ); + + private class ExtensionPhaseCustomizer implements ServiceTrackerCustomizer<Extension, ExtendedExtensionDTO> { + + @Override + public ExtendedExtensionDTO addingService(ServiceReference<Extension> reference) { + ExtendedExtensionTemplateDTO template = extensionTemplates().stream().map( + t -> (ExtendedExtensionTemplateDTO)t + ).filter( + t -> t.filter.match(reference) + ).findFirst().get(); + + ExtendedExtensionDTO snapshot = snapshots().stream().map( + s -> (ExtendedExtensionDTO)s + ).filter( + s -> s.template == template + ).findFirst().orElse(null); + + if (snapshot != null) { + if (reference.compareTo(snapshot.serviceReference) <= 0) { + return null; + } + + if (snapshots().remove(snapshot)) { + _references.add(snapshot); + snapshot.extension = null; + containerState.bundleContext().ungetService(snapshot.serviceReference); + } + } + + ExtendedExtensionDTO extensionDTO = new ExtendedExtensionDTO(); + + BundleContext bc = containerState.bundleContext(); + + extensionDTO.extension = bc.getServiceObjects(reference); + extensionDTO.service = SRs.from(reference); + extensionDTO.serviceReference = reference; + extensionDTO.template = template; + + snapshots().add(extensionDTO); + containerState.incrementChangeCount(); + + if (snapshots().size() == extensionTemplates().size()) { + next.ifPresent( + next -> submit(next.closeOp(), next::close).then( + s -> { + return submit(next.openOp(), next::open).then( + null, + f -> { + _log.error(l -> l.error("CCR Error in extension open TRACKING {} on {}", reference, bundle(), f.getFailure())); + + error(f.getFailure()); + } + ); + }, + f -> { + _log.error(l -> l.error("CCR Error extension close TRACKING {} on {}", reference, bundle(), f.getFailure())); + + error(f.getFailure()); + } + ) + ); + } + + return extensionDTO; + } + + @Override + public void modifiedService(ServiceReference<Extension> reference, ExtendedExtensionDTO extentionDTO) { + removedService(reference, extentionDTO); + addingService(reference); + } + + @Override + public void removedService(ServiceReference<Extension> reference, final ExtendedExtensionDTO extensionDTO) { + _log.debug(l -> l.debug("CCR Departing extension {} on {}", Conversions.convert(extensionDTO).to(ExtensionDTO.class), bundle())); + + containerState.bundleContext().ungetService(reference); + + if (!snapshots().removeIf(snap -> ((ExtendedExtensionDTO)snap).serviceReference.equals(reference))) { + return; + } + + for (Iterator<ExtendedExtensionDTO> itr = _references.iterator();itr.hasNext();) { + ExtendedExtensionDTO entry = itr.next(); + if (((ExtendedExtensionTemplateDTO)extensionDTO.template).filter.match(entry.serviceReference)) { + entry.extension = containerState.bundleContext().getServiceObjects(entry.serviceReference); + itr.remove(); + snapshots().add(entry); + break; + } + } + + containerState.incrementChangeCount(); + + next.ifPresent( + next -> { + Promise<Boolean> result = submit(next.closeOp(), next::close).then( + s -> { + if (snapshots().size() == extensionTemplates().size()) { + return submit(next.openOp(), next::open).then( + null, + f -> { + _log.error(l -> l.error("CCR Error in extension open {} on {}", reference, bundle())); + + error(f.getFailure()); + } + ); + } + + return s; + }, + f -> { + _log.error(l -> l.error("CCR Error in extension close {} on {}", reference, bundle())); + + error(f.getFailure()); + } + ); + + try { + result.getValue(); + } + catch (Exception e) { + Throw.exception(e); + } + } + ); + } + + } + +} Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,61 @@ +/** + * 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.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.inject.spi.configurator.BeanConfigurator; + +import org.osgi.service.log.FormatterLogger; +import org.osgi.service.log.Logger; +import org.osgi.service.log.LoggerFactory; + +public class LoggerExtension implements Extension { + + public LoggerExtension(ContainerState containerState) { + _containerState = containerState; + } + + void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) { + final LoggerFactory lf = _containerState.containerLogs().getLoggerFactory(); + + BeanConfigurator<FormatterLogger> formatterLoggerBean = abd.addBean(); + formatterLoggerBean.addType(FormatterLogger.class); + formatterLoggerBean.produceWith( + i -> { + InjectionPoint ip = i.select(InjectionPoint.class).get(); + return lf.getLogger( + ip.getMember().getDeclaringClass().getName(), + FormatterLogger.class); + } + ); + + BeanConfigurator<Logger> loggerBean = abd.addBean(); + loggerBean.addType(Logger.class); + loggerBean.produceWith( + i -> { + InjectionPoint ip = i.select(InjectionPoint.class).get(); + return lf.getLogger( + ip.getMember().getDeclaringClass().getName(), + Logger.class); + } + ); + } + + private final ContainerState _containerState; + +} Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java (from r1829114, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/literal/CdiMark.java) URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/literal/CdiMark.java&r1=1829114&r2=1829115&rev=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/literal/CdiMark.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Mark.java Sat Apr 14 01:10:27 2018 @@ -12,19 +12,41 @@ * limitations under the License. */ -package org.apache.aries.cdi.container.internal.literal; +package org.apache.aries.cdi.container.internal.container; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import javax.enterprise.util.AnnotationLiteral; import javax.inject.Qualifier; @Qualifier @Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) @Retention(value = RetentionPolicy.RUNTIME) -public @interface CdiMark { +public @interface Mark { + + public class Literal extends AnnotationLiteral<Mark> implements Mark { + + private static final long serialVersionUID = 1L; + + public static Literal from(int i) { + return new Literal(i); + } + + public Literal(int i) { + _value = i; + } + + @Override + public int value() { + return _value; + } + + private final int _value; + + } int value(); Copied: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java (from r1829114, aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/component/MarkedInjectionPoint.java) URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java?p2=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java&p1=aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/component/MarkedInjectionPoint.java&r1=1829114&r2=1829115&rev=1829115&view=diff ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/component/MarkedInjectionPoint.java (original) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/MarkedInjectionPoint.java Sat Apr 14 01:10:27 2018 @@ -12,23 +12,23 @@ * limitations under the License. */ -package org.apache.aries.cdi.container.internal.component; +package org.apache.aries.cdi.container.internal.container; import java.lang.annotation.Annotation; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import javax.enterprise.inject.spi.InjectionPoint; -import org.apache.aries.cdi.container.internal.literal.CdiMarkLiteral; import org.apache.aries.cdi.container.internal.util.Sets; import org.jboss.weld.injection.ForwardingInjectionPoint; public class MarkedInjectionPoint extends ForwardingInjectionPoint { - public MarkedInjectionPoint(InjectionPoint injectionPoint, Annotation annotation, int mark) { + public MarkedInjectionPoint(InjectionPoint injectionPoint) { _delegate = injectionPoint; - _mark = mark; - _qualifiers = Sets.hashSet(injectionPoint.getQualifiers(), annotation, CdiMarkLiteral.from(_mark)); + _mark = Mark.Literal.from(counter.incrementAndGet()); + _qualifiers = Sets.hashSet(injectionPoint.getQualifiers(), _mark); } @Override @@ -40,7 +40,7 @@ public class MarkedInjectionPoint extend return delegate(); } - public int getMark() { + public Mark getMark() { return _mark; } @@ -49,8 +49,10 @@ public class MarkedInjectionPoint extend return _qualifiers; } + private static final AtomicInteger counter = new AtomicInteger(); + private final InjectionPoint _delegate; - private final int _mark; + private final Mark _mark; private final Set<Annotation> _qualifiers; } \ No newline at end of file Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Op.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,62 @@ +/** + * 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.Arrays; + +public class Op { + + public static enum Mode {CLOSE, OPEN} + + public static enum Type { + CONFIGURATION_EVENT, + CONFIGURATION_LISTENER, + CONTAINER_ACTIVATOR, + CONTAINER_BOOTSTRAP, + CONTAINER_COMPONENT, + CONTAINER_FIRE_EVENTS, + CONTAINER_INSTANCE, + CONTAINER_PUBLISH_SERVICES, + REFERENCES, + EXTENSION, + FACTORY_ACTIVATOR, + FACTORY_COMPONENT, + FACTORY_INSTANCE, + INIT, + SINGLE_ACTIVATOR, + SINGLE_COMPONENT, + SINGLE_INSTANCE, + } + + public static Op of(Mode mode, Type type, String name) { + return new Op(mode, type, name); + } + + private Op(Mode mode, Type type, String name) { + this.mode = mode; + this.type = type; + this.name = name; + } + + public final Mode mode; + public final Type type; + public final String name; + + @Override + public String toString() { + return Arrays.asList(getClass().getSimpleName(), mode, type, name).toString(); + } + +} \ No newline at end of file Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/Phase.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,53 @@ +/** + * 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.Optional; +import java.util.concurrent.Callable; + +import org.osgi.framework.Bundle; +import org.osgi.util.promise.Promise; + +public abstract class Phase { + + public Phase(ContainerState containerState, Phase next) { + this.containerState = containerState; + this.next = Optional.ofNullable(next); + } + + public final Bundle bundle() { + return containerState.bundle(); + } + + public abstract Op closeOp(); + + public abstract boolean close(); + + public final void error(Throwable t) { + containerState.error(t); + } + + public abstract boolean open(); + + public abstract Op openOp(); + + public final <T> Promise<T> submit(Op op, Callable<T> callable) { + return containerState.submit(op, callable); + } + + protected final ContainerState containerState; + protected final Optional<Phase> next; + +} Added: aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java?rev=1829115&view=auto ============================================================================== --- aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java (added) +++ aries/trunk/cdi/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ReferenceServiceObjectsImpl.java Sat Apr 14 01:10:27 2018 @@ -0,0 +1,59 @@ +/** + * 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.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.osgi.framework.ServiceObjects; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cdi.reference.ReferenceServiceObjects; + +public class ReferenceServiceObjectsImpl<T> implements ReferenceServiceObjects<T> { + + public ReferenceServiceObjectsImpl(ServiceObjects<T> so) { + _so = so; + } + + public void close() { + _objects.removeIf( + o -> { + _so.ungetService(o); + return true; + } + ); + } + + @Override + public T getService() { + T service = _so.getService(); + _objects.add(service); + return service; + } + + @Override + public ServiceReference<T> getServiceReference() { + return _so.getServiceReference(); + } + + @Override + public void ungetService(T service) { + _objects.remove(service); + _so.ungetService(service); + } + + private final Set<T> _objects = ConcurrentHashMap.newKeySet(); + private final ServiceObjects<T> _so; +} \ No newline at end of file