[seam-commits] Seam SVN: r11873 - in modules/remoting/trunk: src/main/java/org/jboss/seam/remoting/model and 1 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Mon Dec 21 21:19:09 EST 2009


Author: shane.bryzak at jboss.com
Date: 2009-12-21 21:19:09 -0500 (Mon, 21 Dec 2009)
New Revision: 11873

Modified:
   modules/remoting/trunk/examples/model/src/main/webapp/model.html
   modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java
   modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
   modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
Log:
server side handling for model apply updates


Modified: modules/remoting/trunk/examples/model/src/main/webapp/model.html
===================================================================
--- modules/remoting/trunk/examples/model/src/main/webapp/model.html	2009-12-22 00:31:37 UTC (rev 11872)
+++ modules/remoting/trunk/examples/model/src/main/webapp/model.html	2009-12-22 02:19:09 UTC (rev 11873)
@@ -38,8 +38,13 @@
       model.getValue("customer").setFirstName("bob");
     }
     
-    function applyModel() {
-      model.applyUpdates(); 
+    function applyUpdates() {
+      var callback = function(model) { alert("updates applied"); };
+      
+      model.applyUpdates(new Seam.Action()
+        .setBeanType("org.jboss.seam.remoting.examples.model.CustomerAction")
+        .setMethod("saveCustomer"),
+        callback);
     }
 
     // ]]>
@@ -49,7 +54,7 @@
   
   <button onclick="javascript:loadCustomer()">Load customer</button> 
   <button onclick="javascript:modifyCustomer()">Modify customer</button>
-  <button onclick="javascript:applyModel()">Apply changes</button>
+  <button onclick="javascript:applyUpdates()">Apply updates</button>
 
 
 </body>

Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java	2009-12-22 00:31:37 UTC (rev 11872)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/Model.java	2009-12-22 02:19:09 UTC (rev 11873)
@@ -3,6 +3,7 @@
 import java.io.Serializable;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
@@ -16,6 +17,8 @@
 import org.jboss.seam.remoting.AnnotationsParser;
 import org.jboss.seam.remoting.Call;
 import org.jboss.seam.remoting.CallContext;
+import org.jboss.seam.remoting.wrapper.ConversionException;
+import org.jboss.seam.remoting.wrapper.Wrapper;
 
 /**
  * Manages a model request
@@ -30,6 +33,7 @@
    private String id;
    private String callId;
    private CallContext callContext;
+   private Call action;
    
    public class BeanProperty implements Serializable
    {
@@ -189,8 +193,70 @@
       beanProperties.put(alias, new BeanProperty(bean, propertyName));
    }
    
+   public void setModelProperty(int refId, String name, Wrapper wrapper)
+   {
+      Wrapper outRef = callContext.getOutRefs().get(refId);
+      
+      try
+      {
+         Field f = outRef.getValue().getClass().getField(name);
+         if (wrapper.conversionScore(f.getType()).getScore() > 0)
+         {
+            // found a match
+            boolean accessible = f.isAccessible();
+            try
+            {
+               if (!f.isAccessible()) f.setAccessible(true);
+               f.set(outRef.getValue(), wrapper.convert(f.getType()));
+            }
+            catch (ConversionException ex)
+            {
+               throw new RuntimeException("Exception converting model property value", ex);
+            }
+            catch (IllegalAccessException ex)
+            {
+               throw new RuntimeException("Exception setting model property", ex);
+            }
+            finally
+            {
+               f.setAccessible(accessible);
+            }
+         }
+      }
+      catch (NoSuchFieldException ex)
+      {
+         String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+         for (Method m : outRef.getValue().getClass().getMethods())
+         {
+            if (m.getName().equals(methodName) && m.getParameterTypes().length == 1 &&
+                  wrapper.conversionScore(m.getParameterTypes()[0]).getScore() > 0)
+            {
+               try
+               {
+                  m.invoke(outRef.getValue(), wrapper.convert(m.getParameterTypes()[0]));
+                  break;
+               }
+               catch (Exception ex2) 
+               {
+                  throw new RuntimeException("Exception converting model property value", ex2);
+               }
+            }
+         }
+      }
+   }
+   
    public void applyChanges(Set<ChangeSet> delta)
    {
       
    }
+   
+   public void setAction(Call action)
+   {
+      this.action = action;
+   }
+   
+   public Call getAction() 
+   {
+      return action;
+   }
 }

Modified: modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java
===================================================================
--- modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java	2009-12-22 00:31:37 UTC (rev 11872)
+++ modules/remoting/trunk/src/main/java/org/jboss/seam/remoting/model/ModelHandler.java	2009-12-22 02:19:09 UTC (rev 11873)
@@ -4,13 +4,12 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.StringReader;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import javax.enterprise.context.Conversation;
+import javax.enterprise.inject.Instance;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.inject.Inject;
 import javax.servlet.http.HttpServletRequest;
@@ -20,10 +19,12 @@
 import org.dom4j.Element;
 import org.dom4j.io.SAXReader;
 import org.jboss.seam.remoting.Call;
+import org.jboss.seam.remoting.CallContext;
 import org.jboss.seam.remoting.MarshalUtils;
 import org.jboss.seam.remoting.RequestContext;
 import org.jboss.seam.remoting.RequestHandler;
 import org.jboss.seam.remoting.wrapper.Wrapper;
+import org.jboss.seam.remoting.wrapper.WrapperFactory;
 import org.jboss.weld.Container;
 import org.jboss.weld.context.ContextLifecycle;
 import org.jboss.weld.context.ConversationContext;
@@ -43,8 +44,8 @@
    
    @Inject BeanManager beanManager;
    @Inject ConversationManager conversationManager;
-   @Inject Conversation conversation;
    @Inject ModelRegistry registry;
+   @Inject Instance<Conversation> conversationInstance;
    
    @SuppressWarnings("unchecked")
    public void handle(HttpServletRequest request, HttpServletResponse response)
@@ -70,116 +71,196 @@
       final Element env = doc.getRootElement();
       final RequestContext ctx = new RequestContext(env.element("header"));
             
-      // Initialize the conversation context
-      ConversationContext conversationContext = Container.instance().deploymentServices().get(ContextLifecycle.class).getConversationContext();
-      conversationContext.setBeanStore(new ConversationBeanStore(request.getSession(), ctx.getConversationId()));
-      conversationContext.setActive(true);
-      
-      if (ctx.getConversationId() != null && !ctx.getConversationId().isEmpty())
-      { 
-         conversationManager.beginOrRestoreConversation(ctx.getConversationId());
-      }
-      else
+      ConversationContext conversationContext = null;
+      try
       {
-         conversationManager.beginOrRestoreConversation(null);
-      }
-      
-      Set<Model> models = new HashSet<Model>();
-      Call action = null;      
-      
-      for (Element modelElement : (List<Element>) env.element("body").elements("model"))
-      {     
-         String operation = modelElement.attributeValue("operation");
-         String callId = modelElement.attributeValue("callId");
+         // Initialize the conversation context
+         conversationContext = Container.instance().deploymentServices().get(ContextLifecycle.class).getConversationContext();
+         conversationContext.setBeanStore(new ConversationBeanStore(request.getSession(), ctx.getConversationId()));
+         conversationContext.setActive(true);  
          
-         if ("fetch".equals(operation))
+         if (ctx.getConversationId() != null && !ctx.getConversationId().isEmpty())
+         { 
+            conversationManager.beginOrRestoreConversation(ctx.getConversationId());
+         }
+         else
          {
-            Model model = registry.createModel();
-            models.add(model);
-            model.setCallId(callId);           
+            conversationManager.beginOrRestoreConversation(null);
+         }
+         
+         Set<Model> models = new HashSet<Model>(); 
+         
+         for (Element modelElement : (List<Element>) env.element("body").elements("model"))
+         {     
+            String operation = modelElement.attributeValue("operation");
+            String callId = modelElement.attributeValue("callId");
             
-            if (modelElement.elements("action").size() > 0)
+            if ("fetch".equals(operation))
             {
-               Element actionElement = modelElement.element("action");
-               Element targetElement = actionElement.element("target");
-               Element qualifiersElement = actionElement.element("qualifiers");
-               Element methodElement = actionElement.element("method");
-               Element paramsElement = actionElement.element("params");
-               Element refsElement = actionElement.element("refs");
-               
-               action = new Call(beanManager, callId, targetElement.getTextTrim(), 
-                    qualifiersElement != null ? qualifiersElement.getTextTrim() : null, 
-                    methodElement != null ? methodElement.getTextTrim() : null);                        
-   
-               if (refsElement != null)
-               {
-                  for (Element refElement : (List<Element>) refsElement.elements("ref"))
-                  {
-                     action.getContext().createWrapperFromElement(refElement);
-                  }
-      
-                  for (Wrapper w : action.getContext().getInRefs().values())
-                  {
-                     w.unmarshal();
-                  }
-               }
-   
-               if (paramsElement != null)
-               {
-                  for (Element paramElement : (List<Element>) paramsElement.elements("param"))
-                  {
-                     action.addParameter(action.getContext().createWrapperFromElement(
-                           (Element) paramElement.elements().get(0)));
-                  }
-               }
+               processFetchRequest(modelElement, models, callId);
             }
-            
-            for (Element beanElement : (List<Element>) modelElement.elements("bean"))
+            else if ("apply".equals(operation))
             {
-               Element beanNameElement = beanElement.element("name");
-               Element beanQualifierElement = beanElement.element("qualifier");
-               Element beanPropertyElement = beanElement.element("property");
-               
-               model.addBean(beanElement.attributeValue("alias"),
-                     beanNameElement.getTextTrim(), 
-                     beanQualifierElement != null ? beanQualifierElement.getTextTrim() : null, 
-                     beanPropertyElement != null ? beanPropertyElement.getTextTrim() : null);
+               processApplyRequest(modelElement, models, callId);
             }
-            
-            // TODO Unmarshal expressions - don't support this until security implications investigated
-            for (Element exprElement : (List<Element>) modelElement.elements("expression"))
+         }
+   
+         for (Model model : models)
+         {
+            if (model.getAction() != null && model.getAction().getException() != null)
             {
-               
+               out.write(ENVELOPE_TAG_OPEN);
+               out.write(BODY_TAG_OPEN);         
+               MarshalUtils.marshalException(model.getAction().getException(), 
+                     model.getAction().getContext(), out);
+               out.write(BODY_TAG_CLOSE);
+               out.write(ENVELOPE_TAG_CLOSE);
+               out.flush();
+               return;
             }
-            
-            if (action != null)
-            {
-               action.execute();                              
-            }            
          }
-      }
-
-      if (action != null && action.getException() != null)
-      {
-         out.write(ENVELOPE_TAG_OPEN);
-         out.write(BODY_TAG_OPEN);         
-         MarshalUtils.marshalException(action.getException(), action.getContext(), out);
-         out.write(BODY_TAG_CLOSE);
-         out.write(ENVELOPE_TAG_CLOSE);
-         out.flush();
-      }      
-      else
-      {      
+         
          for (Model model : models)
          {
             model.evaluate();
          }
          
+         Conversation conversation = conversationInstance.get();
          ctx.setConversationId(conversation.getId());      
          marshalResponse(models, ctx, response.getOutputStream());
       }
+      finally
+      {
+         if (conversationContext != null)
+         {
+            conversationContext.setBeanStore(null);
+            conversationContext.setActive(false);            
+         }
+      }
    }
    
+   @SuppressWarnings({ "unchecked" }) 
+   private void processFetchRequest(Element modelElement, Set<Model> models, String callId)
+      throws Exception
+   {
+      Model model = registry.createModel();
+      models.add(model);
+      model.setCallId(callId);           
+      
+      if (modelElement.elements("action").size() > 0)
+      {         
+         unmarshalAction(modelElement.element("action"), model, callId);
+      }
+      
+      for (Element beanElement : (List<Element>) modelElement.elements("bean"))
+      {
+         Element beanNameElement = beanElement.element("name");
+         Element beanQualifierElement = beanElement.element("qualifier");
+         Element beanPropertyElement = beanElement.element("property");
+         
+         model.addBean(beanElement.attributeValue("alias"),
+               beanNameElement.getTextTrim(), 
+               beanQualifierElement != null ? beanQualifierElement.getTextTrim() : null, 
+               beanPropertyElement != null ? beanPropertyElement.getTextTrim() : null);
+      }
+      
+      // TODO Unmarshal expressions - don't support this until security implications investigated
+      for (Element exprElement : (List<Element>) modelElement.elements("expression"))
+      {
+         
+      }
+      
+      if (model.getAction() != null)
+      {
+         model.getAction().execute();                              
+      }         
+   }
+   
+   @SuppressWarnings("unchecked")
+   private void unmarshalAction(Element actionElement, Model model, String callId)
+   {
+      Element targetElement = actionElement.element("target");
+      Element qualifiersElement = actionElement.element("qualifiers");
+      Element methodElement = actionElement.element("method");
+      Element paramsElement = actionElement.element("params");
+      Element refsElement = actionElement.element("refs");
+      
+      model.setAction(new Call(beanManager, callId, targetElement.getTextTrim(), 
+           qualifiersElement != null ? qualifiersElement.getTextTrim() : null, 
+           methodElement != null ? methodElement.getTextTrim() : null));                        
+
+      if (refsElement != null)
+      {
+         for (Element refElement : (List<Element>) refsElement.elements("ref"))
+         {
+            model.getAction().getContext().createWrapperFromElement(refElement);
+         }
+
+         for (Wrapper w : model.getAction().getContext().getInRefs().values())
+         {
+            w.unmarshal();
+         }
+      }
+
+      if (paramsElement != null)
+      {
+         for (Element paramElement : (List<Element>) paramsElement.elements("param"))
+         {
+            model.getAction().addParameter(model.getAction().getContext().createWrapperFromElement(
+                  (Element) paramElement.elements().get(0)));
+         }
+      }      
+   }
+   
+   @SuppressWarnings("unchecked")
+   private void processApplyRequest(Element modelElement, Set<Model> models, String callId)
+      throws Exception
+   {
+      Model model = registry.getModel(modelElement.attributeValue("uid"));
+      model.setCallId(callId); 
+      model.setAction(null);
+      
+      CallContext ctx = new CallContext(beanManager);
+      
+      Element refsElement = modelElement.element("refs");
+      for (Element ref : (List<Element>) refsElement.elements("ref"))
+      {
+         ctx.createWrapperFromElement(ref);
+      }
+      
+      Element delta = modelElement.element("delta");
+      if (delta != null)
+      {
+         List<Element> changesets = delta.elements("changeset");
+         for (Element changeset : changesets)
+         {
+            int refId = Integer.parseInt(changeset.attributeValue("refid"));
+            
+            if (changeset.elements("member").size() > 0)
+            {
+               for (Element member : (List<Element>) changeset.elements("member"))
+               {
+                  String name = member.attributeValue("name");
+                  Wrapper w = model.getCallContext().createWrapperFromElement(
+                        (Element) member.elementIterator().next());
+                  model.setModelProperty(refId, name, w);                  
+               }
+            }
+            
+         }
+      }
+      
+      if (modelElement.elements("action").size() > 0)
+      {         
+         unmarshalAction(modelElement.element("action"), model, callId);
+      }      
+      
+      if (model.getAction() != null)
+      {
+         model.getAction().execute();                              
+      }               
+   }
+   
    private void marshalResponse(Set<Model> models, RequestContext ctx, 
          OutputStream out) throws IOException
    {

Modified: modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js
===================================================================
--- modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js	2009-12-22 00:31:37 UTC (rev 11872)
+++ modules/remoting/trunk/src/main/resources/org/jboss/seam/remoting/remote.js	2009-12-22 02:19:09 UTC (rev 11873)
@@ -928,7 +928,7 @@
   
   Seam.Model.prototype.createApplyRequest = function(a, delta) {
     var callId = "" + Seam.__callId++;
-    var d = "<model operation=\"apply\" callId=\"" + callId + "\">";
+    var d = "<model uid=\"" + this.id + "\" operation=\"apply\" callId=\"" + callId + "\">";
     var refs = delta.buildRefs();
     if (a) {
       d += "<action>";



More information about the seam-commits mailing list