[seam-commits] Seam SVN: r9536 - trunk/src/remoting/org/jboss/seam/remoting.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Mon Nov 10 04:54:24 EST 2008


Author: shane.bryzak at jboss.com
Date: 2008-11-10 04:54:23 -0500 (Mon, 10 Nov 2008)
New Revision: 9536

Modified:
   trunk/src/remoting/org/jboss/seam/remoting/Call.java
   trunk/src/remoting/org/jboss/seam/remoting/ExecutionHandler.java
   trunk/src/remoting/org/jboss/seam/remoting/InterfaceGenerator.java
   trunk/src/remoting/org/jboss/seam/remoting/MarshalUtils.java
   trunk/src/remoting/org/jboss/seam/remoting/remote.js
Log:
JBSEAM-633

Modified: trunk/src/remoting/org/jboss/seam/remoting/Call.java
===================================================================
--- trunk/src/remoting/org/jboss/seam/remoting/Call.java	2008-11-10 06:24:00 UTC (rev 9535)
+++ trunk/src/remoting/org/jboss/seam/remoting/Call.java	2008-11-10 09:54:23 UTC (rev 9536)
@@ -1,5 +1,6 @@
 package org.jboss.seam.remoting;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -16,214 +17,250 @@
 import org.jboss.seam.util.EJB;
 
 /**
- *
+ * 
  * @author Shane Bryzak
  */
 public class Call
 {
-  private String id;
-  private String componentName;
-  private String methodName;
-  //private String expression;
+   private String id;
+   private String componentName;
+   private String methodName;
+   // private String expression;
+   private Throwable exception;
 
-  private List<Wrapper> params = new ArrayList<Wrapper> ();
+   private List<Wrapper> params = new ArrayList<Wrapper>();
 
-  private Object result;
+   private Object result;
 
-  private CallContext context;
+   private CallContext context;
 
-  private List<String> constraints = null;
+   private List<String> constraints = null;
 
-  /**
-   * Constructor.
-   *
-   * @param componentName String
-   * @param methodName String
-   */
-  public Call(String id, String componentName, String methodName)
-  {
-    this.id = id;
-    this.componentName = componentName;
-    this.methodName = methodName;
-    this.context = new CallContext();
-  }
+   /**
+    * Constructor.
+    * 
+    * @param componentName
+    *           String
+    * @param methodName
+    *           String
+    */
+   public Call(String id, String componentName, String methodName) {
+      this.id = id;
+      this.componentName = componentName;
+      this.methodName = methodName;
+      this.context = new CallContext();
+   }
 
-  /**
-   * Return the call context.
-   *
-   * @return CallContext
-   */
-  public CallContext getContext()
-  {
-    return context;
-  }
+   /**
+    * Return the call context.
+    * 
+    * @return CallContext
+    */
+   public CallContext getContext()
+   {
+      return context;
+   }
+   
+   /**
+    * Returns the exception thrown by the invoked method.  If no exception was thrown,
+    * will return null.
+    */
+   public Throwable getException()
+   {
+      return exception;
+   }
 
-  /**
-   * Add a parameter to this call.
-   *
-   * @param param BaseWrapper
-   */
-  public void addParameter(Wrapper param)
-  {
-    params.add(param);
-  }
+   /**
+    * Add a parameter to this call.
+    * 
+    * @param param
+    */
+   public void addParameter(Wrapper param)
+   {
+      params.add(param);
+   }
 
-  /**
-   * Returns the result of this call.
-   *
-   * @return Wrapper
-   */
-  public Object getResult()
-  {
-    return result;
-  }
+   /**
+    * Returns the result of this call.
+    * 
+    * @return Wrapper
+    */
+   public Object getResult()
+   {
+      return result;
+   }
 
-  /**
-   * Returns the id of this call.
-   *
-   * @return String
-   */
-  public String getId()
-  {
-    return id;
-  }
+   /**
+    * Returns the id of this call.
+    * 
+    * @return String
+    */
+   public String getId()
+   {
+      return id;
+   }
 
-  /**
-   * Returns the object graph constraints annotated on the method that is called.
-   *
-   * @return List The constraints
-   */
-  public List<String> getConstraints()
-  {
-    return constraints;
-  }
+   /**
+    * Returns the object graph constraints annotated on the method that is
+    * called.
+    * 
+    * @return List The constraints
+    */
+   public List<String> getConstraints()
+   {
+      return constraints;
+   }
 
-  /**
-   * Execute this call
-   *
-   * @throws Exception
-   */
-  public void execute()
-      throws Exception
-  {
-     if (componentName != null)
-     {
-        processInvocation();
-     }
-  }
-  
-  private void processInvocation()
-     throws Exception
-  {     
-     // Find the component we're calling
-     Component component = Component.forName(componentName);
+   /**
+    * Execute this call
+    * 
+    * @throws Exception
+    */
+   public void execute() throws Exception
+   {
+      if (componentName != null)
+      {
+         processInvocation();
+      }
+   }
 
-     if (component == null)
-       throw new RuntimeException("No such component: " + componentName);
+   private void processInvocation() throws Exception
+   {
+      // Find the component we're calling
+      Component component = Component.forName(componentName);
 
-     // Create an instance of the component
-     Object instance = Component.getInstance(componentName, true);
-     
-     if (instance == null)
-     {
-        throw new RuntimeException(String.format(
-              "Could not create instance of component %s", componentName));
-     }
+      if (component == null)
+      {
+         throw new RuntimeException("No such component: " + componentName);
+      }
 
-     Class type = null;
+      // Create an instance of the component
+      Object instance = Component.getInstance(componentName, true);
 
-     if (component.getType().isSessionBean() &&
-         component.getBusinessInterfaces().size() > 0)
-     {
-       for (Class c : component.getBusinessInterfaces())
-       {
-         if (c.isAnnotationPresent(EJB.LOCAL))
+      if (instance == null)
+      {
+         throw new RuntimeException(String.format(
+               "Could not create instance of component %s", componentName));
+      }
+
+      Class type = null;
+
+      if (component.getType().isSessionBean()
+            && component.getBusinessInterfaces().size() > 0)
+      {
+         for (Class c : component.getBusinessInterfaces())
          {
-           type = c;
-           break;
+            if (c.isAnnotationPresent(EJB.LOCAL))
+            {
+               type = c;
+               break;
+            }
          }
-       }
 
-       if (type == null)
-         throw new RuntimeException(String.format(
-         "Type cannot be determined for component [%s]. Please ensure that it has a local interface.", component));
-     }
+         if (type == null)
+         {
+            throw new RuntimeException(String.format(
+               "Type cannot be determined for component [%s]. Please ensure that it has a local interface.",
+               component));
+         }
+      }
 
-     if (type == null)
-       type = component.getBeanClass();
+      if (type == null)
+      {
+         type = component.getBeanClass();
+      }
 
-     // Find the method according to the method name and the parameter classes
-     Method m = findMethod(methodName, type);
-     if (m == null)
-       throw new RuntimeException("No compatible method found.");
+      // Find the method according to the method name and the parameter classes
+      Method m = findMethod(methodName, type);
+      if (m == null)
+         throw new RuntimeException("No compatible method found.");
 
-     if (m.getAnnotation(WebRemote.class).exclude().length > 0)
-       constraints = Arrays.asList(m.getAnnotation(WebRemote.class).exclude());
+      if (m.getAnnotation(WebRemote.class).exclude().length > 0)
+         constraints = Arrays
+               .asList(m.getAnnotation(WebRemote.class).exclude());
 
-     // Invoke!
-     result = m.invoke(instance, convertParams(m.getGenericParameterTypes()));     
-  }
+      Object[] params = convertParams(m.getGenericParameterTypes());
 
-  /**
-   * Convert our parameter values to an Object array of the specified target
-   * types.
-   *
-   * @param targetTypes Class[] An array containing the target class types.
-   * @return Object[] The converted parameter values.
-   */
-  private Object[] convertParams(Type[] targetTypes)
-      throws ConversionException
-  {
-    Object[] paramValues = new Object[targetTypes.length];
+      // Invoke!
+      try
+      {
+         result = m.invoke(instance, params);
+      } 
+      catch (InvocationTargetException e)
+      {
+         this.exception = e.getCause();
+      }
+   }
 
-    for (int i = 0; i < targetTypes.length; i++)
-      paramValues[i] = params.get(i).convert(targetTypes[i]);
+   /**
+    * Convert our parameter values to an Object array of the specified target
+    * types.
+    * 
+    * @param targetTypes
+    *           Class[] An array containing the target class types.
+    * @return Object[] The converted parameter values.
+    */
+   private Object[] convertParams(Type[] targetTypes)
+         throws ConversionException
+   {
+      Object[] paramValues = new Object[targetTypes.length];
 
-    return paramValues;
-  }
+      for (int i = 0; i < targetTypes.length; i++)
+      {
+         paramValues[i] = params.get(i).convert(targetTypes[i]);
+      }
 
-  /**
-   * Find the best matching method within the specified class according to
-   * the parameter types that were provided to the Call.
-   *
-   * @param name String The name of the method.
-   * @param cls Class The Class to search in.
-   * @return Method The best matching method.
-   */
-  private Method findMethod(String name, Class cls)
-  {
-    Map<Method, Integer> candidates = new HashMap<Method, Integer> ();
+      return paramValues;
+   }
 
-    for (Method m : cls.getDeclaredMethods()) {
-      if (m.getAnnotation(WebRemote.class) == null)
-        continue;
+   /**
+    * Find the best matching method within the specified class according to the
+    * parameter types that were provided to the Call.
+    * 
+    * @param name
+    *           String The name of the method.
+    * @param cls
+    *           Class The Class to search in.
+    * @return Method The best matching method.
+    */
+   private Method findMethod(String name, Class cls)
+   {
+      Map<Method, Integer> candidates = new HashMap<Method, Integer>();
 
-      if (name.equals(m.getName()) &&
-          m.getParameterTypes().length == params.size()) {
-        int score = 0;
+      for (Method m : cls.getDeclaredMethods())
+      {
+         if (m.getAnnotation(WebRemote.class) == null) continue;
 
-        for (int i = 0; i < m.getParameterTypes().length; i++) {
-          ConversionScore convScore = params.get(i).conversionScore(m.getParameterTypes()[
-              i]);
-          if (convScore == ConversionScore.nomatch)
-            continue;
-          score += convScore.getScore();
-        }
-        candidates.put(m, score);
+         if (name.equals(m.getName())
+               && m.getParameterTypes().length == params.size())
+         {
+            int score = 0;
+
+            for (int i = 0; i < m.getParameterTypes().length; i++)
+            {
+               ConversionScore convScore = params.get(i).conversionScore(
+                     m.getParameterTypes()[i]);
+               if (convScore == ConversionScore.nomatch)
+                  continue;
+               score += convScore.getScore();
+            }
+            candidates.put(m, score);
+         }
       }
-    }
 
-    Method bestMethod = null;
-    int bestScore = 0;
+      Method bestMethod = null;
+      int bestScore = 0;
 
-    for (Method m : candidates.keySet()) {
-      int thisScore = candidates.get(m).intValue();
-      if (bestMethod == null || thisScore > bestScore) {
-        bestMethod = m;
-        bestScore = thisScore;
+      for (Method m : candidates.keySet())
+      {
+         int thisScore = candidates.get(m).intValue();
+         if (bestMethod == null || thisScore > bestScore)
+         {
+            bestMethod = m;
+            bestScore = thisScore;
+         }
       }
-    }
 
-    return bestMethod;
-  }
+      return bestMethod;
+   }
 }

Modified: trunk/src/remoting/org/jboss/seam/remoting/ExecutionHandler.java
===================================================================
--- trunk/src/remoting/org/jboss/seam/remoting/ExecutionHandler.java	2008-11-10 06:24:00 UTC (rev 9535)
+++ trunk/src/remoting/org/jboss/seam/remoting/ExecutionHandler.java	2008-11-10 09:54:23 UTC (rev 9536)
@@ -223,8 +223,7 @@
 
     for (Call call : calls)
     {
-      MarshalUtils.marshalResult(call.getId(), call.getContext(), out,
-                                 call.getResult(), call.getConstraints());
+      MarshalUtils.marshalResult(call, out);
     }
 
     out.write(BODY_TAG_CLOSE);

Modified: trunk/src/remoting/org/jboss/seam/remoting/InterfaceGenerator.java
===================================================================
--- trunk/src/remoting/org/jboss/seam/remoting/InterfaceGenerator.java	2008-11-10 06:24:00 UTC (rev 9535)
+++ trunk/src/remoting/org/jboss/seam/remoting/InterfaceGenerator.java	2008-11-10 09:54:23 UTC (rev 9536)
@@ -361,7 +361,7 @@
       }
 
       if (m.getGenericParameterTypes().length > 0) componentSrc.append(", ");
-      componentSrc.append("callback) {\n");
+      componentSrc.append("callback, exceptionHandler) {\n");
 
       componentSrc.append("    return Seam.Remoting.execute(this, \"");
       componentSrc.append(m.getName());
@@ -374,7 +374,7 @@
         componentSrc.append(i);
       }
 
