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/04/06 12:47:46 UTC

git commit: DELTASPIKE-148 and DELTASPIKE-149 @MessageContextConfig

Updated Branches:
  refs/heads/master 7c480a051 -> ca90b1cc1


DELTASPIKE-148 and DELTASPIKE-149 @MessageContextConfig


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

Branch: refs/heads/master
Commit: ca90b1cc114de3a417a57ef47c9626cd2b83652a
Parents: 7c480a0
Author: gpetracek <gp...@apache.org>
Authored: Fri Apr 6 12:21:10 2012 +0200
Committer: gpetracek <gp...@apache.org>
Committed: Fri Apr 6 12:42:53 2012 +0200

----------------------------------------------------------------------
 .../api/literal/MessageContextConfigLiteral.java   |   70 ++++++++++
 .../core/api/message/LocaleResolver.java           |   34 +++++
 .../deltaspike/core/api/message/Message.java       |   28 +----
 .../deltaspike/core/api/message/MessageBundle.java |   12 +-
 .../core/api/message/MessageContextConfig.java     |   38 ++++++
 .../core/api/message/MessageInterpolator.java      |   39 ++++++
 .../core/api/message/MessageResolver.java          |   35 +++++
 .../deltaspike/core/util/PropertyFileUtils.java    |  102 +++++++++++++++
 .../impl/config/DefaultConfigSourceProvider.java   |   14 +--
 .../core/impl/config/PropertyFileConfigSource.java |   44 +------
 .../core/impl/message/DefaultMessageResolver.java  |   70 ++++++++++
 .../core/impl/message/MessageBundleExtension.java  |   15 +-
 .../message/MessageBundleInvocationHandler.java    |   67 ++++++++--
 .../test/core/api/message/BirdMessages.java        |   29 ----
 .../deltaspike/test/core/api/message/Jay.java      |    5 +-
 .../test/core/api/message/MessageTest.java         |   24 +++-
 .../test/core/api/message/SimpleMessage.java       |   29 ++++
 .../test/core/api/message/SimpleMessageTest.java   |   82 ++++++++++++
 .../core/api/message/TestMessageInterpolator.java  |   33 +++++
 .../test/core/api/message/TestMessages.java        |   41 ++++++
 .../test/core/api/message/TestMessages.properties  |   19 +++
 deltaspike/core/integration-test/pom.xml           |    1 +
 22 files changed, 689 insertions(+), 142 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/MessageContextConfigLiteral.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/MessageContextConfigLiteral.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/MessageContextConfigLiteral.java
