You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2012/10/07 19:58:09 UTC

git commit: DELTASPIKE-277 first version of a JsfMessage implementation

Updated Branches:
  refs/heads/master 39c369bc9 -> 1b151a09c


DELTASPIKE-277 first version of a JsfMessage implementation


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

Branch: refs/heads/master
Commit: 1b151a09c325678754ca3b0683dcd37611212275
Parents: 39c369b
Author: Mark Struberg <st...@apache.org>
Authored: Sun Oct 7 19:55:49 2012 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Sun Oct 7 19:55:49 2012 +0200

----------------------------------------------------------------------
 .../message/MessageBundleInvocationHandler.java    |    2 +-
 .../impl/message/TypedMessageBundleProducer.java   |    4 +-
 .../apache/deltaspike/jsf/message/JsfMessage.java  |   13 ++-
 deltaspike/modules/jsf/impl/pom.xml                |    1 +
 .../jsf/impl/message/DefaultJsfMessage.java        |   57 ++++++++--
 .../message/JsfMessageBundleInvocationHandler.java |   85 +++++++++++++++
 .../jsf/impl/message/JsfMessageProducer.java       |   48 ++++++++
 7 files changed, 196 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/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 feac510..6e27a76 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
@@ -36,7 +36,7 @@ import org.apache.deltaspike.core.api.provider.BeanProvider;
 import org.apache.deltaspike.core.util.ClassUtils;
 
 