-      componentSrc.append("], callback);\n");
+      componentSrc.append("], callback, exceptionHandler);\n");
 
       componentSrc.append("  }\n");
     }

Modified: trunk/src/remoting/org/jboss/seam/remoting/MarshalUtils.java
===================================================================
--- trunk/src/remoting/org/jboss/seam/remoting/MarshalUtils.java	2008-11-10 06:24:00 UTC (rev 9535)
+++ trunk/src/remoting/org/jboss/seam/remoting/MarshalUtils.java	2008-11-10 09:54:23 UTC (rev 9536)
@@ -20,46 +20,63 @@
 
   private static final byte[] VALUE_TAG_OPEN = "<value>".getBytes();
   private static final byte[] VALUE_TAG_CLOSE = "</value>".getBytes();
+  
+  private static final byte[] EXCEPTION_TAG_OPEN = "<exception>".getBytes();
+  private static final byte[] EXCEPTION_TAG_CLOSE = "</exception>".getBytes();
+  
+  private static final byte[] MESSAGE_TAG_OPEN = "<message>".getBytes();
+  private static final byte[] MESSAGE_TAG_CLOSE = "</message>".getBytes();
 
-  public static void marshalResult(String callId, CallContext ctx, OutputStream out,
-                                   Object result, List<String> constraints)
+  public static void marshalResult(Call call, OutputStream out)
       throws IOException
   {
-    if (callId != null)
+    if (call.getId() != null)
     {
       out.write(RESULT_TAG_OPEN_START);
-      out.write(callId.getBytes());
+      out.write(call.getId().getBytes());
       out.write(RESULT_TAG_OPEN_END);
     }
     else
       out.write(RESULT_TAG_OPEN);
 
-    out.write(VALUE_TAG_OPEN);
-
-    ctx.createWrapperFromObject(result, "").marshal(out);
-
-    out.write(VALUE_TAG_CLOSE);
-
-    out.write(RequestHandler.REFS_TAG_OPEN);
-
-    // Using a for-loop, because stuff can get added to outRefs as we recurse the object graph
-    for (int i = 0; i < ctx.getOutRefs().size(); i++)
+    if (call.getException() != null)
     {
-      Wrapper wrapper = ctx.getOutRefs().get(i);
-
-      out.write(RequestHandler.REF_TAG_OPEN_START);
-      out.write(Integer.toString(i).getBytes());
-      out.write(RequestHandler.REF_TAG_OPEN_END);
-
-      if (wrapper instanceof BeanWrapper && constraints != null)
-        ((BeanWrapper) wrapper).serialize(out, constraints);
-      else
-        wrapper.serialize(out);
-
-      out.write(RequestHandler.REF_TAG_CLOSE);
+       out.write(EXCEPTION_TAG_OPEN);
+       out.write(MESSAGE_TAG_OPEN);
+       call.getContext().createWrapperFromObject(call.getException().getMessage(), "").marshal(out);
+       out.write(MESSAGE_TAG_CLOSE);
+       out.write(EXCEPTION_TAG_CLOSE);
     }
-
-    out.write(RequestHandler.REFS_TAG_CLOSE);
+    else
+    {
+       out.write(VALUE_TAG_OPEN);
+   
+       call.getContext().createWrapperFromObject(call.getResult(), "").marshal(out);
+   
+       out.write(VALUE_TAG_CLOSE);
+   
+       out.write(RequestHandler.REFS_TAG_OPEN);
+   
+       // Using a for-loop, because stuff can get added to outRefs as we recurse the object graph
+       for (int i = 0; i < call.getContext().getOutRefs().size(); i++)
+       {
+         Wrapper wrapper = call.getContext().getOutRefs().get(i);
+   
+         out.write(RequestHandler.REF_TAG_OPEN_START);
+         out.write(Integer.toString(i).getBytes());
+         out.write(RequestHandler.REF_TAG_OPEN_END);
+   
+         if (wrapper instanceof BeanWrapper && call.getConstraints() != null)
+           ((BeanWrapper) wrapper).serialize(out, call.getConstraints());
+         else
+           wrapper.serialize(out);
+   
+         out.write(RequestHandler.REF_TAG_CLOSE);
+       }
+   
+       out.write(RequestHandler.REFS_TAG_CLOSE);
+    }
+    
     out.write(RESULT_TAG_CLOSE);
   }
 }

