You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2012/03/14 00:02:58 UTC

git commit: DELTASPIKE-114 @ConfigProperty (intermediate result of the first draft)

Updated Branches:
  refs/heads/master 4cc9b6a3f -> 9906b1a32


DELTASPIKE-114 @ConfigProperty (intermediate result of the first draft)


Project: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/commit/9906b1a3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/tree/9906b1a3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/diff/9906b1a3

Branch: refs/heads/master
Commit: 9906b1a3236aacc595243605b759b65410021fa8
Parents: 4cc9b6a
Author: gpetracek <gp...@apache.org>
Authored: Tue Mar 13 14:49:02 2012 +0100
Committer: gpetracek <gp...@apache.org>
Committed: Tue Mar 13 23:41:45 2012 +0100

----------------------------------------------------------------------
 .../deltaspike/core/api/config/ConfigProperty.java |   49 ++++
 .../deltaspike/core/api/converter/Converter.java   |   24 ++
 .../core/api/converter/ConverterException.java     |   43 ++++
 .../core/api/converter/MetaDataAwareConverter.java |   24 ++
 .../core/spi/converter/ConverterFactory.java       |   26 +++
 .../impl/config/injectable/ConfigPropertyBean.java |  174 +++++++++++++++
 .../config/injectable/ConfigPropertyExtension.java |  115 ++++++++++
 .../config/injectable/InjectionTargetEntry.java    |   87 +++++++
 .../core/impl/converter/ConverterKey.java          |   68 ++++++
 .../impl/converter/DefaultConverterFactory.java    |  166 ++++++++++++++
 .../impl/converter/StringToIntegerConverter.java   |   47 ++++
 .../services/javax.enterprise.inject.spi.Extension |    3 +-
 .../example/config/ConverterExample.java           |   51 +++++
 .../config/CustomInverseStringToLongConverter.java |   61 +++++
 .../config/CustomStringToLongConverter.java        |   62 +++++
 .../deltaspike/example/config/Property2.java       |   47 ++++
 .../config/Property2WithInverseSupport.java        |   47 ++++
 .../deltaspike/example/config/SettingsBean.java    |   67 ++++++
 .../META-INF/apache-deltaspike.properties          |   19 ++
 19 files changed, 1179 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