-class MessageBundleInvocationHandler implements InvocationHandler
+public class MessageBundleInvocationHandler implements InvocationHandler, Serializable
 {
     /**
      * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/TypedMessageBundleProducer.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/TypedMessageBundleProducer.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/TypedMessageBundleProducer.java
index 466d404..f13ccb1 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/TypedMessageBundleProducer.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/TypedMessageBundleProducer.java
@@ -18,7 +18,6 @@
  */
 package org.apache.deltaspike.core.impl.message;
 
-import static org.apache.deltaspike.core.util.ReflectionUtils.getRawType;
 
 import java.io.Serializable;
 import java.lang.reflect.Proxy;
@@ -27,6 +26,7 @@ import javax.enterprise.inject.Produces;
 import javax.enterprise.inject.spi.InjectionPoint;
 
 import org.apache.deltaspike.core.util.ClassUtils;
+import org.apache.deltaspike.core.util.ReflectionUtils;
 
 /**
  * The <code>TypedMessageBundleProducer</code> provides a producer method for
@@ -41,7 +41,7 @@ public class TypedMessageBundleProducer implements Serializable
     @SuppressWarnings("UnusedDeclaration")
     Object produceTypedMessageBundle(InjectionPoint injectionPoint)
     {
-        return createMessageBundleProxy(getRawType(injectionPoint.getType()));
+        return createMessageBundleProxy(ReflectionUtils.getRawType(injectionPoint.getType()));
     }
 
     private <T> T createMessageBundleProxy(Class<T> type)

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/message/JsfMessage.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/message/JsfMessage.java b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/message/JsfMessage.java
index 0637c0c..8ddc298 100644
--- a/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/message/JsfMessage.java
+++ b/deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/message/JsfMessage.java
@@ -18,6 +18,8 @@
  */
 package org.apache.deltaspike.jsf.message;
 
+import java.io.Serializable;
+
 /**
  * <p>An injectable component for typesafe FacesMessages.
  * T must be a class which is annotated with
@@ -39,8 +41,17 @@ package org.apache.deltaspike.jsf.message;
  * for creating the FacesMessage.</p>
  *
  */
-public interface JsfMessage<T>
+public interface JsfMessage<T> extends Serializable
 {
+    String CATEGORY_DETAIL = "detail";
+    String CATEGORY_SUMMARY = "summary";
+
+    /**
+     * If the JsfMessage is used in a UIComponent we allow to set the clientId
+     * @param clientId
+     */
+    JsfMessage<T> forClientId(String clientId);
+
     /**
      * @return the underlying Message which will automatically add a FacesMessage with SEVERITY_ERROR
      */

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/deltaspike/modules/jsf/impl/pom.xml
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/pom.xml b/deltaspike/modules/jsf/impl/pom.xml
index 26cd5d0..dd78267 100644
--- a/deltaspike/modules/jsf/impl/pom.xml
+++ b/deltaspike/modules/jsf/impl/pom.xml
@@ -40,6 +40,7 @@
         <dependency>
             <groupId>org.apache.deltaspike.core</groupId>
             <artifactId>deltaspike-core-impl</artifactId>
+            <scope>compile</scope>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/DefaultJsfMessage.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/DefaultJsfMessage.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/DefaultJsfMessage.java
index e8e9e92..9ff6a5a 100644
--- a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/DefaultJsfMessage.java
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/DefaultJsfMessage.java
@@ -18,45 +18,82 @@
  */
 package org.apache.deltaspike.jsf.impl.message;
 
+
+import javax.faces.application.FacesMessage;
+
+import java.lang.reflect.Proxy;
+
+import org.apache.deltaspike.core.api.message.annotation.MessageBundle;
+import org.apache.deltaspike.core.util.ClassUtils;
 import org.apache.deltaspike.jsf.message.JsfMessage;
 
 /**
  * Default implementation of JsfMessage.
+ * The complexity of setting the FacesMessage is
+ * done in the {@link JsfMessageBundleInvocationHandler}.
  */
 public class DefaultJsfMessage<T> implements JsfMessage<T>
 {
+    private String clientId = null;
+    private Class<T> type;
+
+    /**
+     * The Message type
+     * @param type
+     * @param clientId
+     */
+    public DefaultJsfMessage(Class<T> type, String clientId)
+    {
+        this.type = type;
+        this.clientId = clientId;
+
+        if (! type.isInterface() || type.getAnnotation(MessageBundle.class) == null)
+        {
+            throw new IllegalArgumentException("JsfMessage must only be used for interfaces " +
+                "annotated with @MessageBundle!");
+        }
+    }
+
+    @Override
+    public JsfMessage<T> forClientId(String clientId)
+    {
+        return new DefaultJsfMessage<T>(type, clientId);
+    }
+
     @Override
     public T addError()
     {
-        //X TODO
-        return null;
+        return getMessage(FacesMessage.SEVERITY_ERROR);
     }
 
     @Override
     public T addFatal()
     {
-        //X TODO
-        return null;
+        return getMessage(FacesMessage.SEVERITY_FATAL);
     }
 
     @Override
     public T addInfo()
     {
-        //X TODO
-        return null;
+        return getMessage(FacesMessage.SEVERITY_INFO);
     }
 
     @Override
     public T addWarn()
     {
-        //X TODO
-        return null;
+        return getMessage(FacesMessage.SEVERITY_WARN);
     }
 
     @Override
     public T get()
     {
-        //X TODO
-        return null;
+        return getMessage(null);
     }
+
+    private T getMessage(FacesMessage.Severity severity)
+    {
+        return type.cast(Proxy.newProxyInstance(ClassUtils.getClassLoader(null),
+                new Class<?>[]{type}, new JsfMessageBundleInvocationHandler(severity, clientId)));
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageBundleInvocationHandler.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageBundleInvocationHandler.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageBundleInvocationHandler.java
new file mode 100644
index 0000000..f8b6164
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageBundleInvocationHandler.java
@@ -0,0 +1,85 @@
+/*
+ * 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.jsf.impl.message;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import java.lang.reflect.Method;
+
+import org.apache.deltaspike.core.api.message.Message;
+import org.apache.deltaspike.core.impl.message.MessageBundleInvocationHandler;
+import org.apache.deltaspike.jsf.message.JsfMessage;
+
+/**
+ * This Proxy InvocationHandler automatically registers the
+ * returned messages in the FacesContext if a severity is set.
+ */
+public class JsfMessageBundleInvocationHandler extends MessageBundleInvocationHandler
+{
+    private FacesMessage.Severity severity;
+    private String clientId;
+
+    public JsfMessageBundleInvocationHandler(FacesMessage.Severity severity, String clientId)
+    {
+        this.severity = severity;
+        this.clientId = clientId;
+    }
+
+    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable
+    {
+        Object message = super.invoke(proxy, method, args);
+
+        if (severity == null)
+        {
+            return getMessageCategory(message, JsfMessage.CATEGORY_SUMMARY);
+        }
+        else
+        {
+            String summary = getMessageCategory(message, JsfMessage.CATEGORY_SUMMARY);
+            String detail = getMessageCategory(message, JsfMessage.CATEGORY_DETAIL);
+
+            FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(severity, summary, detail));
+
+            return message;
+        }
+    }
+
+    private String getMessageCategory(Object message, String category)
+    {
+        if (message == null)
+        {
+            return null;
+        }
+
+        if (message instanceof String)
+        {
+            return (String) message;
+        }
+        else if (message instanceof Message)
+        {
+            return ((Message) message).toString(category);
+        }
+        else
+        {
+            throw new IllegalArgumentException("message must be of either type String or Message but was: " +
+                message.getClass() + " value: " + message);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-deltaspike/blob/1b151a09/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageProducer.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageProducer.java b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageProducer.java
new file mode 100644
index 0000000..af4bd70
--- /dev/null
+++ b/deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageProducer.java
@@ -0,0 +1,48 @@
+/*
+ * 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.jsf.impl.message;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.InjectionPoint;
+
+import org.apache.deltaspike.core.util.ReflectionUtils;
+import org.apache.deltaspike.jsf.message.JsfMessage;
+
+/**
+ * Produces a dependent JsfMessage
+ */
+@ApplicationScoped
+public class JsfMessageProducer
+{
+    @Produces
+    @Dependent
+    public JsfMessage<?> createJsfMessage(InjectionPoint injectionPoint)
+    {
+        return createJsfMessageFor(injectionPoint, ReflectionUtils.getRawType(injectionPoint.getType()));
+    }
+
+    private JsfMessage<?> createJsfMessageFor(InjectionPoint injectionPoint, Class<Object> rawType)
+    {
+        //X TODO check if the JsfMessage should get injected into a UIComponent and use #getClientId()
+
+        return new DefaultJsfMessage(rawType, null);
+    }
+}