Modified: trunk/src/remoting/org/jboss/seam/remoting/remote.js
===================================================================
--- trunk/src/remoting/org/jboss/seam/remoting/remote.js	2008-11-10 06:24:00 UTC (rev 9535)
+++ trunk/src/remoting/org/jboss/seam/remoting/remote.js	2008-11-10 09:54:23 UTC (rev 9536)
@@ -152,7 +152,8 @@
   }
 }
 
-Seam.Remoting.__Context = function() {
+Seam.Remoting.__Context = function()
+{
   this.conversationId = null;
 
   Seam.Remoting.__Context.prototype.setConversationId = function(conversationId)
@@ -166,6 +167,16 @@
   }
 }
 
+Seam.Remoting.Exception = function(msg) 
+{
+  this.message = msg;
+  
+  Seam.Remoting.Exception.prototype.getMessage = function()
+  {
+    return this.message;
+  }
+}
+
 Seam.Remoting.context = new Seam.Remoting.__Context();
 
 Seam.Remoting.getContext = function()
@@ -466,7 +477,7 @@
 //  call.asyncReq = Seam.Remoting.sendAjaxRequest(envelope, Seam.Remoting.PATH_EXECUTE, Seam.Remoting.processResponse, false);
 //}
 
-Seam.Remoting.createCall = function(component, methodName, params, callback)
+Seam.Remoting.createCall = function(component, methodName, params, callback, exceptionHandler)
 {
   var callId = "" + Seam.Remoting.__callId++;
   if (!callback)
@@ -506,7 +517,7 @@
 
   data += "</call>";
 
-  return {data: data, id: callId, callback: callback};
+  return {data: data, id: callId, callback: callback, exceptionHandler: exceptionHandler};
 }
 
 Seam.Remoting.createHeader = function()