new file mode 100644
index 0000000..ed5e612
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java
@@ -0,0 +1,49 @@
+/*
+ * 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.deltaspike.core.api.config;
+
+import org.apache.deltaspike.core.api.converter.Converter;
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Documented
+
+@Qualifier
+public @interface ConfigProperty
+{
+    String name();
+
+    @Nonbinding
+    Class<? extends Converter> converter() default Converter.class;
+
+    boolean eager() default true;
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/Converter.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/Converter.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/Converter.java
new file mode 100644
index 0000000..26696f9
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/Converter.java
@@ -0,0 +1,24 @@
+/*
+ * 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.deltaspike.core.api.converter;
+
+public interface Converter<S, T>
+{
+    T convert(S source);
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/ConverterException.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/ConverterException.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/ConverterException.java
new file mode 100644
index 0000000..1727d64
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/ConverterException.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.deltaspike.core.api.converter;
+
+//TODO TBD
+public class ConverterException extends RuntimeException
+{
+    private Class<?> sourceType;
+    private Class<?> targetType;
+
+    public ConverterException(Class<?> sourceType, Class<?> targetType, Throwable cause)
+    {
+        super(cause);
+        this.sourceType = sourceType;
+        this.targetType = targetType;
+    }
+
+    public Class<?> getSourceType()
+    {
+        return sourceType;
+    }
+
+    public Class<?> getTargetType()
+    {
+        return targetType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/MetaDataAwareConverter.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/MetaDataAwareConverter.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/MetaDataAwareConverter.java
new file mode 100644
index 0000000..4032058
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/converter/MetaDataAwareConverter.java
@@ -0,0 +1,24 @@
+/*
+ * 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.deltaspike.core.api.converter;
+
+public interface MetaDataAwareConverter<S, T, M> extends Converter<S, T>
+{
+    T convert(S source, M metaData);
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/converter/ConverterFactory.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/converter/ConverterFactory.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/converter/ConverterFactory.java
new file mode 100644
index 0000000..4640f57
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/converter/ConverterFactory.java
@@ -0,0 +1,26 @@
+/*
+ * 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.deltaspike.core.spi.converter;
+
+import org.apache.deltaspike.core.api.converter.Converter;
+
+public interface ConverterFactory
+{
+    <S, T> Converter<S, T> create(Class<S> sourceType, Class<T> targetType);
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyBean.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyBean.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyBean.java
new file mode 100644
index 0000000..b51b628
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyBean.java
@@ -0,0 +1,174 @@
+/*
+ * 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.deltaspike.core.impl.config.injectable;
+
+import org.apache.deltaspike.core.api.config.ConfigProperty;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.api.converter.Converter;
+import org.apache.deltaspike.core.api.converter.MetaDataAwareConverter;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.core.spi.converter.ConverterFactory;
+import org.apache.deltaspike.core.util.ClassUtils;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ConfigPropertyBean<T> implements Bean<T>, Serializable
+{
+    private static final long serialVersionUID = 219378243102320371L;
+
+    private final Class<?> beanType;
+    private final Set<Annotation> qualifiers;
+    private final Set<Type> types;
+    private final ConfigProperty configProperty;
+    private final Annotation customQualifier;
+
+    public ConfigPropertyBean(Type targetType, ConfigProperty configProperty, Annotation customQualifier)
+    {
+        this.configProperty = configProperty;
+
+        this.qualifiers = new HashSet<Annotation>();
+
+        if (customQualifier != null)
+        {
+            this.qualifiers.add(customQualifier);
+        }
+        else
+        {
+            this.qualifiers.add(configProperty);
+        }
+
+        this.customQualifier = customQualifier;
+
+        this.beanType = (Class<?>) targetType;
+
+        this.types = new HashSet<Type>();
+        this.types.add(this.beanType);
+    }
+
+    @Override
+    public Set<Type> getTypes()
+    {
+        return this.types;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers()
+    {
+        return this.qualifiers;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope()
+    {
+        return Dependent.class;
+    }
+
+    @Override
+    public String getName()
+    {
+        //if we would support bean-names, we couldn't support e.g. multiple custom annotations for the same property
+        return null;
+    }
+
+    @Override
+    public boolean isNullable()
+    {
+        return false;
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints()
+    {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Class<?> getBeanClass()
+    {
+        return this.beanType;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes()
+    {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isAlternative()
+    {
+        return false;
+    }
+
+    @Override
+    public T create(CreationalContext<T> creationalContext)
+    {
+        ConverterFactory converterFactory = BeanProvider.getContextualReference(ConverterFactory.class, false);
+
+        //TODO add support for collections, ...
+        //TODO discuss handling of null values
+        String configuredValue = ConfigResolver.getPropertyValue(configProperty.name());
+
+        Converter converter;
+
+        if (Converter.class.equals(configProperty.converter()))
+        {
+            //TODO add exception handling, if we throw an exception for an unknown converter
+            converter = converterFactory.create(String.class, (Class<?>) this.beanType);
+        }
+        else
+        {
+            converter = BeanProvider.getContextualReference(configProperty.converter(), true);
+
+            if (converter == null)
+            {
+                converter = ClassUtils.tryToInstantiateClass(configProperty.converter());
+            }
+        }
+
+        if (converter == null)
+        {
+            throw new IllegalStateException("can't find config for " +
+                    String.class.getName() + " -> " + beanType.getName());
+        }
+
+        if (this.customQualifier != null && converter instanceof MetaDataAwareConverter)
+        {
+            return (T) ((MetaDataAwareConverter) converter).convert(configuredValue, this.customQualifier);
+        }
+        //noinspection unchecked
+        return (T) converter.convert(configuredValue);
+    }
+
+    @Override
+    public void destroy(T configPropertyProducer,
+                        CreationalContext<T> configPropertyProducerCreationalContext)
+    {
+        //no need to destroy a configured value
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyExtension.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyExtension.java
new file mode 100644
index 0000000..807a062
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/ConfigPropertyExtension.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.deltaspike.core.impl.config.injectable;
+
+import org.apache.deltaspike.core.api.config.ConfigProperty;
+import org.apache.deltaspike.core.api.config.ConfigResolver;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassDeactivation;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.enterprise.inject.spi.ProcessInjectionTarget;
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Adds support for {@link org.apache.deltaspike.core.api.config.ConfigProperty}
+ */
+public class ConfigPropertyExtension implements Extension, Deactivatable
+{
+    private Boolean isActivated = null;
+
+    private Set<InjectionTargetEntry> injectionTargets = new HashSet<InjectionTargetEntry>();
+
+    protected void recordConfigPropertyAwareInjectionPoint(@Observes ProcessInjectionTarget event)
+    {
+        initActivation();
+
+        if (!this.isActivated)
+        {
+            return;
+        }
+
+        InjectionTarget<?> injectionTarget = event.getInjectionTarget();
+
+        ConfigProperty configProperty;
+        Annotation qualifier;
+        for (InjectionPoint injectionPoint : injectionTarget.getInjectionPoints())
+        {
+            qualifier = null;
+            configProperty = injectionPoint.getAnnotated().getAnnotation(ConfigProperty.class);
+
+            if (configProperty == null)
+            {
+                for (Annotation annotation : injectionPoint.getAnnotated().getAnnotations())
+                {
+                    configProperty = annotation.annotationType().getAnnotation(ConfigProperty.class);
+
+                    qualifier = annotation;
+
+                    if (configProperty != null)
+                    {
+                        break;
+                    }
+                }
+            }
+
+            if (configProperty != null)
+            {
+                //TODO add support for collections,...
+                if (configProperty.eager() && ConfigResolver.getPropertyValue(configProperty.name()) == null)
+                {
+                    throw new IllegalStateException("no configured value found for property: " + configProperty.name());
+                }
+
+                this.injectionTargets.add(
+                        new InjectionTargetEntry(injectionPoint.getType(), configProperty, qualifier));
+            }
+        }
+    }
+
+    protected void addDependentBeans(@Observes AfterBeanDiscovery event)
+    {
+        initActivation();
+
+        if (!this.isActivated)
+        {
+            return;
+        }
+
+        for (InjectionTargetEntry injectionTargetEntry : this.injectionTargets)
+        {
+            event.addBean(new ConfigPropertyBean<Object>(injectionTargetEntry.getType(), injectionTargetEntry
+                    .getConfigProperty(), injectionTargetEntry.getCustomQualifier()));
+        }
+    }
+
+    protected void initActivation()
+    {
+        if (this.isActivated == null)
+        {
+            this.isActivated = ClassDeactivation.isActivated(getClass());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/InjectionTargetEntry.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/InjectionTargetEntry.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/InjectionTargetEntry.java
new file mode 100644
index 0000000..726d22d
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/injectable/InjectionTargetEntry.java
@@ -0,0 +1,87 @@
+/*
+ * 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.deltaspike.core.impl.config.injectable;
+
+import org.apache.deltaspike.core.api.config.ConfigProperty;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+class InjectionTargetEntry
+{
+    private final Type type;
+    private final ConfigProperty configProperty;
+    private final Annotation optionalCustomQualifier;
+
+    InjectionTargetEntry(Type type, ConfigProperty configProperty, Annotation optionalCustomQualifier)
+    {
+        this.type = type;
+        this.configProperty = configProperty;
+        this.optionalCustomQualifier = optionalCustomQualifier;
+    }
+
+    Type getType()
+    {
+        return type;
+    }
+
+    ConfigProperty getConfigProperty()
+    {
+        return configProperty;
+    }
+
+    Annotation getCustomQualifier()
+    {
+        return optionalCustomQualifier;
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o)
+        {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass())
+        {
+            return false;
+        }
+
+        InjectionTargetEntry that = (InjectionTargetEntry) o;
+
+        if (!configProperty.equals(that.configProperty))
+        {
+            return false;
+        }
+        if (!type.equals(that.type))
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = type.hashCode();
+        result = 31 * result + configProperty.hashCode();
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/ConverterKey.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/ConverterKey.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/ConverterKey.java
new file mode 100644
index 0000000..43712a4
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/ConverterKey.java
@@ -0,0 +1,68 @@
+/*
+ * 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.deltaspike.core.impl.converter;
+
+import javax.enterprise.inject.Typed;
+
+@Typed()
+class ConverterKey
+{
+    private final Class sourceType;
+    private final Class targetType;
+
+    ConverterKey(Class sourceType, Class targetType)
+    {
+        this.sourceType = sourceType;
+        this.targetType = targetType;
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o)
+        {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass())
+        {
+            return false;
+        }
+
+        ConverterKey that = (ConverterKey) o;
+
+        if (!sourceType.equals(that.sourceType))
+        {
+            return false;
+        }
+        if (!targetType.equals(that.targetType))
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = sourceType.hashCode();
+        result = 31 * result + targetType.hashCode();
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/DefaultConverterFactory.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/DefaultConverterFactory.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/DefaultConverterFactory.java
new file mode 100644
index 0000000..672bc49
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/DefaultConverterFactory.java
@@ -0,0 +1,166 @@
+/*
+ * 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.deltaspike.core.impl.converter;
+
+import org.apache.deltaspike.core.api.converter.Converter;
+import org.apache.deltaspike.core.api.literal.AnyLiteral;
+import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
+import org.apache.deltaspike.core.spi.converter.ConverterFactory;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+@ApplicationScoped
+public class DefaultConverterFactory implements ConverterFactory
+{
+    //TODO discuss type logic, 1:n converters,...
+    private Map<ConverterKey, Converter> converterMapping = new ConcurrentHashMap<ConverterKey, Converter>();
+
+    @PostConstruct
+    protected void initDefaultConverters()
+    {
+        addDefaultConverters();
+
+        addCustomConverters();
+    }
+
+    private void addDefaultConverters()
+    {
+        registerConverter(new StringToIntegerConverter());
+    }
+
+    private void addCustomConverters()
+    {
+        List<Converter> customConverters = getCustomConverters();
+
+        for (Converter customConverter : customConverters)
+        {
+            registerConverter(customConverter);
+        }
+    }
+
+    private List<Converter> getCustomConverters()
+    {
+        //TODO check OWB the following works with Weld, but not with OWB:
+        //return BeanProvider.getContextualReferences(Converter.class, true, true);
+
+        //workaround - un-cached lookup is ok, because it's done just once
+
+        BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager();
+        Set<Bean<?>> allBeans = beanManager.getBeans(Object.class, new AnyLiteral());
+
+        List<Bean<Converter>> customConverterBeans = new ArrayList<Bean<Converter>>();
+
+        for (Bean<?> currentBean : allBeans)
+        {
+            if (Converter.class.isAssignableFrom(currentBean.getBeanClass()) && isTypedAsConverter(currentBean))
+            {
+                customConverterBeans.add((Bean<Converter>) currentBean);
+            }
+        }
+
+        List<Converter> converters = new ArrayList<Converter>(customConverterBeans.size());
+
+        Converter currentConverter;
+        for (Bean<Converter> currentBean : customConverterBeans)
+        {
+            currentConverter = (Converter) getContextualReference(currentBean.getBeanClass(), beanManager, currentBean);
+            converters.add(currentConverter);
+        }
+
+        return converters;
+    }
+
+    private static <T> T getContextualReference(Class<T> type, BeanManager beanManager, Bean<?> foundBean)
+    {
+        Set<Bean<?>> beanSet = new HashSet<Bean<?>>(1);
+        beanSet.add(foundBean);
+
+        Bean<?> bean = beanManager.resolve(beanSet);
+
+        CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
+
+        @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
+        T result = (T) beanManager.getReference(bean, type, creationalContext);
+        return result;
+    }
+
+    private boolean isTypedAsConverter(Bean<?> currentBean)
+    {
+        Set<Type> types = currentBean.getTypes();
+
+        if (types == null)
+        {
+            return false;
+        }
+
+        for (Type currentType : types)
+        {
+            if (currentType instanceof Class && Converter.class.isAssignableFrom((Class) currentType))
+            {
+                return true;
+            }
+        }
+
+        //can be the case e.g. with @Typed()
+        return false;
+    }
+
+    protected void registerConverter(Converter converter)
+    {
+        Class sourceType = null;
+        Class targetType = null;
+
+        ParameterizedType parameterizedType;
+        for (Type currentType : converter.getClass().getGenericInterfaces())
+        {
+            if (currentType instanceof ParameterizedType)
+            {
+                parameterizedType = (ParameterizedType) currentType;
+
+                if (Converter.class.isAssignableFrom((Class<?>) parameterizedType.getRawType()))
+                {
+                    sourceType = (Class<?>) parameterizedType.getActualTypeArguments()[0];
+                    targetType = (Class<?>) parameterizedType.getActualTypeArguments()[1];
+                    break;
+                }
+            }
+        }
+
+        this.converterMapping.put(new ConverterKey(sourceType, targetType), converter);
+    }
+
+    @Override
+    public <S, T> Converter<S, T> create(Class<S> sourceType, Class<T> targetType)
+    {
+        //TODO throw an exception if there isn't the correct converter
+        return this.converterMapping.get(new ConverterKey(sourceType, targetType));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/StringToIntegerConverter.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/StringToIntegerConverter.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/StringToIntegerConverter.java
new file mode 100644
index 0000000..1ac8e73
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/converter/StringToIntegerConverter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.deltaspike.core.impl.converter;
+
+import org.apache.deltaspike.core.api.converter.Converter;
+import org.apache.deltaspike.core.api.converter.ConverterException;
+
+import javax.enterprise.inject.Typed;
+
+@Typed()
+class StringToIntegerConverter implements Converter<String, Integer>
+{
+    @Override
+    public Integer convert(String source)
+    {
+        if (source == null || "".equals(source))
+        {
+            return 0;
+        }
+
+        try
+        {
+            return Integer.parseInt(source);
+        }
+        catch (NumberFormatException e)
+        {
+            throw new ConverterException(String.class, Integer.class, e);
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/core/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/deltaspike/core/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
index 4f09ffd..03621ae 100644
--- a/deltaspike/core/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
+++ b/deltaspike/core/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -17,4 +17,5 @@
 # under the License.
 #####################################################################################
 
-org.apache.deltaspike.core.impl.exclude.ExcludeExtension
\ No newline at end of file
+org.apache.deltaspike.core.impl.exclude.ExcludeExtension
+org.apache.deltaspike.core.impl.config.injectable.ConfigPropertyExtension
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/ConverterExample.java
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/ConverterExample.java b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/ConverterExample.java
new file mode 100644
index 0000000..05f076c
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/ConverterExample.java
@@ -0,0 +1,51 @@
+/*
+ * 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.deltaspike.example.config;
+
+import org.apache.deltaspike.cdise.api.CdiContainer;
+import org.apache.deltaspike.cdise.api.CdiContainerLoader;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+
+import javax.enterprise.context.ApplicationScoped;
+import java.util.logging.Logger;
+
+public class ConverterExample
+{
+    private static final Logger LOG = Logger.getLogger(ConverterExample.class.getName());
+
+    private ConverterExample()
+    {
+    }
+
+    public static void main(String[] args)
+    {
+
+        CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
+        cdiContainer.bootContainer();
+        cdiContainer.startContext(ApplicationScoped.class);
+
+        SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false);
+
+        LOG.info("configured int-value #1: " + settingsBean.getIntProperty1());
+        LOG.info("configured long-value #2: " + settingsBean.getProperty2());
+        LOG.info("configured inverse-value #2: " + settingsBean.getInverseProperty());
+
+        cdiContainer.stop();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomInverseStringToLongConverter.java
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomInverseStringToLongConverter.java b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomInverseStringToLongConverter.java
new file mode 100644
index 0000000..07303a1
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomInverseStringToLongConverter.java
@@ -0,0 +1,61 @@
+/*
+ * 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.deltaspike.example.config;
+
+import org.apache.deltaspike.core.api.converter.ConverterException;
+import org.apache.deltaspike.core.api.converter.MetaDataAwareConverter;
+
+import javax.enterprise.inject.Typed;
+import java.util.logging.Logger;
+
+@Typed()
+public class CustomInverseStringToLongConverter
+    implements MetaDataAwareConverter<String, Long, Property2WithInverseSupport>
+{
+    private static final Logger LOG = Logger.getLogger(CustomInverseStringToLongConverter.class.getName());
+
+    @Override
+    public Long convert(String source, Property2WithInverseSupport metaData)
+    {
+        if (source == null || "".equals(source))
+        {
+            return 0L;
+        }
+
+        try
+        {
+            Long result = Long.parseLong(source);
+            if (metaData.inverseConvert())
+            {
+                return result * -1;
+            }
+            return result;
+        }
+        catch (NumberFormatException e)
+        {
+            throw new ConverterException(String.class, Long.class, e);
+        }
+    }
+
+    @Override
+    public Long convert(String source)
+    {
+        throw new IllegalStateException("not implemented");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomStringToLongConverter.java
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomStringToLongConverter.java b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomStringToLongConverter.java
new file mode 100644
index 0000000..7397a26
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomStringToLongConverter.java
@@ -0,0 +1,62 @@
+/*
+ * 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.deltaspike.example.config;
+
+import org.apache.deltaspike.core.api.converter.ConverterException;
+import org.apache.deltaspike.core.api.converter.MetaDataAwareConverter;
+
+import javax.enterprise.context.Dependent;
+import java.util.logging.Logger;
+
+@Dependent
+public class CustomStringToLongConverter implements MetaDataAwareConverter<String, Long, Property2>
+{
+    private static final Logger LOG = Logger.getLogger(CustomStringToLongConverter.class.getName());
+
+    @Override
+    public Long convert(String source, Property2 metaData)
+    {
+        Long result = convert(source);
+
+        if (metaData.logValue())
+        {
+            LOG.info("value of property 2: " + result);
+        }
+
+        return result;
+    }
+
+    @Override
+    public Long convert(String source)
+    {
+        if (source == null || "".equals(source))
+        {
+            return 0L;
+        }
+
+        try
+        {
+            return Long.parseLong(source);
+        }
+        catch (NumberFormatException e)
+        {
+            throw new ConverterException(String.class, Long.class, e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2.java
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2.java b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2.java
new file mode 100644
index 0000000..f3b86ee
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2.java
@@ -0,0 +1,47 @@
+/*
+ * 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.deltaspike.example.config;
+
+import org.apache.deltaspike.core.api.config.ConfigProperty;
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Documented
+
+@ConfigProperty(name = "property2")
+
+@Qualifier
+public @interface Property2
+{
+    @Nonbinding
+    boolean logValue() default true;
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2WithInverseSupport.java
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2WithInverseSupport.java b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2WithInverseSupport.java
new file mode 100644
index 0000000..a246fbd
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2WithInverseSupport.java
@@ -0,0 +1,47 @@
+/*
+ * 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.deltaspike.example.config;
+
+import org.apache.deltaspike.core.api.config.ConfigProperty;
+
+import javax.enterprise.util.Nonbinding;
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
+@Retention(RUNTIME)
+@Documented
+
+@ConfigProperty(name = "property2", converter = CustomInverseStringToLongConverter.class)
+
+@Qualifier
+public @interface Property2WithInverseSupport
+{
+    @Nonbinding
+    boolean inverseConvert() default false;
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/SettingsBean.java
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/SettingsBean.java b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/SettingsBean.java
new file mode 100644
index 0000000..e572ed8
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/SettingsBean.java
@@ -0,0 +1,67 @@
+/*
+ * 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.deltaspike.example.config;
+
+import org.apache.deltaspike.core.api.config.ConfigProperty;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+
+@ApplicationScoped
+public class SettingsBean
+{
+    @Inject
+    @ConfigProperty(name = "property1")
+    private Integer intProperty1;
+
+    private Long property2;
+
+    private Long inverseProperty;
+
+    protected SettingsBean()
+    {
+    }
+
+    @Inject
+    public SettingsBean(@Property2 Long property2)
+    {
+        this.property2 = property2;
+    }
+
+    @Inject
+    protected void init(@Property2WithInverseSupport(inverseConvert = true) Long inverseProperty)
+    {
+        this.inverseProperty = inverseProperty;
+    }
+
+    public Integer getIntProperty1()
+    {
+        return intProperty1;
+    }
+
+    public Long getProperty2()
+    {
+        return property2;
+    }
+
+    public Long getInverseProperty()
+    {
+        return inverseProperty;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/9906b1a3/deltaspike/examples/jse-examples/src/main/resources/META-INF/apache-deltaspike.properties
----------------------------------------------------------------------
diff --git a/deltaspike/examples/jse-examples/src/main/resources/META-INF/apache-deltaspike.properties b/deltaspike/examples/jse-examples/src/main/resources/META-INF/apache-deltaspike.properties
new file mode 100644
index 0000000..bef3918
--- /dev/null
+++ b/deltaspike/examples/jse-examples/src/main/resources/META-INF/apache-deltaspike.properties
@@ -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 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.
+
+property1=14
+property2=7