new file mode 100644
index 0000000..13cfda7
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/MessageContextConfigLiteral.java
@@ -0,0 +1,70 @@
+/*
+ * 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.literal;
+
+import org.apache.deltaspike.core.api.message.LocaleResolver;
+import org.apache.deltaspike.core.api.message.MessageContextConfig;
+import org.apache.deltaspike.core.api.message.MessageInterpolator;
+import org.apache.deltaspike.core.api.message.MessageResolver;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+/**
+ * Literal for {@link org.apache.deltaspike.core.api.message.MessageContextConfig}
+ */
+public class MessageContextConfigLiteral extends AnnotationLiteral<MessageContextConfig> implements MessageContextConfig
+{
+    private static final long serialVersionUID = -5888417869986174834L;
+
+    private final Class<? extends MessageResolver> messageResolver;
+    private final Class<? extends MessageInterpolator> messageInterpolator;
+    private final Class<? extends LocaleResolver> localeResolver;
+
+    public MessageContextConfigLiteral()
+    {
+        this(MessageResolver.class, MessageInterpolator.class, LocaleResolver.class);
+    }
+
+    public MessageContextConfigLiteral(Class<? extends MessageResolver> messageResolver,
+                                       Class<? extends MessageInterpolator> messageInterpolator,
+                                       Class<? extends LocaleResolver> localeResolver)
+    {
+        this.messageResolver = messageResolver;
+        this.messageInterpolator = messageInterpolator;
+        this.localeResolver = localeResolver;
+    }
+
+    @Override
+    public Class<? extends MessageResolver> messageResolver()
+    {
+        return this.messageResolver;
+    }
+
+    @Override
+    public Class<? extends MessageInterpolator> messageInterpolator()
+    {
+        return this.messageInterpolator;
+    }
+
+    @Override
+    public Class<? extends LocaleResolver> localeResolver()
+    {
+        return this.localeResolver;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/LocaleResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/LocaleResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/LocaleResolver.java
new file mode 100644
index 0000000..1f75364
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/LocaleResolver.java
@@ -0,0 +1,34 @@
+/*
+ * 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.message;
+
+
+import java.io.Serializable;
+import java.util.Locale;
+
+/**
+ * Implementations have to provide the current locale
+ */
+public interface LocaleResolver extends Serializable
+{
+    /**
+     * @return the current locale
+     */
+    Locale getLocale();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/Message.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/Message.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/Message.java
index 95980cd..3b1f832 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/Message.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/Message.java
@@ -18,13 +18,13 @@
  */
 package org.apache.deltaspike.core.api.message;
 
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
 @Target(METHOD)
 @Retention(RUNTIME)
 @Documented
@@ -36,26 +36,4 @@ public @interface Message
      * @return the format string
      */
     String value();
-
-    /**
-     * The format type of this method (defaults to {@link Format#PRINTF}).
-     *
-     * @return the format type
-     */
-    Format format() default Format.PRINTF;
-
-    /**
-     * The possible format types.
-     */
-    enum Format
-    {
-        /**
-         * A {@link java.util.Formatter}-type format string.
-         */
-        PRINTF,
-        /**
-         * A {@link java.text.MessageFormat}-type format string.
-         */
-        MESSAGE_FORMAT,
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageBundle.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageBundle.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageBundle.java
index 96c50f7..055709a 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageBundle.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageBundle.java
@@ -18,23 +18,19 @@
  */
 package org.apache.deltaspike.core.api.message;
 
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
 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.TYPE;
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import javax.inject.Qualifier;
-
 @Target({ TYPE, METHOD, PARAMETER, FIELD })
 @Retention(RUNTIME)
-@Qualifier
 @Documented
 public @interface MessageBundle
 {
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageContextConfig.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageContextConfig.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageContextConfig.java
new file mode 100644
index 0000000..499d441
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageContextConfig.java
@@ -0,0 +1,38 @@
+/*
+ * 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.message;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({ TYPE })
+@Retention(RUNTIME)
+@Documented
+public @interface MessageContextConfig
+{
+    Class<? extends MessageResolver> messageResolver() default MessageResolver.class;
+
+    Class<? extends MessageInterpolator> messageInterpolator() default MessageInterpolator.class;
+
+    Class<? extends LocaleResolver> localeResolver() default LocaleResolver.class;
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageInterpolator.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageInterpolator.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageInterpolator.java
new file mode 100644
index 0000000..d0e2331
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageInterpolator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.message;
+
+import java.io.Serializable;
+
+/**
+ * Implementations are responsible to replace placeholders in a message with the final value
+ */
+public interface MessageInterpolator extends Serializable
+{
+    /**
+     * replaces the arguments of the given message with the given arguments
+     *
+     * instead of a MessageContextAware interface. we need it to avoid expensive operations like locking or deep cloning
+     * @param messageText the message text which has to be interpolated
+     * @param arguments a list of numbered and/or named arguments for the current message
+     * @return the final (interpolated) message text
+     *         if it was possible to replace the parameters with the given arguments
+     *         the unmodified messageText otherwise
+     */
+    String interpolate(String messageText, Object[] arguments);
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageResolver.java
new file mode 100644
index 0000000..85feab3
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageResolver.java
@@ -0,0 +1,35 @@
+/*
+ * 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.message;
+
+import java.io.Serializable;
+
+/**
+ * Implementations have to resolve the text stored for a given key in the message-source they are aware of
+ */
+public interface MessageResolver extends Serializable
+{
+    String MISSING_RESOURCE_MARKER = "???";
+
+    /**
+     * @param messageDescriptor the message key (or in-lined text) of the current message
+     * @return the final but not interpolated message text
+     */
+    String getMessage(String messageDescriptor);
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/PropertyFileUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/PropertyFileUtils.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/PropertyFileUtils.java
new file mode 100644
index 0000000..80b7fc7
--- /dev/null
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/PropertyFileUtils.java
@@ -0,0 +1,102 @@
+/*
+ * 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.util;
+
+import javax.enterprise.inject.Typed;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+@Typed()
+public abstract class PropertyFileUtils
+{
+    /**
+     * Constructor which prevents the instantiation of this class
+     */
+    private PropertyFileUtils()
+    {
+        // prevent instantiation
+    }
+
+    public static Enumeration<URL> resolvePropertyFiles(String propertyFileName) throws IOException
+    {
+        ClassLoader cl = ClassUtils.getClassLoader(null);
+
+        Enumeration<URL> propertyFileUrls = cl.getResources(propertyFileName);
+
+        //fallback - see DELTASPIKE-98
+        if (!propertyFileUrls.hasMoreElements())
+        {
+            cl = PropertyFileUtils.class.getClassLoader();
+            propertyFileUrls = cl.getResources(propertyFileName);
+        }
+
+        return propertyFileUrls;
+    }
+
+    public static Properties loadProperties(URL url)
+    {
+        Properties props = new Properties();
+
+        InputStream inputStream = null;
+        try
+        {
+            inputStream = url.openStream();
+
+            if (inputStream != null)
+            {
+                props.load(inputStream);
+            }
+        }
+        catch (IOException e)
+        {
+            throw new IllegalStateException(e);
+        }
+        finally
+        {
+            try
+            {
+                if (inputStream != null)
+                {
+                    inputStream.close();
+                }
+            }
+            catch (IOException e)
+            {
+                // no worries, means that the file is already closed
+            }
+        }
+
+        return props;
+    }
+
+    public static ResourceBundle getResourceBundle(String bundleName)
+    {
+        return getResourceBundle(bundleName, Locale.getDefault());
+    }
+
+    public static ResourceBundle getResourceBundle(String bundleName, Locale locale)
+    {
+        return ResourceBundle.getBundle(bundleName, locale);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java
index fc9e003..d96da1a 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java
@@ -18,9 +18,9 @@
  */
 package org.apache.deltaspike.core.impl.config;
 
-import org.apache.deltaspike.core.util.ClassUtils;
 import org.apache.deltaspike.core.spi.config.ConfigSource;
 import org.apache.deltaspike.core.spi.config.ConfigSourceProvider;
+import org.apache.deltaspike.core.util.PropertyFileUtils;
 
 import java.io.IOException;
 import java.net.URL;
@@ -52,17 +52,9 @@ public class DefaultConfigSourceProvider implements ConfigSourceProvider
         this.configSources.add(new EnvironmentPropertyConfigSource());
         this.configSources.add(new LocalJndiConfigSource());
 
-        ClassLoader cl = ClassUtils.getClassLoader(this);
-        try 
+        try
         {
-            Enumeration<URL> propertyFileUrls = cl.getResources(PROPERTY_FILE_NAME);
-
-            //fallback - see DELTASPIKE-98
-            if (!propertyFileUrls.hasMoreElements())
-            {
-                cl = getClass().getClassLoader();
-                propertyFileUrls = cl.getResources(PROPERTY_FILE_NAME);
-            }
+            Enumeration<URL> propertyFileUrls = PropertyFileUtils.resolvePropertyFiles(PROPERTY_FILE_NAME);
 
             while (propertyFileUrls.hasMoreElements())
             {

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
index a1011a7..a0b4d5b 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java
@@ -18,8 +18,8 @@
  */
 package org.apache.deltaspike.core.impl.config;
 
-import java.io.IOException;
-import java.io.InputStream;
+import org.apache.deltaspike.core.util.PropertyFileUtils;
+
 import java.net.URL;
 import java.util.Properties;
 
@@ -35,7 +35,7 @@ class PropertyFileConfigSource extends BaseConfigSource
     PropertyFileConfigSource(URL propertyFileUrl)
     {
         fileName = propertyFileUrl.toExternalForm();
-        properties = loadProperties(propertyFileUrl);
+        properties = PropertyFileUtils.loadProperties(propertyFileUrl);
         initOrdinal(100);
     }
 
@@ -59,42 +59,4 @@ class PropertyFileConfigSource extends BaseConfigSource
     {
         return fileName;
     }
-
-
-
-    private Properties loadProperties(URL url)
-    {
-        Properties props = new Properties();
-
-        InputStream inputStream = null;
-        try
-        {
-            inputStream = url.openStream();
-
-            if (inputStream != null)
-            {
-                props.load(inputStream);
-            }
-        }
-        catch (IOException e)
-        {
-            throw new IllegalStateException(e);
-        }
-        finally
-        {
-            try
-            {
-                if (inputStream != null)
-                {
-                    inputStream.close();
-                }
-            }
-            catch (IOException e)
-            {
-                // no worries, means that the file is already closed
-            }
-        }
-
-        return props;
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageResolver.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageResolver.java
new file mode 100644
index 0000000..fda9712
--- /dev/null
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageResolver.java
@@ -0,0 +1,70 @@
+/*
+ * 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.message;
+
+import org.apache.deltaspike.core.api.message.MessageResolver;
+import org.apache.deltaspike.core.util.PropertyFileUtils;
+
+import javax.enterprise.inject.Typed;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+@Typed()
+class DefaultMessageResolver implements MessageResolver
+{
+    private static final long serialVersionUID = 5834411208472341006L;
+
+    private final ResourceBundle messageBundle;
+
+    DefaultMessageResolver(String messageBundleName, Locale locale)
+    {
+        ResourceBundle resolvedBundle;
+        try
+        {
+            resolvedBundle = PropertyFileUtils.getResourceBundle(messageBundleName, locale);
+        }
+        catch (MissingResourceException e)
+        {
+            //X TODO log it
+            resolvedBundle = null;
+        }
+
+        this.messageBundle = resolvedBundle;
+    }
+
+    @Override
+    public String getMessage(String messageDescriptor)
+    {
+        if (this.messageBundle != null && messageDescriptor != null &&
+            messageDescriptor.startsWith("{") && messageDescriptor.endsWith("}"))
+        {
+            try
+            {
+                return this.messageBundle.getString(messageDescriptor.substring(1, messageDescriptor.length() - 1));
+            }
+            catch (MissingResourceException e)
+            {
+                return MISSING_RESOURCE_MARKER + messageDescriptor + MISSING_RESOURCE_MARKER;
+            }
+        }
+
+        return messageDescriptor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleExtension.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleExtension.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleExtension.java
index 70a7ab9..51ad0b6 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleExtension.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleExtension.java
@@ -33,7 +33,6 @@ import javax.enterprise.inject.spi.Extension;
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
 import javax.enterprise.inject.spi.ProcessProducerMethod;
 
-import org.apache.deltaspike.core.api.literal.MessageBundleLiteral;
 import org.apache.deltaspike.core.api.message.MessageBundle;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
 import org.apache.deltaspike.core.util.ClassDeactivationUtils;
@@ -104,21 +103,23 @@ public class MessageBundleExtension implements Extension, Deactivatable
     }
 
     @SuppressWarnings("UnusedDeclaration")
-    protected void installBeans(@Observes AfterBeanDiscovery event, BeanManager beanManager)
+    protected void installMessageBundleProducerBeans(@Observes AfterBeanDiscovery event, BeanManager beanManager)
     {
         for (AnnotatedType<?> type : messageBundleTypes)
         {
-            event.addBean(createMessageBundleBean(bundleProducerBean, type,
-                    beanManager));
+            event.addBean(createMessageBundleBean(bundleProducerBean, type, beanManager));
         }
     }
 
     private static <T> Bean<T> createMessageBundleBean(Bean<Object> delegate,
-                                                       AnnotatedType<T> type, BeanManager beanManager)
+                                                       AnnotatedType<T> annotatedType,
+                                                       BeanManager beanManager)
     {
         return new NarrowingBeanBuilder<T>(delegate, beanManager)
-                .readFromType(type).types(type.getBaseType(), Object.class)
-                .addQualifier(new MessageBundleLiteral()).create();
+                .readFromType(annotatedType)
+                //X TODO re-visit type.getBaseType() in combination with #addQualifier
+                .types(annotatedType.getJavaClass(), Object.class)
+                .create();
     }
 
     @SuppressWarnings("UnusedDeclaration")

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleInvocationHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleInvocationHandler.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleInvocationHandler.java
index 392a89d..c106c7c 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleInvocationHandler.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleInvocationHandler.java
@@ -18,11 +18,18 @@
  */
 package org.apache.deltaspike.core.impl.message;
 
+import org.apache.deltaspike.core.api.literal.MessageContextConfigLiteral;
+import org.apache.deltaspike.core.api.message.LocaleResolver;
 import org.apache.deltaspike.core.api.message.Message;
+import org.apache.deltaspike.core.api.message.MessageContextConfig;
+import org.apache.deltaspike.core.api.message.MessageInterpolator;
+import org.apache.deltaspike.core.api.message.MessageResolver;
+import org.apache.deltaspike.core.api.provider.BeanProvider;
+import org.apache.deltaspike.core.util.ClassUtils;
 
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
-import java.text.MessageFormat;
+import java.util.Locale;
 
 class MessageBundleInvocationHandler implements InvocationHandler
 {
@@ -34,28 +41,62 @@ class MessageBundleInvocationHandler implements InvocationHandler
     public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable
     {
         final Message message = method.getAnnotation(Message.class);
+
         if (message == null)
         {
             // nothing to do...
             return null;
         }
 
-        String result;
-        switch (message.format())
+        //X TODO discuss use-cases for a deeper lookup and qualifier support
+        MessageContextConfig messageContextConfig =
+            method.getDeclaringClass().getAnnotation(MessageContextConfig.class);
+
+        if (messageContextConfig == null)
         {
-            case PRINTF:
-            {
-                result = String.format(message.value(), args);
-                break;
-            }
-            case MESSAGE_FORMAT:
+            messageContextConfig = new MessageContextConfigLiteral();
+        }
+
+        String messageTemplate;
+
+        if (!MessageResolver.class.equals(messageContextConfig.messageResolver()))
+        {
+            Class<? extends MessageResolver> messageResolverClass =
+                    ClassUtils.tryToLoadClassForName(messageContextConfig.messageResolver().getName());
+
+            MessageResolver messageResolver = BeanProvider.getContextualReference(messageResolverClass);
+
+            messageTemplate = messageResolver.getMessage(message.value());
+        }
+        else 
+        {
+            Class<? extends LocaleResolver> localeResolverClass =
+                    ClassUtils.tryToLoadClassForName(messageContextConfig.localeResolver().getName());
+
+            Locale resolvedLocale = Locale.getDefault();
+
+            if (!LocaleResolver.class.equals(localeResolverClass))
             {
-                result = MessageFormat.format(message.value(), args);
-                break;
+                LocaleResolver localeResolver = BeanProvider.getContextualReference(localeResolverClass);
+
+                resolvedLocale = localeResolver.getLocale();
             }
-            default:
-                throw new IllegalStateException();
+
+            String messageBundleName = method.getDeclaringClass().getName();
+            messageTemplate = new DefaultMessageResolver(messageBundleName, resolvedLocale).getMessage(message.value());
         }
+
+        Class<? extends MessageInterpolator> messageInterpolatorClass =
+                ClassUtils.tryToLoadClassForName(messageContextConfig.messageInterpolator().getName());
+
+        String result = messageTemplate;
+
+        if (!MessageInterpolator.class.equals(messageInterpolatorClass))
+        {
+            MessageInterpolator messageInterpolator = BeanProvider.getContextualReference(messageInterpolatorClass);
+            result = messageInterpolator.interpolate(messageTemplate, args);
+        }
+
         return result;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/BirdMessages.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/BirdMessages.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/BirdMessages.java
deleted file mode 100644
index 55cc56b..0000000
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/BirdMessages.java
+++ /dev/null
@@ -1,29 +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.deltaspike.test.core.api.message;
-
-import org.apache.deltaspike.core.api.message.Message;
-import org.apache.deltaspike.core.api.message.MessageBundle;
-
-@MessageBundle
-public interface BirdMessages
-{
-    @Message("Spotted %s jays")
-    String numberOfJaysSpotted(int number);
-}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/Jay.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/Jay.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/Jay.java
index 7f23560..2a52ee7 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/Jay.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/Jay.java
@@ -20,13 +20,10 @@ package org.apache.deltaspike.test.core.api.message;
 
 import javax.inject.Inject;
 
-import org.apache.deltaspike.core.api.message.MessageBundle;
-
 public class Jay
 {
     @Inject
-    @MessageBundle
-    private BirdMessages messages;
+    private TestMessages messages;
 
     String getMessage()
     {

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageTest.java
index 64419f0..da7d0c1 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageTest.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageTest.java
@@ -18,10 +18,6 @@
  */
 package org.apache.deltaspike.test.core.api.message;
 
-import static org.junit.Assert.assertEquals;
-
-import javax.enterprise.inject.spi.Extension;
-
 import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
 import org.apache.deltaspike.core.impl.message.MessageBundleExtension;
 import org.apache.deltaspike.test.util.ArchiveUtils;
@@ -34,12 +30,20 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import javax.enterprise.inject.spi.Extension;
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+
 /**
  * Tests for {@link org.apache.deltaspike.core.api.message.Message}
  */
 @RunWith(Arquillian.class)
 public class MessageTest
 {
+    @Inject
+    private TestMessages messages;
+
     /**
      * X TODO creating a WebArchive is only a workaround because JavaArchive
      * cannot contain other archives.
@@ -75,4 +79,16 @@ public class MessageTest
     {
         assertEquals("Spotted 8 jays", jay.getMessage());
     }
+
+    @Test
+    public void testInternationalizedMessage()
+    {
+        assertEquals("Welcome to DeltaSpike", this.messages.welcomeToDeltaSpike());
+    }
+
+    @Test
+    public void testInternationalizedParametrizedMessage()
+    {
+        assertEquals("Welcome to Apache DeltaSpike", this.messages.welcomeTo("Apache DeltaSpike"));
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessage.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessage.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessage.java
new file mode 100644
index 0000000..90fa6d2
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessage.java
@@ -0,0 +1,29 @@
+/*
+ * 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.test.core.api.message;
+
+import org.apache.deltaspike.core.api.message.Message;
+import org.apache.deltaspike.core.api.message.MessageBundle;
+
+@MessageBundle
+public interface SimpleMessage
+{
+    @Message("Welcome to DeltaSpike")
+    String welcomeToDeltaSpike();
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessageTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessageTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessageTest.java
new file mode 100644
index 0000000..01d83fb
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessageTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.test.core.api.message;
+
+import org.apache.deltaspike.core.api.provider.BeanManagerProvider;
+import org.apache.deltaspike.core.impl.message.MessageBundleExtension;
+import org.apache.deltaspike.test.util.ArchiveUtils;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.enterprise.inject.spi.Extension;
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link org.apache.deltaspike.core.api.message.Message}
+ */
+@RunWith(Arquillian.class)
+public class SimpleMessageTest
+{
+    @Inject
+    private SimpleMessage simpleMessage;
+
+    /**
+     * X TODO creating a WebArchive is only a workaround because JavaArchive
+     * cannot contain other archives.
+     */
+    @Deployment
+    public static WebArchive deploy()
+    {
+        new BeanManagerProvider()
+        {
+            @Override
+            public void setTestMode()
+            {
+                super.setTestMode();
+            }
+        }.setTestMode();
+
+        JavaArchive testJar = ShrinkWrap
+                .create(JavaArchive.class, "messageTest.jar")
+                .addPackage("org.apache.deltaspike.test.core.api.message")
+                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
+
+        return ShrinkWrap
+                .create(WebArchive.class, "messageTest.war")
+                .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive())
+                .addAsLibraries(testJar)
+                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
+                .addAsServiceProvider(Extension.class,
+                        MessageBundleExtension.class);
+    }
+
+    @Test
+    public void testSimpleMessage()
+    {
+        assertEquals("Welcome to DeltaSpike", this.simpleMessage.welcomeToDeltaSpike());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessageInterpolator.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessageInterpolator.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessageInterpolator.java
new file mode 100644
index 0000000..f521350
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessageInterpolator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.test.core.api.message;
+
+import org.apache.deltaspike.core.api.message.MessageInterpolator;
+
+import javax.enterprise.context.ApplicationScoped;
+
+@ApplicationScoped
+public class TestMessageInterpolator implements MessageInterpolator
+{
+    @Override
+    public String interpolate(String messageText, Object[] arguments)
+    {
+        return String.format(messageText, arguments);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessages.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessages.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessages.java
new file mode 100644
index 0000000..b0c2b60
--- /dev/null
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessages.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.deltaspike.test.core.api.message;
+
+import org.apache.deltaspike.core.api.message.Message;
+import org.apache.deltaspike.core.api.message.MessageBundle;
+import org.apache.deltaspike.core.api.message.MessageContextConfig;
+
+@MessageBundle
+@MessageContextConfig(messageInterpolator = TestMessageInterpolator.class)
+public interface TestMessages
+{
+    @Message("Spotted %s jays")
+    String numberOfJaysSpotted(int number);
+
+    @Message("{welcome_to_deltaspike}")
+    String welcomeToDeltaSpike();
+
+    @Message("{welcome_to}")
+    String welcomeTo(String name);
+
+    //X TODO
+    //@Message("{welcome_to}")
+    //String welcomeTo(MessageContext messageContext, String name);
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/TestMessages.properties
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/TestMessages.properties b/deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/TestMessages.properties
new file mode 100644
index 0000000..642921f
--- /dev/null
+++ b/deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/TestMessages.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.
+
+welcome_to=Welcome to %s
+welcome_to_deltaspike=Welcome to DeltaSpike
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/ca90b1cc/deltaspike/core/integration-test/pom.xml
----------------------------------------------------------------------
diff --git a/deltaspike/core/integration-test/pom.xml b/deltaspike/core/integration-test/pom.xml
index 314da2c..dacf80c 100644
--- a/deltaspike/core/integration-test/pom.xml
+++ b/deltaspike/core/integration-test/pom.xml
@@ -138,6 +138,7 @@
                         </goals>
                         <configuration>
                             <includes>**/*Test.class</includes>
+                            <includes>**/*.properties</includes>
                             <excludes>org.apache.deltaspike.test.core.api.projectstage.*</excludes>
                             <artifactItems>
                                 <artifactItem>