@@ -597,9 +608,9 @@
   }
 }
 
-Seam.Remoting.execute = function(component, methodName, params, callback)
+Seam.Remoting.execute = function(component, methodName, params, callback, exceptionHandler)
 {
-  var call = Seam.Remoting.createCall(component, methodName, params, callback);
+  var call = Seam.Remoting.createCall(component, methodName, params, callback, exceptionHandler);
 
   if (Seam.Remoting.inBatch)
   {
@@ -765,10 +776,11 @@
   var call = Seam.Remoting.pendingCalls.get(callId);
   Seam.Remoting.pendingCalls.remove(callId);
 
-  if (call && call.callback)
+  if (call && (call.callback || call.exceptionHandler))
   {
     var valueNode = null;
     var refsNode = null;
+    var exceptionNode = null;
 
     var children = result.childNodes;
     for (var i = 0; i < children.length; i++)
@@ -778,15 +790,35 @@
         valueNode = children.item(i);
       else if (tag == "refs")
         refsNode = children.item(i);
+      else if (tag == "exception")
+        exceptionNode = children.item(i);
     }
 
-    var refs = new Array();
-    if (refsNode)
-      Seam.Remoting.unmarshalRefs(refsNode, refs);
-
-    var value = Seam.Remoting.unmarshalValue(valueNode.firstChild, refs);
-
-    call.callback(value, context, callId);
+    if (exceptionNode != null)
+    {
+      var msgNode = null;
+      var children = exceptionNode.childNodes;
+      for (var i = 0; i < children.length; i++)
+      {
+        var tag = children.item(i).tagName;
+        if (tag == "message")
+          msgNode = children.item(i); 
+      }
+      
+      var msg = Seam.Remoting.unmarshalValue(msgNode.firstChild);
+      var ex = new Seam.Remoting.Exception(msg);
+      call.exceptionHandler(ex); 
+    }
+    else
+    {
+      var refs = new Array();
+      if (refsNode)
+        Seam.Remoting.unmarshalRefs(refsNode, refs);
+  
+      var value = Seam.Remoting.unmarshalValue(valueNode.firstChild, refs);
+  
+      call.callback(value, context, callId);
+    }
   }
 }
 




More information about the seam-commits mailing list