TAMAYA-238: Unified CDI injection modules.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/commit/b3bcddcb Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/b3bcddcb Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/b3bcddcb Branch: refs/heads/master Commit: b3bcddcb8b7743d81a6670b99d804e3f8c4f419a Parents: 78415bc Author: anatole <[email protected]> Authored: Fri Mar 17 00:20:18 2017 +0100 Committer: anatole <[email protected]> Committed: Fri Mar 17 00:20:18 2017 +0100 ---------------------------------------------------------------------- modules/injection/cdi-ee/bnd.bnd | 3 - modules/injection/cdi-ee/pom.xml | 202 -------- .../integration/cdi/CDIAwareServiceContext.java | 206 -------- .../integration/cdi/CDIConfiguredField.java | 77 --- .../integration/cdi/CDIConfiguredMethod.java | 77 --- .../integration/cdi/CDIConfiguredType.java | 94 ---- .../integration/cdi/ConfigurationExtension.java | 290 ----------- .../integration/cdi/ConfigurationProducer.java | 147 ------ .../integration/cdi/DefaultDynamicValue.java | 501 ------------------- .../javax.enterprise.inject.spi.Extension | 19 - ...onfigurationProducerFailedInjectionTest.java | 33 -- .../cdi/ConfigurationProducerTest.java | 168 ------- .../cdi/ConfigurationResolverTest.java | 112 ----- .../integration/cdi/EnvironmentsTest.java | 83 --- .../integration/cdi/InterpolationTest.java | 62 --- .../integration/cdi/NotFoundNoDefault.java | 78 --- .../META-INF/javaconfiguration.properties | 32 -- .../cdi-ee/src/test/resources/base.properties | 32 -- .../cdi-ee/src/test/resources/cert.properties | 20 - .../cdi-ee/src/test/resources/dev.properties | 19 - .../cdi-ee/src/test/resources/prod.properties | 20 - .../cdi-ee/src/test/resources/qa.properties | 20 - .../cdi-ee/src/test/resources/test.properties | 20 - .../integration/cdi/SEInjectorCDIExtension.java | 112 ----- .../cdi/ServiceLoaderServiceContext.java | 190 ------- .../integration/cdi/TamayaCDIIntegration.java | 52 -- .../cdi/config/ConfiguredVetoExtension.java | 42 -- .../src/main/resources/META-INF/beans.xml | 24 - .../org.apache.tamaya.spi.ServiceContext | 19 - .../tamaya/integration/cdi/ConfiguredClass.java | 112 ----- .../tamaya/integration/cdi/ConfiguredTest.java | 83 --- .../tamaya/integration/cdi/InjectedClass.java | 62 --- .../cdi/cfg/ProvidedPropertySource.java | 66 --- .../integration/cdi/cfg/TestConfigProvider.java | 45 -- .../integration/cdi/cfg/TestPropertySource.java | 82 --- .../src/test/resources/META-INF/beans.xml | 24 - modules/injection/cdi/bnd.bnd | 3 + modules/injection/cdi/pom.xml | 213 ++++++++ .../integration/cdi/CDIAwareServiceContext.java | 206 ++++++++ .../integration/cdi/CDIConfiguredField.java | 77 +++ .../integration/cdi/CDIConfiguredMethod.java | 77 +++ .../integration/cdi/CDIConfiguredType.java | 94 ++++ .../integration/cdi/ConfigurationExtension.java | 290 +++++++++++ .../integration/cdi/ConfigurationProducer.java | 253 ++++++++++ .../integration/cdi/DefaultDynamicValue.java | 497 ++++++++++++++++++ .../cdi/ServiceLoaderServiceContext.java | 190 +++++++ .../integration/cdi/TamayaCDIAccessor.java | 52 ++ .../cdi/TamayaCDIInjectionExtension.java | 277 ++++++++++ .../cdi/TamayaSEInjectionExtension.java | 108 ++++ .../cdi/extra/ConfiguredVetoExtension.java | 43 ++ .../cdi/src/main/resources/META-INF/beans.xml | 24 + .../javax.enterprise.inject.spi.Extension | 21 + .../org.apache.tamaya.spi.ServiceContext | 19 + ...onfigurationProducerFailedInjectionTest.java | 33 ++ .../cdi/ConfigurationProducerTest.java | 169 +++++++ .../cdi/ConfigurationResolverTest.java | 112 +++++ .../tamaya/integration/cdi/ConfiguredClass.java | 111 ++++ .../tamaya/integration/cdi/ConfiguredTest.java | 83 +++ .../integration/cdi/EnvironmentsTest.java | 83 +++ .../tamaya/integration/cdi/InjectedClass.java | 62 +++ .../integration/cdi/InterpolationTest.java | 62 +++ .../integration/cdi/NotFoundNoDefault.java | 78 +++ .../cdi/cfg/ProvidedPropertySource.java | 66 +++ .../integration/cdi/cfg/TestConfigProvider.java | 45 ++ .../integration/cdi/cfg/TestPropertySource.java | 82 +++ .../cdi/src/test/resources/META-INF/beans.xml | 24 + .../META-INF/javaconfiguration.properties | 35 ++ .../cdi/src/test/resources/base.properties | 32 ++ .../cdi/src/test/resources/cert.properties | 20 + .../cdi/src/test/resources/dev.properties | 19 + .../cdi/src/test/resources/prod.properties | 20 + .../cdi/src/test/resources/qa.properties | 20 + .../cdi/src/test/resources/test.properties | 20 + 73 files changed, 3620 insertions(+), 3228 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/bnd.bnd ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/bnd.bnd b/modules/injection/cdi-ee/bnd.bnd deleted file mode 100644 index a97720d..0000000 --- a/modules/injection/cdi-ee/bnd.bnd +++ /dev/null @@ -1,3 +0,0 @@ -Export-Package: \ - org.apache.tamaya.inject -Bundle-SymbolicName: org.apache.tamaya.inject-ee \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/pom.xml ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/pom.xml b/modules/injection/cdi-ee/pom.xml deleted file mode 100644 index c16b3a7..0000000 --- a/modules/injection/cdi-ee/pom.xml +++ /dev/null @@ -1,202 +0,0 @@ -<!-- -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you 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 current 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. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.apache.tamaya.ext</groupId> - <artifactId>tamaya-injection-all</artifactId> - <version>0.3-incubating-SNAPSHOT</version> - <relativePath>..</relativePath> - </parent> - - <artifactId>tamaya-cdi</artifactId> - <name>Apache Tamaya Modules - Injection CDI</name> - <packaging>jar</packaging> - - <properties> - <owb.version>1.6.2</owb.version> - <weld.version>2.2.7.Final</weld.version> - <geronimo-jcdi-1.1-spec.version>1.0</geronimo-jcdi-1.1-spec.version> - <geronimo-interceptor-1.2-spec.version>1.0</geronimo-interceptor-1.2-spec.version> - <geronimo-atinject-1.0-spec.version>1.0</geronimo-atinject-1.0-spec.version> - <bval.version>0.5</bval.version> - <ds.version>1.1.0</ds.version> - <javaee-api.version>6.0-6</javaee-api.version> - <openejb.version>4.7.1</openejb.version> - <tomee.version>1.7.1</tomee.version> - </properties> - - <dependencies> - <dependency> - <groupId>org.apache.tamaya.ext</groupId> - <artifactId>tamaya-injection-api</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>java-hamcrest</artifactId> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.apache.tamaya</groupId> - <artifactId>tamaya-core</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.tamaya</groupId> - <artifactId>tamaya-api</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.tamaya.ext</groupId> - <artifactId>tamaya-spisupport</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.openejb</groupId> - <artifactId>javaee-api</artifactId> - <version>${javaee-api.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.tomitribe</groupId> - <artifactId>tomitribe-util</artifactId> - <version>1.1.0</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.openejb</groupId> - <artifactId>openejb-core</artifactId> - <version>${openejb.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.geronimo.specs</groupId> - <artifactId>geronimo-jcdi_1.1_spec</artifactId> - <version>${geronimo-jcdi-1.1-spec.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-test-control-module-api</artifactId> - <version>${ds.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.deltaspike.modules</groupId> - <artifactId>deltaspike-test-control-module-impl</artifactId> - <version>${ds.version}</version> - <scope>test</scope> - </dependency> - </dependencies> - <profiles> - <!--<profile>--> - <!--<id>OWB</id>--> - <!--<!– there is an issue with this profile:--> - <!--java.lang.NoClassDefFoundError: org/apache/webbeans/event/EventMetadata--> - <!--–>--> - <!--<activation>--> - <!--<activeByDefault>false</activeByDefault>--> - <!--</activation>--> - <!--<dependencies>--> - <!--<!– OWB specific dependencies–>--> - <!--<dependency>--> - <!--<groupId>org.apache.geronimo.specs</groupId>--> - <!--<artifactId>geronimo-atinject_1.0_spec</artifactId>--> - <!--<version>${geronimo-atinject-1.0-spec.version}</version>--> - <!--</dependency>--> - <!--<dependency>--> - <!--<groupId>org.apache.geronimo.specs</groupId>--> - <!--<artifactId>geronimo-interceptor_1.2_spec</artifactId>--> - <!--<version>${geronimo-interceptor-1.2-spec.version}</version>--> - <!--<scope>test</scope>--> - <!--</dependency>--> - <!--<dependency>--> - <!--<groupId>org.apache.geronimo.specs</groupId>--> - <!--<artifactId>geronimo-annotation_1.2_spec</artifactId>--> - <!--<version>1.0</version>--> - <!--<scope>test</scope>--> - <!--</dependency>--> - <!--<dependency>--> - <!--<groupId>org.apache.geronimo.specs</groupId>--> - <!--<artifactId>geronimo-el_2.2_spec</artifactId>--> - <!--<version>1.0.2</version>--> - <!--</dependency>--> - - <!--<dependency>--> - <!--<groupId>org.apache.openwebbeans</groupId>--> - <!--<artifactId>openwebbeans-impl</artifactId>--> - <!--<version>${owb.version}</version>--> - <!--</dependency>--> - <!--<dependency>--> - <!--<groupId>org.apache.openwebbeans</groupId>--> - <!--<artifactId>openwebbeans-spi</artifactId>--> - <!--<version>${owb.version}</version>--> - <!--</dependency>--> - <!--<dependency>--> - <!--<groupId>org.apache.openwebbeans</groupId>--> - <!--<artifactId>openwebbeans-resource</artifactId>--> - <!--<version>${owb.version}</version>--> - <!--</dependency>--> - - <!--<dependency>--> - <!--<groupId>org.apache.bval</groupId>--> - <!--<artifactId>bval-jsr303</artifactId>--> - <!--<version>${bval.version}</version>--> - <!--<scope>test</scope>--> - <!--</dependency>--> - <!--<dependency>--> - <!--<groupId>org.apache.deltaspike.cdictrl</groupId>--> - <!--<artifactId>deltaspike-cdictrl-owb</artifactId>--> - <!--<version>${ds.version}</version>--> - <!--<scope>test</scope>--> - <!--</dependency>--> - <!--</dependencies>--> - <!--</profile>--> - <profile> - <id>Weld</id> - <activation> - <activeByDefault>true</activeByDefault> - </activation> - <dependencies> - <dependency> - <groupId>org.jboss.weld.se</groupId> - <artifactId>weld-se</artifactId> - <version>${weld.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.apache.deltaspike.cdictrl</groupId> - <artifactId>deltaspike-cdictrl-weld</artifactId> - <version>${ds.version}</version> - <scope>test</scope> - </dependency> - </dependencies> - </profile> - </profiles> -</project> http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java deleted file mode 100644 index 8c1312f..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.tamaya.integration.cdi; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.spi.ServiceContext; - -import javax.annotation.Priority; -import javax.enterprise.inject.Instance; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import java.io.IOException; -import java.net.URL; -import java.text.MessageFormat; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; -import java.util.logging.Logger; - - -/** - * <p>This class implements a {@link ServiceContext}, which basically provides a similar loading mechanism as used - * by the {@link java.util.ServiceLoader}. Whereas the {@link java.util.ServiceLoader} only loads configurations - * and instances from one classloader, this loader manages configs found and the related instances for each - * classloader along the classloader hierarchies individually. It ensures instances are loaded on the classloader - * level, where they first are visible. Additionally it ensures the same configuration resource (and its - * declared services) are loaded multiple times, when going up the classloader hierarchy.</p> - * - * <p>Finally classloaders are not stored by reference by this class, to ensure they still can be garbage collected. - * Refer also the inherited parent class for further details.</p> - * - * <p>This class uses an ordinal of {@code 10}, so it overrides any default {@link ServiceContext} implementations - * provided with the Tamaya core modules.</p> - */ -public class CDIAwareServiceContext implements ServiceContext { - - /** - * Singletons. - */ - private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>(); - - private ServiceContext defaultServiceContext = new ServiceLoaderServiceContext(); - - - @Override - public <T> T getService(Class<T> serviceType) { - Object cached = singletons.get(serviceType); - if (cached == null) { - Collection<T> services = getServices(serviceType); - if (services.isEmpty()) { - cached = null; - } else { - cached = getServiceWithHighestPriority(services, serviceType); - } - if(cached!=null) { - singletons.put(serviceType, cached); - } - } - return serviceType.cast(cached); - } - - /** - * Loads and registers services. - * - * @param <T> the concrete type. - * @param serviceType The service type. - * @return the items found, never {@code null}. - */ - @Override - public <T> List<T> getServices(final Class<T> serviceType) { - List<T> found = defaultServiceContext.getServices(serviceType); - BeanManager beanManager = TamayaCDIIntegration.getBeanManager(); - Instance<T> cdiInstances = null; - if(beanManager!=null){ - Set<Bean<?>> instanceBeans = beanManager.getBeans(Instance.class); - Bean<?> bean = instanceBeans.iterator().next(); - cdiInstances = (Instance<T>)beanManager.getReference(bean, Instance.class, - beanManager.createCreationalContext(bean)); - } - if(cdiInstances!=null){ - for(T t:cdiInstances.select(serviceType)){ - found.add(t); - } - } - return found; - } - - @Override - public <T> T create(Class<T> serviceType) { - T serv = getService(serviceType); - if(serv!=null){ - try { - return (T)serv.getClass().newInstance(); - } catch (Exception e) { - Logger.getLogger(getClass().getName()) - .log(Level.SEVERE, "Failed to create new instance of: " +serviceType.getName(), e); - } - } - return null; - } - - @Override - public Enumeration<URL> getResources(String resource, ClassLoader cl) throws IOException { - if(cl==null){ - cl = Thread.currentThread().getContextClassLoader(); - } - if(cl==null){ - cl = getClass().getClassLoader(); - } - return cl.getResources(resource); - } - - @Override - public URL getResource(String resource, ClassLoader cl) { - if(cl==null){ - cl = Thread.currentThread().getContextClassLoader(); - } - if(cl==null){ - cl = getClass().getClassLoader(); - } - return cl.getResource(resource); - } - - /** - * Checks the given instance for a @Priority annotation. If present the annotation's value s evaluated. If no such - * annotation is present, a default priority is returned (1); - * @param o the instance, not null. - * @return a priority, by default 1. - */ - public static int getPriority(Object o){ - int prio = 1; //X TODO discuss default priority - Priority priority = o.getClass().getAnnotation(Priority.class); - if (priority != null) { - prio = priority.value(); - } - return prio; - } - - /** - * @param services to scan - * @param <T> type of the service - * - * @return the service with the highest {@link Priority#value()} - * - * @throws ConfigException if there are multiple service implementations with the maximum priority - */ - private <T> T getServiceWithHighestPriority(Collection<T> services, Class<T> serviceType) { - - // we do not need the priority stuff if the list contains only one element - if (services.size() == 1) { - return services.iterator().next(); - } - - Integer highestPriority = null; - int highestPriorityServiceCount = 0; - T highestService = null; - - for (T service : services) { - int prio = getPriority(service); - if (highestPriority == null || highestPriority < prio) { - highestService = service; - highestPriorityServiceCount = 1; - highestPriority = prio; - } else if (highestPriority == prio) { - highestPriorityServiceCount++; - } - } - - if (highestPriorityServiceCount > 1) { - throw new ConfigException(MessageFormat.format("Found {0} implementations for Service {1} with Priority {2}: {3}", - highestPriorityServiceCount, - serviceType.getName(), - highestPriority, - services)); - } - - return highestService; - } - - /** - * Returns ordinal of 20, overriding defaults as well as the inherited (internally used) CLAwareServiceContext - * instance. - * @return ordinal of 20. - */ - @Override - public int ordinal() { - return 20; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java deleted file mode 100644 index fa826f5..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredField.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.tamaya.Configuration; -import org.apache.tamaya.inject.spi.ConfiguredField; - -import javax.enterprise.inject.spi.InjectionPoint; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * CDI implementation for event publishing of configured instances. - */ -class CDIConfiguredField implements ConfiguredField{ - - private final Field field; - private List<String> keys = new ArrayList<>(); - - CDIConfiguredField(InjectionPoint injectionPoint, List<String> keys){ - this.field = (Field)injectionPoint.getMember(); - this.keys.addAll(keys); - this.keys = Collections.unmodifiableList(this.keys); - } - - @Override - public Class<?> getType() { - return field.getType(); - } - - @Override - public Collection<String> getConfiguredKeys() { - return keys; - } - - @Override - public Field getAnnotatedField() { - return field; - } - - @Override - public String getName() { - return field.getName(); - } - - @Override - public String getSignature() { - return getName()+':'+field.getType().getName(); - } - - @Override - public void configure(Object instance, Configuration config) { - throw new UnsupportedOperationException("Use CDI annotations for configuration injection."); - } - - @Override - public String toString() { - return "CDIConfiguredField["+getSignature()+']'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java deleted file mode 100644 index ed8019a..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredMethod.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.tamaya.Configuration; -import org.apache.tamaya.inject.spi.ConfiguredMethod; - -import javax.enterprise.inject.spi.InjectionPoint; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Implementation of a configured methods for CDI module. - */ -public class CDIConfiguredMethod implements ConfiguredMethod{ - - private final Method method; - private List<String> keys = new ArrayList<>(); - - CDIConfiguredMethod(InjectionPoint injectionPoint, List<String> keys){ - this.method = (Method)injectionPoint.getMember(); - this.keys.addAll(keys); - this.keys = Collections.unmodifiableList(this.keys); - } - - @Override - public Collection<String> getConfiguredKeys() { - return keys; - } - - @Override - public Class<?>[] getParameterTypes() { - return method.getParameterTypes(); - } - - @Override - public Method getAnnotatedMethod() { - return method; - } - - @Override - public String getName() { - return method.getName(); - } - - @Override - public String getSignature() { - return null; - } - - @Override - public void configure(Object instance, Configuration config) { - throw new UnsupportedOperationException("Use CDI annotations for configuration injection."); - } - - @Override - public String toString() { - return "CDIConfiguredMethod["+getSignature()+']'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java deleted file mode 100644 index c677065..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/CDIConfiguredType.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.tamaya.Configuration; -import org.apache.tamaya.inject.spi.ConfiguredField; -import org.apache.tamaya.inject.spi.ConfiguredMethod; -import org.apache.tamaya.inject.spi.ConfiguredType; - -import javax.enterprise.inject.spi.InjectionPoint; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; - -/** - * Event published for items configured by CDI extensions. This is for example used by the documentation module - * to automatically track the configuration endpoints for documentation. - */ -class CDIConfiguredType implements ConfiguredType{ - - private final Class<?> type; - private final List<CDIConfiguredMethod> methods = new ArrayList<>(); - private final List<CDIConfiguredField> fields = new ArrayList<>(); - - public CDIConfiguredType(Class<?> type){ - this.type = Objects.requireNonNull(type); - } - - @Override - public Class getType() { - return type; - } - - @Override - public String getName() { - return type.getName(); - } - - @Override - public Collection<ConfiguredField> getConfiguredFields() { - return null; - } - - @Override - public Collection<ConfiguredMethod> getConfiguredMethods() { - return null; - } - - @Override - public void configure(Object instance, Configuration config) { - throw new UnsupportedOperationException("Use CDI annotations for configuration injection."); - } - - /** - * Used to build up during injection point processing. - * @param injectionPoint the CDI injection ppint, not null. - * @param keys the possible config keys, in order of precedence, not null. - */ - void addConfiguredMember(InjectionPoint injectionPoint, List<String> keys) { - Member member = injectionPoint.getMember(); - if(member instanceof Field){ - this.fields.add(new CDIConfiguredField(injectionPoint, keys)); - } else if(member instanceof Method){ - this.methods.add(new CDIConfiguredMethod(injectionPoint, keys)); - } - } - - @Override - public String toString() { - return "CDIConfiguredType{" + - "type=" + type + - ", methods=" + methods + - ", fields=" + fields + - '}'; - } -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java deleted file mode 100644 index 4524461..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationExtension.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.ConfigOperator; -import org.apache.tamaya.Configuration; -import org.apache.tamaya.ConfigurationProvider; -import org.apache.tamaya.inject.api.Config; -import org.apache.tamaya.inject.api.ConfigDefaultSections; -import org.apache.tamaya.inject.api.WithConfigOperator; -import org.apache.tamaya.inject.api.WithPropertyConverter; -import org.apache.tamaya.spi.PropertyConverter; - -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.event.Observes; -import javax.enterprise.inject.spi.AfterBeanDiscovery; -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 javax.enterprise.inject.spi.ProcessBean; -import javax.enterprise.inject.spi.ProcessProducerMethod; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; - - -/** - * CDI Extension module that adds injection mechanism for configuration. - * - * @see org.apache.tamaya.inject.api.Config - * @see org.apache.tamaya.inject.api.ConfigDefaultSections - * @see ConfigException - */ -public class ConfigurationExtension implements Extension { - - private static final Logger LOG = Logger.getLogger(ConfigurationExtension.class.getName()); - - static final Map<Class, ConfigOperator> CUSTOM_OPERATORS = new ConcurrentHashMap<>(); - static final Map<Class, PropertyConverter> CUSTOM_CONVERTERS = new ConcurrentHashMap<>(); - - private final Set<Type> types = new HashSet<>(); - private Bean<?> convBean; - - /** - * Constructor for loading logging its load. - */ - public ConfigurationExtension(){ - LOG.finest("Loading Tamaya CDI Support..."); - } - - /** - * Method that checks the configuration injection points during deployment for available configuration. - * @param pb the bean to process. - * @param beanManager the bean manager to notify about new injections. - */ - public void retrieveTypes(@Observes final ProcessBean<?> pb, BeanManager beanManager) { - - final Set<InjectionPoint> ips = pb.getBean().getInjectionPoints(); - CDIConfiguredType configuredType = new CDIConfiguredType(pb.getBean().getBeanClass()); - - boolean configured = false; - boolean logged = false; - for (InjectionPoint injectionPoint : ips) { - if (injectionPoint.getAnnotated().isAnnotationPresent(Config.class)) { - final Config annotation = injectionPoint.getAnnotated().getAnnotation(Config.class); - final ConfigDefaultSections typeAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefaultSections.class); - final List<String> keys = evaluateKeys(injectionPoint.getMember().getName(), - annotation!=null?annotation.value():null, - typeAnnot!=null?typeAnnot.value():null); - - final WithConfigOperator withOperatorAnnot = injectionPoint.getAnnotated().getAnnotation(WithConfigOperator.class); - if(withOperatorAnnot!=null){ - tryLoadOpererator(withOperatorAnnot.value()); - } - final WithPropertyConverter withConverterAnnot = injectionPoint.getAnnotated().getAnnotation(WithPropertyConverter.class); - if(withConverterAnnot!=null){ - tryLoadConverter(withConverterAnnot.value()); - } - - // We don't want to wait until the injection really fails at runtime. - // If there is a non resolvable configuration, we want to know at startup. - Configuration config = ConfigurationProvider.getConfiguration(); - String value = null; - for(String key:keys) { - value = config.get(key); - if(value!=null){ - break; - } - } - if(value==null && !annotation.defaultValue().isEmpty()){ - value = annotation.defaultValue(); - } - if(value==null){ - throw new ConfigException(String.format( - "Cannot resolve any of the possible configuration keys: %s. Please provide one of the given keys " + - "with a value in your configuration sources.", - keys.toString())); - } - types.add(injectionPoint.getType()); - if(annotation!=null){ - configured = true; - if(!logged) { - LOG.finest("Enabling Tamaya CDI Configuration on bean: " + configuredType.getName()); - } - configuredType.addConfiguredMember(injectionPoint, keys); - } - } - } - if(configured) { - beanManager.fireEvent(configuredType); - } - } - - - public void captureConvertBean(@Observes final ProcessProducerMethod<?, ?> ppm) { - if (ppm.getAnnotated().isAnnotationPresent(Config.class)) { - convBean = ppm.getBean(); - } - - } - - public void addConverter(@Observes final AfterBeanDiscovery abd, final BeanManager bm) { - if(!types.isEmpty()) { - abd.addBean(new ConverterBean(convBean, types)); - } - } - - private void tryLoadOpererator(Class<? extends ConfigOperator> operatorClass) { - Objects.requireNonNull(operatorClass); - if(ConfigOperator.class == operatorClass){ - return; - } - try{ - if(!CUSTOM_OPERATORS.containsKey(operatorClass)) { - CUSTOM_OPERATORS.put(operatorClass, operatorClass.newInstance()); - } - } catch(Exception e){ - throw new ConfigException("Custom ConfigOperator could not be loaded: " + operatorClass.getName(), e); - } - } - - private void tryLoadConverter(Class<? extends PropertyConverter> converterClass) { - Objects.requireNonNull(converterClass); - if(PropertyConverter.class == converterClass){ - return; - } - try{ - if(!CUSTOM_CONVERTERS.containsKey(converterClass)) { - CUSTOM_CONVERTERS.put(converterClass, converterClass.newInstance()); - } - } catch(Exception e){ - throw new ConfigException("Custom PropertyConverter could not be loaded: " + converterClass.getName(), e); - } - } - - /** - * Evaluates the effective keys to be used. if no {@code keys} are defined, {@code memberName} is used. - * The effective keys are then combined with the sections given (if any) and only, if the given keys are not - * absolute keys (surrounded by brackets). - * @param memberName the default member name, not null. - * @param keys the keys, may be empty, or null. - * @param sections the default sections, may be empty. May also be null. - * @return the list of keys to be finally used for configuration resolution in order of - * precedence. The first keys in the list that could be successfully resolved define the final - * configuration value. - */ - public static List<String> evaluateKeys(String memberName, String[] keys, String[] sections) { - List<String> effKeys = new ArrayList<>(); - if(keys!=null){ - effKeys.addAll(Arrays.asList(keys)); - } - if (effKeys.isEmpty()) { - effKeys.add(memberName); - } - ListIterator<String> iterator = effKeys.listIterator(); - while (iterator.hasNext()) { - String next = iterator.next(); - if (next.startsWith("[") && next.endsWith("]")) { - // absolute key, strip away brackets, take key as is - iterator.set(next.substring(1, next.length() - 1)); - } else { - if (sections != null && sections.length>0) { - // Remove original entry, since it will be replaced with prefixed entries - iterator.remove(); - // Add prefixed entries, including absolute (root) entry for "" area keys. - for (String area : sections) { - iterator.add(area.isEmpty() ? next : area + '.' + next); - } - } - } - } - return effKeys; - } - - - /** - * Internally used conversion bean. - */ - private static class ConverterBean implements Bean<Object> { - - private final Bean<Object> delegate; - private final Set<Type> types; - - public ConverterBean(final Bean convBean, final Set<Type> types) { - this.types = types; - this.delegate = convBean; - } - - @Override - public Set<Type> getTypes() { - return types; - } - - @Override - public Class<?> getBeanClass() { - return delegate.getBeanClass(); - } - - @Override - public Set<InjectionPoint> getInjectionPoints() { - return delegate.getInjectionPoints(); - } - - @Override - public String getName() { - return delegate.getName(); - } - - @Override - public Set<Annotation> getQualifiers() { - return delegate.getQualifiers(); - } - - @Override - public Class<? extends Annotation> getScope() { - return delegate.getScope(); - } - - @Override - public Set<Class<? extends Annotation>> getStereotypes() { - return delegate.getStereotypes(); - } - - @Override - public boolean isAlternative() { - return delegate.isAlternative(); - } - - @Override - public boolean isNullable() { - return delegate.isNullable(); - } - - @Override - public Object create(CreationalContext<Object> creationalContext) { - return delegate.create(creationalContext); - } - - @Override - public void destroy(Object instance, CreationalContext<Object> creationalContext) { - delegate.destroy(instance, creationalContext); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java deleted file mode 100644 index bfbb51a..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/ConfigurationProducer.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.ConfigOperator; -import org.apache.tamaya.Configuration; -import org.apache.tamaya.ConfigurationProvider; -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.inject.api.Config; -import org.apache.tamaya.inject.api.ConfigDefaultSections; -import org.apache.tamaya.inject.api.DynamicValue; -import org.apache.tamaya.inject.api.WithConfigOperator; -import org.apache.tamaya.inject.api.WithPropertyConverter; -import org.apache.tamaya.spi.ConversionContext; -import org.apache.tamaya.spi.PropertyConverter; - -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Produces; -import javax.enterprise.inject.spi.InjectionPoint; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Field; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Producer bean for configuration properties. - */ -@ApplicationScoped -public class ConfigurationProducer { - - private static final Logger LOGGER = Logger.getLogger(ConfigurationProducer.class.getName()); - - private DynamicValue createynamicValue(final InjectionPoint injectionPoint) { - Member member = injectionPoint.getMember(); - if (member instanceof Field) { - return DefaultDynamicValue.of((Field) member, ConfigurationProvider.getConfiguration()); - } else if (member instanceof Method) { - return DefaultDynamicValue.of((Method) member, ConfigurationProvider.getConfiguration()); - } - return null; - } - - @Produces - @Config - public Object resolveAndConvert(final InjectionPoint injectionPoint) { - if (DynamicValue.class.equals(injectionPoint.getAnnotated().getBaseType())) { - return createynamicValue(injectionPoint); - } - final Config annotation = injectionPoint.getAnnotated().getAnnotation(Config.class); - final ConfigDefaultSections typeAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefaultSections.class); - final List<String> keys = ConfigurationExtension.evaluateKeys(injectionPoint.getMember().getName(), - annotation != null ? annotation.value() : null, - typeAnnot != null ? typeAnnot.value() : null); - - final WithConfigOperator withOperatorAnnot = injectionPoint.getAnnotated().getAnnotation(WithConfigOperator.class); - ConfigOperator operator = null; - if (withOperatorAnnot != null) { - operator = ConfigurationExtension.CUSTOM_OPERATORS.get(withOperatorAnnot.value()); - } - PropertyConverter customConverter = null; - final WithPropertyConverter withConverterAnnot = injectionPoint.getAnnotated().getAnnotation(WithPropertyConverter.class); - if (withConverterAnnot != null) { - customConverter = ConfigurationExtension.CUSTOM_CONVERTERS.get(withConverterAnnot.value()); - } - - // unless the extension is not installed, this should never happen because the extension - // enforces the resolvability of the config - Configuration config = ConfigurationProvider.getConfiguration(); - if (operator != null) { - config = operator.operate(config); - } - final Class<?> toType = (Class<?>) injectionPoint.getAnnotated().getBaseType(); - String textValue = null; - String defaultTextValue = annotation.defaultValue().isEmpty() ? null : annotation.defaultValue(); - String keyFound = null; - for (String key : keys) { - textValue = config.get(key); - if (textValue != null) { - keyFound = key; - break; - } - } - ConversionContext.Builder builder = new ConversionContext.Builder(config, - ConfigurationProvider.getConfiguration().getContext(), keyFound, TypeLiteral.of(toType)); - if (injectionPoint.getMember() instanceof AnnotatedElement) { - builder.setAnnotatedElement((AnnotatedElement) injectionPoint.getMember()); - } - ConversionContext conversionContext = builder.build(); - Object value = null; - if (keyFound != null) { - if (customConverter != null) { - value = customConverter.convert(textValue, conversionContext); - } - if (value == null) { - value = config.get(keyFound, toType); - } - } else if (defaultTextValue != null) { - value = defaultTextValue; - if (customConverter != null) { - value = customConverter.convert((String)value, conversionContext); - } - if (value != null) { - List<PropertyConverter<Object>> converters = ConfigurationProvider.getConfiguration().getContext() - .getPropertyConverters(TypeLiteral.of(toType)); - for (PropertyConverter<Object> converter : converters) { - try { - value = converter.convert(defaultTextValue, conversionContext); - if (value != null) { - LOGGER.log(Level.FINEST, "Parsed default value from '" + defaultTextValue + "' into " + - injectionPoint); - break; - } - } catch (Exception e) { - LOGGER.log(Level.FINEST, "Failed to convert default value '" + defaultTextValue + "' for " + - injectionPoint, e); - } - } - } - } - if (value == null) { - throw new ConfigException(String.format( - "Can't resolve any of the possible config keys: %s to the required target type: %s, supported formats: %s", - keys.toString(), toType.getName(), conversionContext.getSupportedFormats().toString())); - } - LOGGER.finest(String.format("Injecting %s for key %s in class %s", keyFound, value.toString(), injectionPoint.toString())); - return value; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java b/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java deleted file mode 100644 index a06feb8..0000000 --- a/modules/injection/cdi-ee/src/main/java/org/apache/tamaya/integration/cdi/DefaultDynamicValue.java +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.tamaya.integration.cdi; - -import org.apache.tamaya.ConfigException; -import org.apache.tamaya.Configuration; -import org.apache.tamaya.TypeLiteral; -import org.apache.tamaya.inject.spi.BaseDynamicValue; -import org.apache.tamaya.inject.api.DynamicValue; -import org.apache.tamaya.inject.spi.InjectionUtils; -import org.apache.tamaya.inject.api.LoadPolicy; -import org.apache.tamaya.inject.api.UpdatePolicy; -import org.apache.tamaya.inject.api.WithPropertyConverter; -import org.apache.tamaya.spi.ConversionContext; -import org.apache.tamaya.spi.PropertyConverter; - -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.logging.Logger; - -/** - * A accessor for a single configured value. This can be used to support values that may change during runtime, - * reconfigured or final. Hereby external code (could be Tamaya configuration listners or client code), can set a - * new value. Depending on the {@link UpdatePolicy} the new value is immedeately active or it requires an active commit - * by client code. Similarly an instance also can ignore all later changes to the value. - * <h3>Implementation Details</h3> - * This class is - * <ul> - * <li>Serializable, when also the item stored is serializable</li> - * <li>Thread safe</li> - * </ul> - * - * @param <T> The type of the value. - */ -final class DefaultDynamicValue<T> extends BaseDynamicValue<T> { - - private static final long serialVersionUID = -2071172847144537443L; - - /** - * The property name of the entry. - */ - private final String propertyName; - /** - * The keys to be resolved. - */ - private final String[] keys; - /** - * Back reference to the base configuration instance. This reference is used reevalaute the given property and - * compare the result with the previous value after a configuration change was triggered. - */ - private final Configuration configuration; - /** - * The target type of the property used to lookup a matching {@link PropertyConverter}. - * If null, {@code propertyConverter} is set and used instead. - */ - private final TypeLiteral<T> targetType; - /** - * The property converter to be applied, may be null. In the ladder case targetType is not null. - */ - private final PropertyConverter<T> propertyConverter; - /** - * Policy that defines how new values are applied, be default it is applied initially once, but never updated - * anymore. - */ - private UpdatePolicy updatePolicy; - /** - * Load policy. - */ - private final LoadPolicy loadPolicy; - - /** - * The current value, never null. - */ - private transient T value; - /** - * The new value, or null. - */ - private transient Object[] newValue; - /** - * List of listeners that listen for changes. - */ - private transient WeakList<PropertyChangeListener> listeners; - - /** - * Constructor. - * - * @param propertyName the name of the fields' property/method. - * @param keys the keys of the property, not null. - * @param configuration the configuration, not null. - * @param targetType the target type, not null. - * @param propertyConverter the optional converter to be used. - */ - private DefaultDynamicValue(String propertyName, Configuration configuration, TypeLiteral<T> targetType, - PropertyConverter<T> propertyConverter, List<String> keys, LoadPolicy loadPolicy, - UpdatePolicy updatePolicy) { - this.propertyName = Objects.requireNonNull(propertyName); - this.keys = keys.toArray(new String[keys.size()]); - this.configuration = Objects.requireNonNull(configuration); - this.propertyConverter = propertyConverter; - this.targetType = targetType; - this.loadPolicy = Objects.requireNonNull(loadPolicy); - this.updatePolicy = Objects.requireNonNull(updatePolicy); - if(loadPolicy == LoadPolicy.INITIAL){ - this.value = evaluateValue(); - } - } - - public static DynamicValue of(Field annotatedField, Configuration configuration) { - return of(annotatedField, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDIATE); - } - - public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy) { - return of(annotatedField, configuration, loadPolicy, UpdatePolicy.IMMEDIATE); - } - - public static DynamicValue of(Field annotatedField, Configuration configuration, UpdatePolicy updatePolicy) { - return of(annotatedField, configuration, LoadPolicy.ALWAYS, updatePolicy); - } - - public static DynamicValue of(Field annotatedField, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) { - // Check for adapter/filter - Type targetType = annotatedField.getGenericType(); - if (targetType == null) { - throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName() - + '.' + annotatedField.getName()); - } - if (targetType instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) targetType; - Type[] types = pt.getActualTypeArguments(); - if (types.length != 1) { - throw new ConfigException("Failed to evaluate target type for " + annotatedField.getDeclaringClass().getName() - + '.' + annotatedField.getName()); - } - targetType = types[0]; - } - PropertyConverter<?> propertyConverter = null; - WithPropertyConverter annot = annotatedField.getAnnotation(WithPropertyConverter.class); - if (annot != null) { - try { - propertyConverter = annot.value().newInstance(); - } catch (Exception e) { - throw new ConfigException("Failed to instantiate annotated PropertyConverter on " + - annotatedField.getDeclaringClass().getName() - + '.' + annotatedField.getName(), e); - } - } - List<String> keys = InjectionUtils.getKeys(annotatedField); - return new DefaultDynamicValue(annotatedField.getName(), configuration, - TypeLiteral.of(targetType), propertyConverter, keys, loadPolicy, updatePolicy); - } - - public static DynamicValue of(Method method, Configuration configuration) { - return of(method, configuration, LoadPolicy.ALWAYS, UpdatePolicy.IMMEDIATE); - } - - public static DynamicValue of(Method method, Configuration configuration, UpdatePolicy updatePolicy) { - return of(method, configuration, LoadPolicy.ALWAYS, updatePolicy); - } - - public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy) { - return of(method, configuration, loadPolicy, UpdatePolicy.IMMEDIATE); - } - - public static DynamicValue of(Method method, Configuration configuration, LoadPolicy loadPolicy, UpdatePolicy updatePolicy) { - // Check for adapter/filter - Type targetType = method.getGenericReturnType(); - if (targetType == null) { - throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass() - .getName() + '.' + method.getName()); - } - if (targetType instanceof ParameterizedType) { - ParameterizedType pt = (ParameterizedType) targetType; - Type[] types = pt.getActualTypeArguments(); - if (types.length != 1) { - throw new ConfigException("Failed to evaluate target type for " + method.getDeclaringClass() - .getName() + '.' + method.getName()); - } - targetType = types[0]; - } - PropertyConverter<Object> propertyConverter = null; - WithPropertyConverter annot = method.getAnnotation(WithPropertyConverter.class); - if (annot != null) { - try { - propertyConverter = (PropertyConverter<Object>) annot.value().newInstance(); - } catch (Exception e) { - throw new ConfigException("Failed to instantiate annotated PropertyConverter on " + - method.getDeclaringClass().getName() - + '.' + method.getName(), e); - } - } - return new DefaultDynamicValue<>(method.getName(), - configuration, TypeLiteral.of(targetType), propertyConverter, InjectionUtils.getKeys(method), - loadPolicy, updatePolicy); - } - - - /** - * Commits a new value that has not been committed yet, make it the new value of the instance. On change any - * registered listeners will be triggered. - */ - public void commit() { - T oldValue = value; - value = newValue==null?null:(T)newValue[0]; - newValue = null; - informListeners(oldValue, value); - } - - private void informListeners(T value, T newValue) { - synchronized (this) { - PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, value, - newValue); - if (listeners != null) { - for (PropertyChangeListener consumer : listeners.get()) { - consumer.propertyChange(evt); - } - } - } - } - - /** - * Discards a new value that was published. No listeners will be informed. - */ - public void discard() { - newValue = null; - } - - - /** - * Access the {@link UpdatePolicy} used for updating this value. - * - * @return the update policy, never null. - */ - public UpdatePolicy getUpdatePolicy() { - return updatePolicy; - } - - /** - * Sets a new {@link UpdatePolicy}. - * - * @param updatePolicy the new policy, not null. - */ - public void setUpdatePolicy(UpdatePolicy updatePolicy) { - this.updatePolicy = Objects.requireNonNull(updatePolicy); - } - - /** - * Add a listener to be called as weak reference, when this value has been changed. - * - * @param l the listener, not null - */ - public void addListener(PropertyChangeListener l) { - if (listeners == null) { - listeners = new WeakList<>(); - } - listeners.add(l); - } - - /** - * Removes a listener to be called, when this value has been changed. - * - * @param l the listner to be removed, not null - */ - public void removeListener(PropertyChangeListener l) { - if (listeners != null) { - listeners.remove(l); - } - } - - /** - * If a value is present in this {@code DynamicValue}, returns the value, - * otherwise throws {@code ConfigException}. - * - * @return the non-null value held by this {@code Optional} - * @throws ConfigException if there is no value present - * @see DefaultDynamicValue#isPresent() - */ - public T get() { - T newLocalValue; - if(loadPolicy!=LoadPolicy.INITIAL) { - newLocalValue = evaluateValue(); - if (this.value == null) { - this.value = newLocalValue; - } - if(!Objects.equals(this.value, newLocalValue)){ - switch (updatePolicy){ - case IMMEDEATE: - case IMMEDIATE: - commit(); - break; - case EXPLCIT: - case EXPLICIT: - this.newValue = new Object[]{newLocalValue}; - break; - case LOG_ONLY: - informListeners(this.value, newLocalValue); - this.newValue = null; - break; - case NEVER: - this.newValue = null; - break; - default: - this.newValue = null; - break; - } - } - } - return value; - } - - /** - * Method to check for and apply a new value. Depending on the {@link UpdatePolicy} - * the value is immediately or deferred visible (or it may even be ignored completely). - * - * @return true, if a new value has been detected. The value may not be visible depending on the current - * {@link UpdatePolicy} in place. - */ - public boolean updateValue() { - if(this.value==null && this.newValue==null){ - this.value = evaluateValue(); - return false; - } - T newValue = evaluateValue(); - if (Objects.equals(newValue, this.value)) { - return false; - } - switch (this.updatePolicy) { - case LOG_ONLY: - Logger.getLogger(getClass().getName()).info("Discard change on " + this + ", newValue=" + newValue); - informListeners(value, newValue); - this.newValue = null; - break; - case NEVER: - this.newValue = null; - break; - case EXPLCIT: - case IMMEDEATE: - default: - this.newValue = new Object[]{newValue}; - commit(); - break; - } - return true; - } - - /** - * Evaluates the current value dynamically from the underlying configuration. - * - * @return the current actual value, or null. - */ - public T evaluateValue() { - T value = null; - - for (String key : keys) { - if (propertyConverter == null) { - value = configuration.get(key, targetType); - } else { - String source = configuration.get(key); - ConversionContext ctx = new ConversionContext.Builder(configuration, - configuration.getContext(), key, targetType).build(); - value = propertyConverter.convert(source, ctx); - } - - if (value != null) { - break; - } - } - - return value; - } - - /** - * Access a new value that has not yet been committed. - * - * @return the uncommitted new value, or null. - */ - public T getNewValue() { - T nv = newValue==null?null:(T)newValue[0]; - if (nv != null) { - return nv; - } - return null; - } - - - /** - * Serialization implementation that strips away the non serializable Optional part. - * - * @param oos the output stream - * @throws IOException if serialization fails. - */ - private void writeObject(ObjectOutputStream oos) throws IOException { - oos.writeObject(getUpdatePolicy()); - oos.writeObject(get()); - } - - /** - * Reads an instance from the input stream. - * - * @param ois the object input stream - * @throws IOException if deserialization fails. - * @throws ClassNotFoundException - */ - private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { - this.updatePolicy = (UpdatePolicy) ois.readObject(); - if (isPresent()) { - this.value = (T) ois.readObject(); - } - newValue = null; - } - - - /** - * Simple helper that allows keeping the listeners registered as weak references, hereby avoiding any - * memory leaks. - * - * @param <I> the type - */ - private class WeakList<I> { - final List<WeakReference<I>> refs = new LinkedList<>(); - - /** - * Adds a new instance. - * - * @param t the new instance, not null. - */ - void add(I t) { - refs.add(new WeakReference<>(t)); - } - - /** - * Removes a instance. - * - * @param t the instance to be removed. - */ - void remove(I t) { - synchronized (refs) { - for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) { - WeakReference<I> ref = iterator.next(); - I instance = ref.get(); - if (instance == null || instance == t) { - iterator.remove(); - break; - } - } - } - } - - - /** - * Access a list (copy) of the current instances that were not discarded by the GC. - * - * @return the list of accessible items. - */ - public List<I> get() { - synchronized (refs) { - List<I> res = new ArrayList<>(); - for (Iterator<WeakReference<I>> iterator = refs.iterator(); iterator.hasNext(); ) { - WeakReference<I> ref = iterator.next(); - I instance = ref.get(); - if (instance == null) { - iterator.remove(); - } else { - res.add(instance); - } - } - return res; - } - } - } - - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension deleted file mode 100644 index e82118a..0000000 --- a/modules/injection/cdi-ee/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension +++ /dev/null @@ -1,19 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 current 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. -# -org.apache.tamaya.integration.cdi.ConfigurationExtension \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java deleted file mode 100644 index 6bfda3a..0000000 --- a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerFailedInjectionTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.openejb.OpenEjbContainer; -import org.junit.Test; - -import javax.ejb.embeddable.EJBContainer; - -public class ConfigurationProducerFailedInjectionTest { - - @Test(expected = OpenEjbContainer.AssembleApplicationException.class) - public void notFoundShouldNotDeploy() { - // this explicitly tests that a non resolvable config makes - // the deployment fail and we won't have any failure at runtime - EJBContainer.createEJBContainer(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java deleted file mode 100644 index d128191..0000000 --- a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationProducerTest.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.tamaya.integration.cdi; - -import org.apache.openejb.jee.EjbJar; -import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.testing.Classes; -import org.apache.openejb.testing.Module; -import org.apache.tamaya.inject.api.Config; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.tomitribe.util.Duration; - -import javax.inject.Inject; -import java.io.File; - -import static org.junit.Assert.*; - -@RunWith(ApplicationComposer.class) -public class ConfigurationProducerTest { - - @Module - @Classes(cdi = true, value = { - AllTypes.class, - ConfigurationExtension.class, - ConfigurationProducer.class - }) - public EjbJar jar() { - return new EjbJar("config"); - } - - @Inject - private AllTypes allTypes; - - @Test - public void defaultValues() { - assertNotNull(allTypes); - assertEquals("defaultString", allTypes.getDefaultString()); - assertEquals(new File("./"), allTypes.getDefaultFile()); - assertEquals(new Duration("2 hours and 54 minutes"), allTypes.getDefaultDuration()); - assertEquals(true, allTypes.getDefaultBoolean()); - assertEquals(45, (int) allTypes.getDefaultInteger()); - } - - @Test - public void actualPropertyValues() { - assertNotNull(allTypes); - assertEquals("hello", allTypes.getString()); - assertEquals(new File("./conf"), allTypes.getFile()); - assertEquals(new Duration("10 minutes and 57 seconds"), allTypes.getDuration()); - assertEquals(true, allTypes.getaBoolean()); - assertEquals(123, (int) allTypes.getInteger()); - } - - static class AllTypes { - - @Inject - @Config(value = "string.value", defaultValue = "defaultString") - private String string; - - @Inject - @Config(value = "defaultString.value", defaultValue = "defaultString") - private String defaultString; - - @Inject - @Config(value = "file.value", defaultValue = "./") - private File file; - - @Inject - @Config(value = "defaultFile.value", defaultValue = "./") - private File defaultFile; - - @Inject - @Config(value = "duration.value", defaultValue = "2 hours and 54 minutes") - private Duration duration; - - @Inject - @Config(value = "defaultDuration.value", defaultValue = "2 hours and 54 minutes") - private Duration defaultDuration; - - @Inject - @Config(value = "boolean.value", defaultValue = "true") - private Boolean aBoolean; - - @Inject - @Config(value = "defaultBoolean.value", defaultValue = "true") - private Boolean defaultBoolean; - - @Inject - @Config(value = "integer.value", defaultValue = "45") - private Integer integer; - - @Inject - @Config(value = "defaultInteger.value", defaultValue = "45") - private Integer defaultInteger; - - public String getString() { - return string; - } - - public File getFile() { - return file; - } - - public Duration getDuration() { - return duration; - } - - public Boolean getaBoolean() { - return aBoolean; - } - - public Integer getInteger() { - return integer; - } - - public String getDefaultString() { - return defaultString; - } - - public File getDefaultFile() { - return defaultFile; - } - - public Duration getDefaultDuration() { - return defaultDuration; - } - - public Boolean getDefaultBoolean() { - return defaultBoolean; - } - - public Integer getDefaultInteger() { - return defaultInteger; - } - - @Override - public String toString() { - return "AllTypes{" + - "string='" + string + '\'' + - ", defaultString='" + defaultString + '\'' + - ", file=" + file + - ", defaultFile=" + defaultFile + - ", duration=" + duration + - ", defaultDuration=" + defaultDuration + - ", aBoolean=" + aBoolean + - ", defaultBoolean=" + defaultBoolean + - ", integer=" + integer + - ", defaultInteger=" + defaultInteger + - '}'; - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/b3bcddcb/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java ---------------------------------------------------------------------- diff --git a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java b/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java deleted file mode 100644 index 1c551b2..0000000 --- a/modules/injection/cdi-ee/src/test/java/org/apache/tamaya/integration/cdi/ConfigurationResolverTest.java +++ /dev/null @@ -1,112 +0,0 @@ -///* -// * Licensed to the Apache Software Foundation (ASF) under one or more -// * contributor license agreements. See the NOTICE file distributed with -// * this work for additional information regarding copyright ownership. -// * The ASF licenses this file to You 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.tamaya.integration.cdi; -// -//import org.apache.openejb.loader.SystemInstance; -//import org.junit.Before; -//import org.junit.Test; -// -//import static org.junit.Assert.*; -// -//public class ConfigurationResolverTest { -// -// private ConfigurationResolver resolver; -// -// @Before -// public void cleanEnv() { -// SystemInstance.reset(); -// System.clearProperty("environment"); -// -// resolver = new ConfigurationResolver(); -// } -// -// @Test -// public void defaultEnvironment() { -// assertEquals("test", resolver.getEnvironment()); -// } -// -// @Test -// public void overrideDefaultEnvironment() { -// System.setProperty("environment", "dev"); -// -// // don't use the field cause before is invoked before we have a chance to set the environment -// assertEquals("dev", new ConfigurationResolver().getEnvironment()); -// } -// -// @Test -// public void isResolvable() { -// -// { // precondition -// try { -// resolver.isResolvableConfig(null, "value"); -// fail("a null key is not resolvable"); -// -// } catch (final NullPointerException e) { -// // expected -// } -// } -// { // precondition -// try { -// resolver.isResolvableConfig("key", null); -// fail("a null default value is not resolvable"); -// -// } catch (final NullPointerException e) { -// // expected -// } -// } -// -// // loaded from test.properties -// assertTrue(resolver.isResolvableConfig("remote.wsdl.location", "")); -// assertFalse(resolver.isResolvableConfig("something", "")); -// -// // loaded from base.properties -// assertTrue(resolver.isResolvableConfig("remote.username", "")); -// assertFalse(resolver.isResolvableConfig("bla", "")); -// } -// -// @Test -// public void found() { -// -// { // precondition -// try { -// resolver.isResolvableConfig(null, "value"); -// fail("a null key is not resolvable"); -// -// } catch (final NullPointerException e) { -// // expected -// } -// } -// { // precondition -// try { -// resolver.isResolvableConfig("key", null); -// fail("a null default value is not resolvable"); -// -// } catch (final NullPointerException e) { -// // expected -// } -// } -// -// // loaded from test.properties -// assertEquals("classpath:/service-wsdl.xml", resolver.resolve("remote.wsdl.location", "")); -// assertEquals("something-else", resolver.resolve("something", "something-else")); -// -// // loaded from base.properties -// assertEquals("joecool", resolver.resolve("remote.username", "")); -// assertEquals("blabla", resolver.resolve("bla", "blabla")); -// } -// -//}
