You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2016/10/30 22:06:29 UTC
[07/15] incubator-tamaya-extensions git commit: TAMAYA-189: Moved
format and injection modules into separate subtrees.
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/pom.xml b/modules/injection/cdi-se/pom.xml
new file mode 100644
index 0000000..848b95e
--- /dev/null
+++ b/modules/injection/cdi-se/pom.xml
@@ -0,0 +1,212 @@
+<!--
+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-se</artifactId>
+ <groupId>tamaya-integration</groupId>
+ <name>Apache Tamaya Modules - Injection CDI (Direct)</name>
+ <packaging>bundle</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>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>prepare-agent</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.apache.tamaya.integration.cdi.config
+ </Export-Package>
+ <Private-Package>
+ org.apache.tamaya.integration.cdi.internal
+ </Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <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.ext</groupId>
+ <artifactId>tamaya-classloader-support</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tamaya.ext</groupId>
+ <artifactId>tamaya-spisupport</artifactId>
+ <version>${project.version}</version>
+ </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-injection</artifactId>
+ <version>${project.version}</version>
+ </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>
+ <activation>
+ <activeByDefault>true</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>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-annotation_1.2_spec</artifactId>
+ <version>1.0</version>
+ <scope>provided</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>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.weld.se</groupId>
+ <artifactId>weld-se</artifactId>
+ <version>${weld.version}</version>
+ </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/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
new file mode 100644
index 0000000..566d00e
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/CDIAwareServiceContext.java
@@ -0,0 +1,169 @@
+/*
+ * 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.text.MessageFormat;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * <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;
+ }
+
+ /**
+ * 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 javax.annotation.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/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java
new file mode 100644
index 0000000..ae1f0bf
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContext.java
@@ -0,0 +1,296 @@
+/*
+ * 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.ConfigurationProvider;
+import org.apache.tamaya.TypeLiteral;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.PropertyFilter;
+import org.apache.tamaya.spi.PropertySource;
+import org.apache.tamaya.spi.PropertySourceProvider;
+import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Vetoed;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Default Implementation of a simple ConfigurationContext.
+ */
+@SuppressWarnings("FieldCanBeLocal")
+@Vetoed
+public class DefaultConfigurationContext implements ConfigurationContext {
+ /** The logger used. */
+ private final static Logger LOG = Logger.getLogger(DefaultConfigurationContext.class.getName());
+ /**
+ * Cubcomponent handling {@link PropertyConverter} instances.
+ */
+ private final PropertyConverterManager propertyConverterManager = new PropertyConverterManager();
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertySource} instances.
+ */
+ private List<PropertySource> immutablePropertySources;
+
+ /**
+ * The current unmodifiable list of loaded {@link PropertyFilter} instances.
+ */
+ private List<PropertyFilter> immutablePropertyFilters;
+
+ /**
+ * The overriding policy used when combining PropertySources registered to evalute the final configuration
+ * values.
+ */
+ private PropertyValueCombinationPolicy propertyValueCombinationPolicy;
+
+ /**
+ * Lock for internal synchronization.
+ */
+ private final ReentrantReadWriteLock propertySourceLock = new ReentrantReadWriteLock();
+
+ /** Comparator used for ordering property sources. */
+ private final PropertySourceComparator propertySourceComparator = new PropertySourceComparator();
+
+ /** Comparator used for ordering property filters. */
+ private final PropertyFilterComparator propertyFilterComparator = new PropertyFilterComparator();
+
+
+ /**
+ * The first time the Configuration system gets invoked we do initialize
+ * all our {@link PropertySource}s and
+ * {@link PropertyFilter}s which are known at startup.
+ */
+ public DefaultConfigurationContext() {
+ List<PropertySource> propertySources = new ArrayList<>();
+
+ // first we load all PropertySources which got registered via java.util.ServiceLoader
+ propertySources.addAll(ServiceContextManager.getServiceContext().getServices(PropertySource.class));
+
+ // after that we add all PropertySources which get dynamically registered via their PropertySourceProviders
+ propertySources.addAll(evaluatePropertySourcesFromProviders());
+
+ // now sort them according to their ordinal values
+ Collections.sort(propertySources, new PropertySourceComparator());
+
+ immutablePropertySources = Collections.unmodifiableList(propertySources);
+ LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+ immutablePropertySources);
+
+ // as next step we pick up the PropertyFilters pretty much the same way
+ List<PropertyFilter> propertyFilters = new ArrayList<>();
+ propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+ Collections.sort(propertyFilters, new PropertyFilterComparator());
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ if(propertyValueCombinationPolicy==null) {
+ propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ }
+ LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+ }
+
+ DefaultConfigurationContext(ConfigurationContextBuilder builder) {
+ List<PropertySource> propertySources = new ArrayList<>();
+ // first we load all PropertySources which got registered via java.util.ServiceLoader
+ propertySources.addAll(builder.getPropertySources());
+ // now sort them according to their ordinal values
+ Collections.sort(propertySources, propertySourceComparator);
+ immutablePropertySources = Collections.unmodifiableList(propertySources);
+ LOG.info("Registered " + immutablePropertySources.size() + " property sources: " +
+ immutablePropertySources);
+
+ // as next step we pick up the PropertyFilters pretty much the same way
+ List<PropertyFilter> propertyFilters = new ArrayList<>();
+ propertyFilters.addAll(ServiceContextManager.getServiceContext().getServices(PropertyFilter.class));
+ Collections.sort(propertyFilters, propertyFilterComparator);
+ immutablePropertyFilters = Collections.unmodifiableList(propertyFilters);
+ LOG.info("Registered " + immutablePropertyFilters.size() + " property filters: " +
+ immutablePropertyFilters);
+
+ propertyValueCombinationPolicy = ServiceContextManager.getServiceContext().getService(PropertyValueCombinationPolicy.class);
+ if(propertyValueCombinationPolicy==null){
+ propertyValueCombinationPolicy = PropertyValueCombinationPolicy.DEFAULT_OVERRIDING_COLLECTOR;
+ }
+ LOG.info("Using PropertyValueCombinationPolicy: " + propertyValueCombinationPolicy);
+ }
+
+
+
+ /**
+ * Pick up all {@link PropertySourceProvider}s and return all the
+ * {@link PropertySource}s they like to register.
+ */
+ private Collection<? extends PropertySource> evaluatePropertySourcesFromProviders() {
+ List<PropertySource> propertySources = new ArrayList<>();
+ Collection<PropertySourceProvider> propertySourceProviders = ServiceContextManager.getServiceContext().getServices(PropertySourceProvider.class);
+ for (PropertySourceProvider propertySourceProvider : propertySourceProviders) {
+ Collection<PropertySource> sources = propertySourceProvider.getPropertySources();
+ LOG.finer("PropertySourceProvider " + propertySourceProvider.getClass().getName() +
+ " provided the following property sources: " + sources);
+ propertySources.addAll(sources);
+ }
+
+ return propertySources;
+ }
+
+ @Override
+ public void addPropertySources(PropertySource... propertySourcesToAdd) {
+ Lock writeLock = propertySourceLock.writeLock();
+ try {
+ writeLock.lock();
+ List<PropertySource> newPropertySources = new ArrayList<>(this.immutablePropertySources);
+ newPropertySources.addAll(Arrays.asList(propertySourcesToAdd));
+ Collections.sort(newPropertySources, new PropertySourceComparator());
+
+ this.immutablePropertySources = Collections.unmodifiableList(newPropertySources);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Comparator used for ordering PropertySources.
+ */
+ private static class PropertySourceComparator implements Comparator<PropertySource>, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Order property source reversely, the most important come first.
+ *
+ * @param source1 the first PropertySource
+ * @param source2 the second PropertySource
+ * @return the comparison result.
+ */
+ private int comparePropertySources(PropertySource source1, PropertySource source2) {
+ if (source1.getOrdinal() < source2.getOrdinal()) {
+ return -1;
+ } else if (source1.getOrdinal() > source2.getOrdinal()) {
+ return 1;
+ } else {
+ return source1.getClass().getName().compareTo(source2.getClass().getName());
+ }
+ }
+
+ @Override
+ public int compare(PropertySource source1, PropertySource source2) {
+ return comparePropertySources(source1, source2);
+ }
+ }
+
+ /**
+ * Comparator used for ordering PropertyFilters.
+ */
+ private static class PropertyFilterComparator implements Comparator<PropertyFilter>, Serializable{
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Compare 2 filters for ordering the filter chain.
+ *
+ * @param filter1 the first filter
+ * @param filter2 the second filter
+ * @return the comparison result
+ */
+ private int comparePropertyFilters(PropertyFilter filter1, PropertyFilter filter2) {
+ Priority prio1 = filter1.getClass().getAnnotation(Priority.class);
+ Priority prio2 = filter2.getClass().getAnnotation(Priority.class);
+ int ord1 = prio1 != null ? prio1.value() : 0;
+ int ord2 = prio2 != null ? prio2.value() : 0;
+
+ if (ord1 < ord2) {
+ return -1;
+ } else if (ord1 > ord2) {
+ return 1;
+ } else {
+ return filter1.getClass().getName().compareTo(filter2.getClass().getName());
+ }
+ }
+
+ @Override
+ public int compare(PropertyFilter filter1, PropertyFilter filter2) {
+ return comparePropertyFilters(filter1, filter2);
+ }
+ }
+
+ @Override
+ public List<PropertySource> getPropertySources() {
+ return immutablePropertySources;
+ }
+
+ @Override
+ public PropertySource getPropertySource(String name) {
+ for(PropertySource ps:getPropertySources()){
+ if(ps.getName().equals(name)){
+ return ps;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public <T> void addPropertyConverter(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+ propertyConverterManager.register(typeToConvert, propertyConverter);
+ LOG.info("Added PropertyConverter: " + propertyConverter.getClass().getName());
+ }
+
+ @Override
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ return propertyConverterManager.getPropertyConverters();
+ }
+
+ @Override
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ return propertyConverterManager.getPropertyConverters(targetType);
+ }
+
+ @Override
+ public List<PropertyFilter> getPropertyFilters() {
+ return immutablePropertyFilters;
+ }
+
+ @Override
+ public PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(){
+ return propertyValueCombinationPolicy;
+ }
+
+ @Override
+ public ConfigurationContextBuilder toBuilder() {
+ return ConfigurationProvider.getConfigurationContextBuilder().setContext(this);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java
new file mode 100644
index 0000000..c2dc83e
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/DefaultConfigurationContextBuilder.java
@@ -0,0 +1,152 @@
+///*
+// * 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.TypeLiteral;
+//import org.apache.tamaya.spi.ConfigurationContext;
+//import org.apache.tamaya.spi.ConfigurationContextBuilder;
+//import org.apache.tamaya.spi.PropertyConverter;
+//import org.apache.tamaya.spi.PropertyFilter;
+//import org.apache.tamaya.spi.PropertySource;
+//import org.apache.tamaya.spi.PropertyValueCombinationPolicy;
+//
+//import javax.enterprise.inject.Vetoed;
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//import java.util.Collection;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Objects;
+//
+///**
+// * Default implementation of {@link ConfigurationContextBuilder}.
+// */
+//@Vetoed
+//public class DefaultConfigurationContextBuilder implements ConfigurationContextBuilder {
+//
+// final Map<String, PropertySource> propertySources = new HashMap<>();
+// final List<PropertyFilter> propertyFilters = new ArrayList<>();
+// final Map<TypeLiteral<?>, List<PropertyConverter<?>>> propertyConverters = new HashMap<>();
+// PropertyValueCombinationPolicy combinationPolicy;
+//
+// @Override
+// public ConfigurationContextBuilder setContext(ConfigurationContext context) {
+// this.propertySources.clear();
+// for(PropertySource ps:context.getPropertySources()) {
+// this.propertySources.put(ps.getName(), ps);
+// }
+// this.propertyFilters.clear();
+// this.propertyFilters.addAll(context.getPropertyFilters());
+// this.propertyConverters.clear();
+// this.propertyConverters.putAll(context.getPropertyConverters());
+// this.combinationPolicy = context.getPropertyValueCombinationPolicy();
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertySources(Collection<PropertySource> propertySourcesToAdd) {
+// for(PropertySource ps:propertySourcesToAdd){
+// if(this.propertySources.containsKey(ps.getName())){
+// throw new ConfigException("Duplicate PropertySource: " + ps.getName());
+// }
+// }
+// for(PropertySource ps:propertySourcesToAdd) {
+// this.propertySources.put(ps.getName(), ps);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertySources(PropertySource... propertySourcesToAdd) {
+// return addPropertySources(Arrays.asList(propertySourcesToAdd));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertySources(Collection<String> propertySourcesToRemove) {
+// for(String key: propertySourcesToRemove){
+// this.propertySources.remove(key);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertySources(String... propertySourcesToRemove) {
+// return removePropertySources(Arrays.asList(propertySourcesToRemove));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertyFilters(Collection<PropertyFilter> filters) {
+// this.propertyFilters.addAll(filters);
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder addPropertyFilters(PropertyFilter... filters) {
+// return addPropertyFilters(Arrays.asList(filters));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyFilters(Collection<PropertyFilter> filters) {
+// this.propertyFilters.removeAll(filters);
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyFilters(PropertyFilter... filters) {
+// return removePropertyFilters(Arrays.asList(filters));
+// }
+//
+// @Override
+// public <T> ConfigurationContextBuilder addPropertyConverters(TypeLiteral<T> typeToConvert, PropertyConverter<T> propertyConverter) {
+// List<PropertyConverter<?>> converters = this.propertyConverters.get(typeToConvert);
+// if(converters==null){
+// converters = new ArrayList<>();
+// this.propertyConverters.put(typeToConvert, converters);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, PropertyConverter<?>... converters) {
+// return removePropertyConverters(typeToConvert, Arrays.asList(converters));
+// }
+//
+// @Override
+// public ConfigurationContextBuilder removePropertyConverters(TypeLiteral<?> typeToConvert, Collection<PropertyConverter<?>> converters) {
+// List<PropertyConverter<?>> existing = this.propertyConverters.get(typeToConvert);
+// if(existing!=null) {
+// existing.removeAll(converters);
+// }
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContextBuilder setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy policy) {
+// this.combinationPolicy = Objects.requireNonNull(policy);
+// return this;
+// }
+//
+// @Override
+// public ConfigurationContext build() {
+// return new DefaultConfigurationContext(this);
+// }
+//
+//}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java
new file mode 100644
index 0000000..d6ad1ba
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/EnumConverter.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+
+import javax.enterprise.inject.Vetoed;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Converter, converting from String to tge given enum type.
+ * @param <T> the enum type.
+ */
+@Vetoed
+public class EnumConverter<T> implements PropertyConverter<T> {
+ private final Logger LOG = Logger.getLogger(EnumConverter.class.getName());
+ private Class<T> enumType;
+ private Method factory;
+
+ public EnumConverter(Class<T> enumType) {
+ if (!Enum.class.isAssignableFrom(enumType)) {
+ throw new IllegalArgumentException("Not an Enum: " + enumType.getName());
+ }
+ this.enumType = Objects.requireNonNull(enumType);
+ try {
+ this.factory = enumType.getMethod("valueOf", String.class);
+ } catch (NoSuchMethodException e) {
+ throw new ConfigException("Uncovertible enum type without valueOf method found, please provide a custom " +
+ "PropertyConverter for: " + enumType.getName());
+ }
+ }
+
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(getClass(), "<enumValue>");
+ try {
+ return (T) factory.invoke(null, value);
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+ }
+ try {
+ return (T) factory.invoke(null, value.toUpperCase(Locale.ENGLISH));
+ } catch (InvocationTargetException | IllegalAccessException e) {
+ LOG.log(Level.FINEST, "Invalid enum value '" + value + "' for " + enumType.getName(), e);
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java
new file mode 100644
index 0000000..e0e35f7
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/PropertyConverterManager.java
@@ -0,0 +1,427 @@
+/*
+ * 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.TypeLiteral;
+import org.apache.tamaya.spi.ConversionContext;
+import org.apache.tamaya.spi.PropertyConverter;
+import org.apache.tamaya.spi.ServiceContextManager;
+
+import javax.enterprise.inject.Vetoed;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Logger;
+
+/**
+ * Manager that deals with {@link PropertyConverter} instances.
+ * This class is thread-safe.
+ */
+@Vetoed
+public class PropertyConverterManager {
+ /**
+ * The logger used.
+ */
+ private static final Logger LOG = Logger.getLogger(PropertyConverterManager.class.getName());
+ /**
+ * The registered converters.
+ */
+ private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> converters = new ConcurrentHashMap<>();
+ /**
+ * The transitive converters.
+ */
+ private final Map<TypeLiteral<?>, List<PropertyConverter<?>>> transitiveConverters = new ConcurrentHashMap<>();
+ /**
+ * The lock used.
+ */
+ private final ReadWriteLock lock = new ReentrantReadWriteLock();
+
+ private static final Comparator<Object> PRIORITY_COMPARATOR = new Comparator<Object>() {
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ int prio = CDIAwareServiceContext.getPriority(o1) - CDIAwareServiceContext.getPriority(o2);
+ if (prio < 0) {
+ return 1;
+ } else if (prio > 0) {
+ return -1;
+ } else {
+ return o1.getClass().getSimpleName().compareTo(o2.getClass().getSimpleName());
+ }
+ }
+ };
+
+ /**
+ * Constructor.
+ */
+ public PropertyConverterManager() {
+ initConverters();
+ }
+
+ /**
+ * Registers the default converters provided out of the box.
+ */
+ protected void initConverters() {
+ for (PropertyConverter conv : ServiceContextManager.getServiceContext().getServices(PropertyConverter.class)) {
+ Type type = TypeLiteral.getGenericInterfaceTypeParameters(conv.getClass(), PropertyConverter.class)[0];
+ register(TypeLiteral.of(type), conv);
+ }
+ }
+
+ /**
+ * Registers a ew converter instance.
+ *
+ * @param targetType the target type, not null.
+ * @param converter the converter, not null.
+ * @param <T> the type.
+ */
+ public <T> void register(TypeLiteral<T> targetType, PropertyConverter<T> converter) {
+ Objects.requireNonNull(converter);
+ Lock writeLock = lock.writeLock();
+ try {
+ writeLock.lock();
+ List converters = List.class.cast(this.converters.get(targetType));
+ List<PropertyConverter<?>> newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.converters.put(targetType, Collections.unmodifiableList(newConverters));
+ // evaluate transitive closure for all inherited supertypes and implemented interfaces
+ // direct implemented interfaces
+ for (Class<?> ifaceType : targetType.getRawType().getInterfaces()) {
+ converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+ newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+ }
+ Class<?> superClass = targetType.getRawType().getSuperclass();
+ while (superClass != null && !superClass.equals(Object.class)) {
+ converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(superClass)));
+ newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.transitiveConverters.put(TypeLiteral.of(superClass), Collections.unmodifiableList(newConverters));
+ for (Class<?> ifaceType : superClass.getInterfaces()) {
+ converters = List.class.cast(this.transitiveConverters.get(TypeLiteral.of(ifaceType)));
+ newConverters = new ArrayList<>();
+ if (converters != null) {
+ newConverters.addAll(converters);
+ }
+ newConverters.add(converter);
+ Collections.sort(newConverters, PRIORITY_COMPARATOR);
+ this.transitiveConverters.put(TypeLiteral.of(ifaceType), Collections.unmodifiableList(newConverters));
+ }
+ superClass = superClass.getSuperclass();
+ }
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Allows to evaluate if a given target type is supported.
+ *
+ * @param targetType the target type, not null.
+ * @return true, if a converter for the given type is registered, or a default one can be created.
+ */
+ public boolean isTargetTypeSupported(TypeLiteral<?> targetType) {
+ if (converters.containsKey(targetType) || transitiveConverters.containsKey(targetType)) {
+ return true;
+ }
+ return createDefaultPropertyConverter(targetType) != null;
+ }
+
+ /**
+ * Get a map of all property converters currently registered. This will not contain the converters that
+ * may be created, when an instance is adapted, which provides a String constructor or compatible
+ * factory methods taking a single String instance.
+ *
+ * @return the current map of instantiated and registered converters.
+ * @see #createDefaultPropertyConverter(TypeLiteral)
+ */
+ public Map<TypeLiteral<?>, List<PropertyConverter<?>>> getPropertyConverters() {
+ Lock readLock = lock.readLock();
+ try {
+ readLock.lock();
+ return new HashMap<>(this.converters);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * <p>Get the list of all current registered converters for the given target type.
+ * If not converters are registered, they component tries to create and register a dynamic
+ * converter based on String costructor or static factory methods available.</p>
+ *
+ * <p>The converters provided are of the following type and returned in the following order:</p>
+ * <ul>
+ * <li>Converters mapped explicitly to the required target type are returned first, ordered
+ * by decreasing priority. This means, if explicit converters are registered these are used
+ * primarly for converting a value.</li>
+ * <li>The target type of each explicitly registered converter also can be transitively mapped to
+ * 1) all directly implemented interfaces, 2) all its superclasses (except Object), 3) all the interfaces
+ * implemented by its superclasses. These groups of transitive converters is returned similarly in the
+ * order as mentioned, whereas also here a priority based decreasing ordering is applied.</li>
+ * <li>java.lang wrapper classes and native types are automatically mapped.</li>
+ * <li>If no explicit converters are registered, for Enum types a default implementation is provided that
+ * compares the configuration values with the different enum members defined (cases sensitive mapping).</li>
+ * </ul>
+ *
+ * <p>So given that list above directly registered mappings always are tried first, before any transitive mapping
+ * should be used. Also in all cases @Priority annotations are honored for ordering of the converters in place.
+ * Transitive conversion is supported for all directly implemented interfaces (including inherited ones) and
+ * the inheritance hierarchy (exception Object). Super interfaces of implemented interfaces are ignored.</p>
+ *
+ *
+ * @param targetType the target type, not null.
+ * @param <T> the type class
+ * @return the ordered list of converters (may be empty for not convertible types).
+ * @see #createDefaultPropertyConverter(TypeLiteral)
+ */
+ public <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> targetType) {
+ Lock readLock = lock.readLock();
+ List<PropertyConverter<T>> converterList = new ArrayList<>();
+ List<PropertyConverter<T>> converters;
+ // direct mapped converters
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ // transitive converter
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.transitiveConverters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ // handling of java.lang wrapper classes
+ TypeLiteral<T> boxedType = mapBoxedType(targetType);
+ if (boxedType != null) {
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(boxedType));
+ } finally {
+ readLock.unlock();
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ }
+ if (converterList.isEmpty()) {
+ // adding any converters created on the fly, e.g. for enum types.
+ PropertyConverter<T> defaultConverter = createDefaultPropertyConverter(targetType);
+ if (defaultConverter != null) {
+ register(targetType, defaultConverter);
+ try {
+ readLock.lock();
+ converters = List.class.cast(this.converters.get(targetType));
+ } finally {
+ readLock.unlock();
+ }
+ }
+ if (converters != null) {
+ converterList.addAll(converters);
+ }
+ }
+ return converterList;
+ }
+
+ /**
+ * Maps native types to the corresponding boxed types.
+ *
+ * @param targetType the native type.
+ * @param <T> the type
+ * @return the boxed type, or null.
+ */
+ private <T> TypeLiteral<T> mapBoxedType(TypeLiteral<T> targetType) {
+ Type parameterType = targetType.getType();
+ if (parameterType == int.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Integer.class));
+ }
+ if (parameterType == short.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Short.class));
+ }
+ if (parameterType == byte.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Byte.class));
+ }
+ if (parameterType == long.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Long.class));
+ }
+ if (parameterType == boolean.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+ }
+ if (parameterType == char.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Character.class));
+ }
+ if (parameterType == float.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Float.class));
+ }
+ if (parameterType == double.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Double.class));
+ }
+ if (parameterType == int[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Integer[].class));
+ }
+ if (parameterType == short[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Short[].class));
+ }
+ if (parameterType == byte[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Byte[].class));
+ }
+ if (parameterType == long[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Long[].class));
+ }
+ if (parameterType == boolean.class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Boolean.class));
+ }
+ if (parameterType == char[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Character[].class));
+ }
+ if (parameterType == float[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Float[].class));
+ }
+ if (parameterType == double[].class) {
+ return TypeLiteral.class.cast(TypeLiteral.of(Double[].class));
+ }
+ return null;
+ }
+
+ /**
+ * Creates a dynamic PropertyConverter for the given target type.
+ *
+ * @param targetType the target type
+ * @param <T> the type class
+ * @return a new converter, or null.
+ */
+ protected <T> PropertyConverter<T> createDefaultPropertyConverter(final TypeLiteral<T> targetType) {
+ if (Enum.class.isAssignableFrom(targetType.getRawType())) {
+ return new EnumConverter<>(targetType.getRawType());
+ }
+ PropertyConverter<T> converter = null;
+ final Method factoryMethod = getFactoryMethod(targetType.getRawType(), "of", "valueOf", "instanceOf", "getInstance", "from", "fromString", "parse");
+ if (factoryMethod != null) {
+ converter = new PropertyConverter<T>() {
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(PropertyConverter.class, "static T of(String)", "static T valueOf(String)",
+ "static T getInstance(String)", "static T from(String)",
+ "static T fromString(String)", "static T parse(String)");
+ try {
+ if (!Modifier.isStatic(factoryMethod.getModifiers())) {
+ throw new ConfigException(factoryMethod.toGenericString() +
+ " is not a static method. Only static " +
+ "methods can be used as factory methods.");
+ }
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ factoryMethod.setAccessible(true);
+ return null;
+ }
+ });
+ Object invoke = factoryMethod.invoke(null, value);
+ return targetType.getRawType().cast(invoke);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ };
+ }
+ if (converter == null) {
+ try {
+ final Constructor<T> constr = targetType.getRawType().getDeclaredConstructor(String.class);
+ converter = new PropertyConverter<T>() {
+ @Override
+ public T convert(String value, ConversionContext context) {
+ context.addSupportedFormats(PropertyConverter.class, "new T(String)");
+ try {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
+ public Object run() {
+ constr.setAccessible(true);
+ return null;
+ }
+ });
+ return constr.newInstance(value);
+ } catch (Exception e) {
+ throw new ConfigException("Failed to decode '" + value + "'", e);
+ }
+ }
+ };
+ } catch (Exception e) {
+ LOG.finest("Failed to construct instance of type: " + targetType.getRawType().getName() + ": " + e);
+ }
+ }
+ return converter;
+ }
+
+ /**
+ * Tries to evaluate a factory method that can be used to create an instance based on a String.
+ *
+ * @param type the target type
+ * @param methodNames the possible static method names
+ * @return the first method found, or null.
+ */
+ private Method getFactoryMethod(Class<?> type, String... methodNames) {
+ Method m;
+ for (String name : methodNames) {
+ try {
+ m = type.getDeclaredMethod(name, String.class);
+ return m;
+ } catch (NoSuchMethodException | RuntimeException e) {
+ LOG.finest("No such factory method found on type: " + type.getName() + ", methodName: " + name);
+ }
+ }
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java
new file mode 100644
index 0000000..86e95b0
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/SEInjectorCDIExtension.java
@@ -0,0 +1,112 @@
+/*
+ * 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.inject.ConfigurationInjection;
+import org.apache.tamaya.inject.api.Config;
+import org.apache.tamaya.inject.api.ConfigDefaultSections;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Vetoed;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.enterprise.inject.spi.ProcessInjectionTarget;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+/**
+ * CDI portable extension that integrates {@link org.apache.tamaya.inject.ConfigurationInjector}
+ * with CDI by adding configuration features to CDI (config enable CDI beans).
+ */
+@Vetoed
+public final class SEInjectorCDIExtension implements Extension {
+
+ /**
+ * Method that injects the values into any configured fields, by wrapping the given
+ * InjectionTarget.
+ * @param pit the injection target
+ * @param <T> the target type
+ */
+ public <T> void initializeConfiguredFields(final @Observes ProcessInjectionTarget<T> pit) {
+ final AnnotatedType<T> at = pit.getAnnotatedType();
+ if (!isConfigured(at.getJavaClass())) {
+ return;
+ }
+ final InjectionTarget<T> it = pit.getInjectionTarget();
+ InjectionTarget<T> wrapped = new InjectionTarget<T>() {
+ @Override
+ public void inject(T instance, CreationalContext<T> ctx) {
+ it.inject(instance, ctx);
+ ConfigurationInjection.getConfigurationInjector().configure(instance);
+ }
+
+ @Override
+ public void postConstruct(T instance) {
+ it.postConstruct(instance);
+ }
+
+ @Override
+ public void preDestroy(T instance) {
+ it.dispose(instance);
+ }
+
+ @Override
+ public void dispose(T instance) {
+ it.dispose(instance);
+ }
+
+ @Override
+ public Set<InjectionPoint> getInjectionPoints() {
+ return it.getInjectionPoints();
+ }
+
+ @Override
+ public T produce(CreationalContext<T> ctx) {
+ return it.produce(ctx);
+ }
+ };
+ pit.setInjectionTarget(wrapped);
+ }
+
+ private boolean isConfigured(Class type) {
+ if (type.getAnnotation(ConfigDefaultSections.class) != null) {
+ return true;
+ }
+ // if no class level annotation is there we might have field level annotations only
+ for (Field field : type.getDeclaredFields()) {
+ if (field.isAnnotationPresent(Config.class)) {
+ return true;
+ }
+ }
+ // if no class level annotation is there we might have method level annotations only
+ for (Method method : type.getDeclaredMethods()) {
+ if(method.isAnnotationPresent(Config.class)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
new file mode 100644
index 0000000..5171d91
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/ServiceLoaderServiceContext.java
@@ -0,0 +1,151 @@
+/*
+ * 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 java.text.MessageFormat;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements the (default) {@link ServiceContext} interface and hereby uses the JDK
+ * {@link ServiceLoader} to load the services required.
+ */
+final class ServiceLoaderServiceContext implements ServiceContext {
+ /**
+ * List current services loaded, per class.
+ */
+ private final ConcurrentHashMap<Class<?>, List<Object>> servicesLoaded = new ConcurrentHashMap<>();
+ /**
+ * Singletons.
+ */
+ private final Map<Class<?>, Object> singletons = new ConcurrentHashMap<>();
+
+ @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 = (List<T>) servicesLoaded.get(serviceType);
+ if (found != null) {
+ return found;
+ }
+ List<T> services = new ArrayList<>();
+ try {
+ for (T t : ServiceLoader.load(serviceType)) {
+ services.add(t);
+ }
+ services = Collections.unmodifiableList(services);
+ } catch (Exception e) {
+ Logger.getLogger(ServiceLoaderServiceContext.class.getName()).log(Level.WARNING,
+ "Error loading services current type " + serviceType, e);
+ }
+ final List<T> previousServices = List.class.cast(servicesLoaded.putIfAbsent(serviceType, (List<Object>) services));
+ return previousServices != null ? previousServices : services;
+ }
+
+ /**
+ * 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;
+ }
+
+ @Override
+ public int ordinal() {
+ return 1;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
new file mode 100644
index 0000000..3f62039
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaCDIIntegration.java
@@ -0,0 +1,52 @@
+/*
+ * 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 javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+
+/**
+ * Tamaya main integration with CDI, storing the BeanManager reference for implementation, where no
+ * JNDI is available or {@code java:comp/env/BeanManager} is not set correctly.
+ */
+public class TamayaCDIIntegration implements Extension {
+ /** The BeanManager references stored. */
+ private static BeanManager beanManager;
+
+ /**
+ * Initializes the current BeanManager with the instance passed.
+ * @param validation the event
+ * @param beanManager the BeanManager instance
+ */
+ @SuppressWarnings("all")
+ public void initBeanManager(@Observes AfterDeploymentValidation validation, BeanManager beanManager){
+ TamayaCDIIntegration.beanManager = beanManager;
+ }
+
+ /**
+ * Get the current {@link BeanManager} instance.
+ * @return the currently used bean manager.
+ */
+ public static BeanManager getBeanManager(){
+ return beanManager;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java
new file mode 100644
index 0000000..a81e545
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/TamayaConfigProvider.java
@@ -0,0 +1,55 @@
+/*
+ * 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.ConfigurationProvider;
+import org.apache.tamaya.spi.ConfigurationContext;
+import org.apache.tamaya.spi.ConfigurationContextBuilder;
+import org.apache.tamaya.spisupport.DefaultConfiguration;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Singleton;
+
+/**
+ * Tamaya main integreation with CDI (singleton) serving producers for Configuration, ConfigurationContext and
+ * ConfigurationContextBuilder.
+ */
+@Singleton
+public class TamayaConfigProvider{
+
+ @Produces
+ @ApplicationScoped
+ public Configuration getConfiguration(ConfigurationContext context){
+ return new DefaultConfiguration(context);
+ }
+
+ @Produces @ApplicationScoped
+ public ConfigurationContext getConfigurationContext(){
+ return new DefaultConfigurationContext();
+ }
+
+ @Produces
+ public ConfigurationContextBuilder getConfigurationContextBuilder(){
+ return ConfigurationProvider.getConfigurationContextBuilder();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java
new file mode 100644
index 0000000..f90998d
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/java/org/apache/tamaya/integration/cdi/config/ConfiguredVetoExtension.java
@@ -0,0 +1,42 @@
+/*
+ * 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.config;
+
+import org.apache.tamaya.ConfigurationProvider;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+/**
+ * CDI Extension that can be used to veto on beans by configuring the fully qualified class names (as regex expression)
+ * under {@code javax.enterprise.inject.vetoed}. Multiple expression can be added as comma separated values.
+ */
+public class ConfiguredVetoExtension {
+
+ public void observesBean(@Observes ProcessAnnotatedType<?> type){
+ String vetoedTypesVal = ConfigurationProvider.getConfiguration().get("javax.enterprise.inject.vetoed");
+ String[] vetoedTypes = vetoedTypesVal.split(",");
+ for(String typeExpr:vetoedTypes){
+ if(type.getAnnotatedType().getJavaClass().getName().matches(typeExpr)){
+ type.veto();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml b/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..adee378
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
+
+</beans>
+
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..8580a42
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,20 @@
+#
+# 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.TamayaCDIIntegration
+org.apache.tamaya.integration.cdi.SEInjectorCDIExtension
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext b/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
new file mode 100644
index 0000000..4fe7e01
--- /dev/null
+++ b/modules/injection/cdi-se/src/main/resources/META-INF/services/org.apache.tamaya.spi.ServiceContext
@@ -0,0 +1,19 @@
+#
+# 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.CDIAwareServiceContext
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/fe7cd8f1/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java
----------------------------------------------------------------------
diff --git a/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java
new file mode 100644
index 0000000..9d920bc
--- /dev/null
+++ b/modules/injection/cdi-se/src/test/java/org/apache/tamaya/integration/cdi/ConfiguredClass.java
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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.
+ *
+ */
+package org.apache.tamaya.integration.cdi;
+
+import org.apache.tamaya.inject.api.Config;
+
+import java.math.BigDecimal;
+
+import javax.inject.Singleton;
+
+/**
+ * Class to be loaded from CDI to ensure fields are correctly configured using CDI injection mechanisms.
+ */
+@Singleton
+public class ConfiguredClass{
+
+ @Config
+ private String testProperty;
+
+ @Config(value = {"a.b.c.key1","a.b.c.key2","a.b.c.key3"}, defaultValue = "The current \\${JAVA_HOME} env property is ${env:JAVA_HOME}.")
+ String value1;
+
+ @Config({"foo","a.b.c.key2"})
+ private String value2;
+
+ @Config(defaultValue = "N/A")
+ private String runtimeVersion;
+
+ @Config(defaultValue = "${sys:java.version}")
+ private String javaVersion2;
+
+ @Config(defaultValue = "5")
+ private Integer int1;
+
+ @Config
+ private int int2;
+
+ @Config
+ private boolean booleanT;
+
+ @Config("BD")
+ private BigDecimal bigNumber;
+
+ @Config("double1")
+ private double doubleValue;
+
+ public String getTestProperty() {
+ return testProperty;
+ }
+
+ public String getValue1() {
+ return value1;
+ }
+
+ public String getValue2() {
+ return value2;
+ }
+
+ public String getRuntimeVersion() {
+ return runtimeVersion;
+ }
+
+ public String getJavaVersion2() {
+ return javaVersion2;
+ }
+
+ public Integer getInt1() {
+ return int1;
+ }
+
+ public int getInt2() {
+ return int2;
+ }
+
+ public boolean isBooleanT() {
+ return booleanT;
+ }
+
+ public BigDecimal getBigNumber() {
+ return bigNumber;
+ }
+
+ public double getDoubleValue() {
+ return doubleValue;
+ }
+
+ @Override
+ public String toString(){
+ return super.toString() + ": testProperty="+testProperty+", value1="+value1+", value2="+value2
+ +", int1="+int1+", int2="+int2+", booleanT="+booleanT+", bigNumber="+bigNumber
+ +", runtimeVersion="+runtimeVersion+", javaVersion2="+javaVersion2;
+ }
+
+}