You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by pl...@apache.org on 2016/09/06 17:18:04 UTC
[08/50] [abbrv] incubator-tamaya-sandbox git commit: TAMAYA-116:
Added first integration code for Sabot CDI injection extension.
TAMAYA-116: Added first integration code for Sabot CDI injection extension.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/commit/cfbc38de
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/tree/cfbc38de
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/diff/cfbc38de
Branch: refs/heads/master
Commit: cfbc38de1ff5df11d9351fcc80c6c8e4d108c7ef
Parents: 5f2b6e3
Author: anatole <an...@apache.org>
Authored: Tue Oct 6 09:54:51 2015 +0200
Committer: anatole <an...@apache.org>
Committed: Tue Oct 6 09:56:14 2015 +0200
----------------------------------------------------------------------
.../tamaya/environment/spi/ContextSpi.java | 41 ---
.../tamaya/integration/cdi2/ConfigDefault.java | 41 +++
.../integration/cdi2/ConfigDefaultSections.java | 43 ++++
.../tamaya/integration/cdi2/ConfigProperty.java | 80 ++++++
.../cdi2/ConfigurationExtension.java | 257 +++++++++++++++++++
.../integration/cdi2/ConfigurationProducer.java | 115 +++++++++
.../integration/cdi2/WithConfigOperator.java | 45 ++++
.../integration/cdi2/WithPropertyConverter.java | 45 ++++
.../cdi2/src/main/resources/META-INF/beans.xml | 1 +
.../javax.enterprise.inject.spi.Extension | 1 +
.../META-INF/javaconfiguration.properties | 14 +
integration/pom.xml | 4 +-
12 files changed, 644 insertions(+), 43 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/environment/src/main/java/org/apache/tamaya/environment/spi/ContextSpi.java
----------------------------------------------------------------------
diff --git a/environment/src/main/java/org/apache/tamaya/environment/spi/ContextSpi.java b/environment/src/main/java/org/apache/tamaya/environment/spi/ContextSpi.java
deleted file mode 100644
index edc5c54..0000000
--- a/environment/src/main/java/org/apache/tamaya/environment/spi/ContextSpi.java
+++ /dev/null
@@ -1,41 +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.environment.spi;
-
-
-import org.apache.tamaya.environment.RuntimeContext;
-
-/**
- * Service for accessing the current ids that identify a runtime environment. Environments are used to
- * access/determine configurations.<br/>
- * <h3>Implementation PropertyMapSpec</h3> This class is
- * <ul>
- * <li>thread safe,
- * <li>and behaves contextual.
- * </ul>
- */
-public interface ContextSpi {
-
- /**
- * Get the current environment id.
- * @return the corresponding environment id, never null.
- */
- RuntimeContext getCurrentContext();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefault.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefault.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefault.java
new file mode 100644
index 0000000..420f1fd
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefault.java
@@ -0,0 +1,41 @@
+/*
+ * 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.cdi2;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define a default keys to be returned, when no configured keys could be
+ * determined for a property/template accessor. The keys hereby can also contain a
+ * dynamic expression that is evaluated by the configuration system.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
+public @interface ConfigDefault {
+
+ /**
+ * The default keys to be injected, if no such configuration entry was found. If keys was found and no default
+ * is defined, it is handled as a deployment error.
+ */
+ String value() default "";
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefaultSections.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefaultSections.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefaultSections.java
new file mode 100644
index 0000000..e6b5ba2
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigDefaultSections.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cdi2;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to control injection and resolution current a configured bean. The configuration keys
+ * to be resolved are basically determined by the {@link org.apache.tamaya.inject.ConfigProperty}
+ * annotation(s). Nevertheless these annotations can also have relative key names. This annotation allows
+ * to define a configuration area that is prefixed to all relative configuration keys within the
+ * corresponding class/template interface.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE })
+public @interface ConfigDefaultSections {
+
+ /**
+ * Allows to declare an section names that are prepended to resolve relative configuration keys.
+ * @return the section names to used for key resolution.
+ */
+ String[] value() default {};
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigProperty.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigProperty.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigProperty.java
new file mode 100644
index 0000000..4077fce
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigProperty.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cdi2;
+
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to enable injection current a configured property or define the returned data for
+ * a configuration template method. Hereby this annotation can be used in multiple ways and combined
+ * with other annotations such as {@link ConfigDefault}, {@link WithConfigOperator}, {@link WithPropertyConverter}.
+ *
+ * Below the most simple variant current a configured class is given:
+ * {@code
+ * pubic class ConfiguredItem{
+ *
+ * @ConfiguredProperty
+ * private String aValue;
+ * }
+ * When this class is configured, e.g. by passing it to {@link org.apache.tamaya.Configuration#configure(Object)},
+ * the following is happening:
+ * <ul>
+ * <li>The current valid Configuration is evaluated by calling {@code Configuration cfg = ConfigurationProvider.getConfiguration();}</li>
+ * <li>The current possible property keys are evaluated by calling {@code cfg.get("aValue");}</li>
+ * <li>if not successful, and a @ConfigDefault annotation is present, the default value is used.
+ * <li>If no value could be evaluated a ({@link org.apache.tamaya.ConfigException} is thrown.</li>
+ * <li>On success, since no type conversion is involved, the value is injected.</li>
+ * </ul>
+ *
+ * In the next example we explicitly define the property keys:
+ * {@code
+ * @ConfigDefaultSections("section1")
+ * pubic class ConfiguredItem{
+ *
+ * @ConfiguredProperty({"b", "[a.b.deprecated.keys]", "a"})
+ * @ConfigDefault("myDefaultValue")
+ * private String aValue;
+ * }
+ *
+ * Within this example we evaluate multiple possible keys (section1.b, a.b.deprecated.keys, section1.a). Evaluation is
+ * aborted if a key could be successfully resolved. Hereby the ordering current the annotations define the ordering
+ * current resolution, so in the example above
+ * resolution equals to {@code "section1.b", "a.b.deprecated.keys", "section1.a"}. If no value has bee found,
+ * the configured default {@code myDefaultValue} is returned.
+ */
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
+public @interface ConfigProperty {
+
+ /**
+ * Get the property names to be used. Hereby the first non null keys evaluated is injected as property keys.
+ *
+ * @return the property names, not null. If missing the field or method name being injected is used by default.
+ */
+ @Nonbinding
+ String[] value() default {};
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationExtension.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationExtension.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationExtension.java
new file mode 100644
index 0000000..ffec5d1
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationExtension.java
@@ -0,0 +1,257 @@
+/*
+ * 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.cdi2;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.ConfigurationProvider;
+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;
+
+/**
+ * CDI Extension module that adds injection mechanism for configuration.
+ *
+ * @see ConfigProperty
+ * @see ConfigDefault
+ * @see org.apache.tamaya.integration.cdi2.ConfigDefaultSections
+ * @see ConfigException
+ */
+public class ConfigurationExtension implements Extension {
+
+ static final Map<Class, ConfigOperator> CUSTOM_OPERATORS = new ConcurrentHashMap<>();
+ static final Map<Class, PropertyConverter> CUSTOM_CONVERTERS = new ConcurrentHashMap<>();
+
+ 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);
+ }
+ }
+
+ private Set<Type> types = new HashSet<>();
+ private Bean<?> convBean;
+
+ /**
+ * Method that checks the configuration injection points during deployment for available configuration.
+ * @param pb the bean to process.
+ */
+ public void retrieveTypes(@Observes final ProcessBean<?> pb) {
+
+ final Set<InjectionPoint> ips = pb.getBean().getInjectionPoints();
+
+ for (InjectionPoint injectionPoint : ips) {
+ if (injectionPoint.getAnnotated().isAnnotationPresent(ConfigProperty.class)) {
+ final ConfigProperty annotation = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class);
+ final ConfigDefault defaultAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefault.class);
+ final ConfigDefaultSections typeAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefaultSections.class);
+ final List<String> keys = evaluateKeys(injectionPoint.getMember().getName(), annotation.value(), typeAnnot.value());
+
+ 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 keyFound = null;
+ String value = null;
+ for(String key:keys) {
+ value = config.get(key);
+ if(value!=null){
+ keyFound = key;
+ break;
+ }
+ }
+ if(value==null && defaultAnnot!=null){
+ value = defaultAnnot.value();
+ }
+ if(value==null){
+ throw new ConfigException(String.format(
+ "Can't resolve any of the possible config keys: %s. Please provide one of the given keys" +
+ "with a value in your configuration sources.",
+ keys.toString()));
+ }
+ types.add(injectionPoint.getType());
+ }
+ }
+ }
+
+ 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, but not 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<>(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;
+ }
+
+
+ public void captureConvertBean(@Observes final ProcessProducerMethod<?, ?> ppm) {
+ if (ppm.getAnnotated().isAnnotationPresent(ConfigProperty.class)) {
+ convBean = ppm.getBean();
+ }
+
+ }
+
+ public void addConverter(@Observes final AfterBeanDiscovery abd, final BeanManager bm) {
+ abd.addBean(new ConverterBean(convBean, types));
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationProducer.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationProducer.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationProducer.java
new file mode 100644
index 0000000..8b4ae9f
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/ConfigurationProducer.java
@@ -0,0 +1,115 @@
+/*
+ * 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.cdi2;
+
+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.spi.PropertyConverter;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+@ApplicationScoped
+public class ConfigurationProducer {
+
+ private static final Logger LOGGER = Logger.getLogger(ConfigurationProducer.class.getName());
+
+ @Produces
+ @ConfigProperty
+ public Object resolveAndConvert(final InjectionPoint injectionPoint) {
+
+ final ConfigProperty annotation = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class);
+ final ConfigDefault defaultAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefault.class);
+ final ConfigDefaultSections typeAnnot = injectionPoint.getAnnotated().getAnnotation(ConfigDefaultSections.class);
+ final List<String> keys = ConfigurationExtension.evaluateKeys(injectionPoint.getMember().getName(), annotation.value(), typeAnnot.value());
+
+ final WithConfigOperator withOperatorAnnot = injectionPoint.getAnnotated().getAnnotation(WithConfigOperator.class);
+ ConfigOperator operator = null;
+ if(withOperatorAnnot!=null){
+ operator = ConfigurationExtension.CUSTOM_OPERATORS.get(withOperatorAnnot.value());
+ }
+ PropertyConverter customCnverter = null;
+ final WithPropertyConverter withConverterAnnot = injectionPoint.getAnnotated().getAnnotation(WithPropertyConverter.class);
+ if(withConverterAnnot!=null){
+ customCnverter = 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 = defaultAnnot!=null?defaultAnnot.value():null;
+ String keyFound = null;
+ for(String key:keys) {
+ textValue = config.get(key);
+ if(textValue!=null){
+ keyFound = key;
+ break;
+ }
+ }
+ Object value = null;
+ if(keyFound!=null){
+ if(customCnverter!=null) {
+ value = customCnverter.convert(textValue);
+ }
+ if(value==null){
+ value = config.get(keyFound, toType);
+ }
+ }
+ else if(defaultTextValue!=null){
+ if(customCnverter!=null) {
+ value = customCnverter.convert(defaultTextValue);
+ }
+ if(value==null) {
+ List<PropertyConverter<Object>> converters = ConfigurationProvider.getConfigurationContext()
+ .getPropertyConverters(TypeLiteral.of(toType));
+ for (PropertyConverter<Object> converter : converters) {
+ try {
+ value = converter.convert(defaultTextValue);
+ 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",
+ keys.toString(), toType.getName()));
+ }
+ 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-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithConfigOperator.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithConfigOperator.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithConfigOperator.java
new file mode 100644
index 0000000..7d6ac66
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithConfigOperator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.cdi2;
+
+import org.apache.tamaya.ConfigOperator;
+import org.apache.tamaya.Configuration;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define an configuration operator to be used before accessing a configured keys.
+ * This allows filtering current configuration, e.g. for realizing views or ensuring security
+ * constraints.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
+public @interface WithConfigOperator {
+
+ /**
+ * Define a custom adapter that should be used to adapt the configuration entry injected. This overrides any
+ * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
+ * registered, it is handled as a deployment error.
+ */
+ Class<? extends ConfigOperator> value();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithPropertyConverter.java
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithPropertyConverter.java b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithPropertyConverter.java
new file mode 100644
index 0000000..f50edcb
--- /dev/null
+++ b/integration/cdi2/src/main/java/org/apache/tamaya/integration/cdi2/WithPropertyConverter.java
@@ -0,0 +1,45 @@
+/*
+ * 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.cdi2;
+
+
+import org.apache.tamaya.spi.PropertyConverter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define a type adapter to be used before injecting a configured keys, or for applying changes.
+ * This will override any other adapter for performing the type conversion before
+ * injecting the field keys.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
+public @interface WithPropertyConverter {
+
+ /**
+ * Define a custom adapter or codec that should be used to adapt the configuration entry injected. This overrides any
+ * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
+ * registered, it is handled as a deployment error.
+ */
+ Class<? extends PropertyConverter<?>> value();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/resources/META-INF/beans.xml b/integration/cdi2/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..e71e480
--- /dev/null
+++ b/integration/cdi2/src/main/resources/META-INF/beans.xml
@@ -0,0 +1 @@
+<beans></beans>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/integration/cdi2/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..78139d5
--- /dev/null
+++ b/integration/cdi2/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.tomitribe.sabot.ConfigurationExtension
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/cdi2/src/test/resources/META-INF/javaconfiguration.properties
----------------------------------------------------------------------
diff --git a/integration/cdi2/src/test/resources/META-INF/javaconfiguration.properties b/integration/cdi2/src/test/resources/META-INF/javaconfiguration.properties
new file mode 100644
index 0000000..6c8b06c
--- /dev/null
+++ b/integration/cdi2/src/test/resources/META-INF/javaconfiguration.properties
@@ -0,0 +1,14 @@
+remote.wsdl.location = classpath:/service-wsdl.xml
+remote.port=1443
+remote.address=${remote.host}:${remote.port}
+remote.target.url = https://${remote.address}/remote/service/url
+remote.username = joecool
+# ciphered using built in StaticDESPasswordCipher
+remote.password = NjAq6q2agYVnvSMz+eYUZg==
+cipher=org.apache.openejb.cipher.StaticDESPasswordCipher
+
+string.value = hello
+file.value = ./conf
+duration.value = 10 minutes and 57 seconds
+boolean.value = true
+integer.value = 123
http://git-wip-us.apache.org/repos/asf/incubator-tamaya-sandbox/blob/cfbc38de/integration/pom.xml
----------------------------------------------------------------------
diff --git a/integration/pom.xml b/integration/pom.xml
index 3d50784..dd3dfaa 100644
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -29,10 +29,10 @@ under the License.
<packaging>pom</packaging>
<modelVersion>4.0.0</modelVersion>
- <artifactId>tamaya-integrations</artifactId>
+ <artifactId>tamaya-integration-sandbox</artifactId>
<modules>
- <module>cdi</module>
+ <module>cdi2</module>
<module>commons</module>
</modules>