[jboss-svn-commits] JBL Code SVN: r14785 - in labs/jbossesb/trunk/product/rosetta: tests/src/org/jboss/soa/esb/message/mapping and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Aug 31 11:52:17 EDT 2007


Author: kevin.conner at jboss.com
Date: 2007-08-31 11:52:17 -0400 (Fri, 31 Aug 2007)
New Revision: 14785

Modified:
   labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/message/mapping/ObjectMapper.java
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/FromMessageMapperUnitTest.java
   labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/ToMessageMapperUnitTest.java
Log:
Allow qualified names in ObjectMapper: JBESB-944

Modified: labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/message/mapping/ObjectMapper.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/message/mapping/ObjectMapper.java	2007-08-31 15:48:41 UTC (rev 14784)
+++ labs/jbossesb/trunk/product/rosetta/src/org/jboss/soa/esb/message/mapping/ObjectMapper.java	2007-08-31 15:52:17 UTC (rev 14785)
@@ -41,7 +41,21 @@
     /** Name to get the byte[] content */
     public static String BODY_CONTENT = "BODY_CONTENT";
     private Logger logger = Logger.getLogger(this.getClass());
+    
     /**
+     * The quote used to delimit names.
+     */
+    private static final char QUOTE = '\'' ;
+    /**
+     * The escape character used to within names.
+     */
+    private static final char ESCAPE = '\\' ;
+    /**
+     * The expression separator character.
+     */
+    private static final char EXPRESSION_SEPARATOR = '.' ;
+
+    /**
      * 
      * body.myObject will add 'myObject', while
      * body.myObject.mySubObject will create an entry of 'mySubObject'. 
@@ -139,16 +153,11 @@
         throws ObjectMappingException
     {
         Object object=null;
-        String[] path = expression.split("\\.");
-        if (path.length<2) {
-            if (path.length==1) {
-                //assuming we mean the body
-                expression = "body." + expression;
-                path = expression.split("\\.");
-            } else {
-                throw new ObjectMappingException(expression + " should start with [<location>.]<name>");
-            }
-        } 
+        final String[] path = getExpressionPath(expression) ;
+        if (path.length == 0)
+        {
+            throw new ObjectMappingException(expression + " should start with [<location>.]<name>") ;
+        }
         String location = path[0];
         String name     = path[1];
         if ("body".equalsIgnoreCase(location)) {
@@ -172,10 +181,8 @@
             throw new ObjectMappingException(expression + " should start with one of [header,body,properties,attachment]");
         }
         //If needed use MVEL for evaluation of the rest of the path
-        if (path.length>2) {
-            int beginIndex = expression.indexOf(".",expression.indexOf(".")+1)+1;
-            expression = expression.substring(beginIndex);
-            object = MVEL.getProperty(expression, object);
+        if (path.length==3) {
+            object = MVEL.getProperty(path[2], object);
         }
         return object;
     }
@@ -191,16 +198,15 @@
     public void setObjectOnMessage(Message message, String expression, Object object)
         throws ObjectMappingException
     {
-        String[] path = expression.split("\\.");
-        if (path.length<2) {
-            if (path.length==1) {
-                //assuming we mean the body
-                expression = "body." + expression;
-                path = expression.split("\\.");
-            } else {
-                throw new ObjectMappingException(expression + " should start with [<location>.]<name>");
-            }
+        String[] path = getExpressionPath(expression) ;
+        if(path.length == 0)
+        {
+            throw new ObjectMappingException(expression + " should start with [<location>.]<name>") ;
         }
+        else if ((path.length > 2) && !"header".equals(path[0]))
+        {
+            throw new ObjectMappingException("Only 'header' can contain hierarchical names: " + expression) ;
+        }
         String location = path[0];
         String name     = path[1];
         if ("body".equalsIgnoreCase(location)) {
@@ -220,6 +226,14 @@
                 message.getAttachment().put(name, object);
             }
         } else if ("header".equalsIgnoreCase(location)) {
+            if (path.length == 2)
+            {
+                expression = location + '.' + name ;
+            }
+            else
+            {
+                expression = location + '.' + name + '.' + path[2] ;
+            }
             MVEL.setProperty(message, expression, object);
         } else {
             throw new ObjectMappingException(expression + " should start with one of [header,body,properties,attachment]");
@@ -260,4 +274,230 @@
             return object.toString().getBytes();
         }
     }
+    
+    /**
+     * Get the expression path from the expression.
+     * @param expression The expression to split up.
+     * @return The expression path.
+     * @throws ObjectMappingException for errors during parsing
+     * 
+     * The expression path returned by this method will be
+     * <code>
+     *   - [&lt;location&gt;]
+     *   - &lt;name&gt; 
+     *   - &lt;property path&gt;
+     * </code>
+     * <p/>
+     * The name can be fully qualified by wrapping it within single quote (') characters.
+     * 
+     * If the path evaluates to a single entry then it is assumed that this is the name of a property
+     * location in the body.  In this case the result of this method will be "body", &lt;name&gt;.
+     */
+    private String[] getExpressionPath(final String expression)
+        throws ObjectMappingException
+    {
+        if (expression != null)
+        {
+            final int length =  expression.length() ;
+            if (length > 0)
+            {
+                final ObjectMapperState state = new ObjectMapperState(expression) ;
+                skipWhitespace(state) ;
+                
+                if (state.getIndex() < length)
+                {
+                    final String first = getPathElement(state) ;
+                    if (state.getIndex() >= length)
+                    {
+                        return new String[] { "body", first} ;
+                    }
+                    
+                    final String second = getPathElement(state) ;
+                    final int index = state.getIndex() ;
+                    if (index >= length)
+                    {
+                        return new String[] { first, second } ;
+                    }
+                    else
+                    {
+                        return new String[] {first, second, expression.substring(index)} ;
+                    }
+                }
+            }
+        }
+        
+        return new String[0] ;
+    }
+    
+    /**
+     * Return the next path element from the expression.
+     * @param state The ObjectMapper state.
+     * @return The next expression path element.
+     * @throws ObjectMappingException for errors during parsing
+     */
+    private String getPathElement(final ObjectMapperState state)
+        throws ObjectMappingException
+    {
+        final String expression = state.getExpression() ;
+        final int length = expression.length() ;
+        final int startIndex = state.getIndex() ;
+        
+        if (expression.charAt(startIndex) == QUOTE)
+        {
+            state.setIndex(startIndex+1) ;
+            final String element = getElement(state, QUOTE, true) ;
+            final int index = state.getIndex() ;
+            
+            if ((index < length) && (expression.charAt(index) != EXPRESSION_SEPARATOR))
+            {
+                throw new ObjectMappingException("Quoted path element terminated at index: " + index + " before separator character reached: " + expression) ;
+            }
+            state.setIndex(index+1) ;
+            return element ;
+        }
+        else
+        {
+            return getElement(state, EXPRESSION_SEPARATOR, false) ;
+        }
+    }
+    
+    /**
+     * Get an element from the specified location.
+     * @param state The ObjectMapper state.
+     * @param endChar The character which ends the element.
+     * @param endCharPresent true if the endChar must be present.
+     * @return The element.
+     * @throws ObjectMappingException for errors during parsing
+     */
+    private String getElement(final ObjectMapperState state, final char endChar, final boolean endCharPresent)
+        throws ObjectMappingException
+    {
+        final String expression = state.getExpression() ;
+        final int length = expression.length() ;
+        int startIndex = state.getIndex() ;
+        int index = startIndex ;
+        
+        StringBuilder sb = null ;
+        
+        while(index < length)
+        {
+            final char current = expression.charAt(index) ;
+            if (current == ESCAPE)
+            {
+                final String currentExpression = expression.substring(startIndex, index) ;
+                if (sb == null)
+                {
+                    sb = new StringBuilder(currentExpression) ;
+                }
+                else
+                {
+                    sb.append(currentExpression) ;
+                }
+                index++ ;
+                if (index >= length)
+                {
+                    throw new ObjectMappingException("Unexpected end of expression reached while escaping: " + expression) ;
+                }
+                sb.append(expression.charAt(index)) ;
+                startIndex = index+1 ;
+                index = startIndex ;
+            }
+            else if (current == endChar)
+            {
+                break ;
+            }
+            else
+            {
+                index ++ ;
+            }
+        }
+        
+        final String remainder = expression.substring(startIndex, index) ;
+        final String result ;
+        if (sb == null)
+        {
+            result = remainder ;
+        }
+        else
+        {
+            sb.append(remainder) ;
+            result = sb.toString() ;
+        }
+        
+        if (endCharPresent && ((index >= length) || (endChar != expression.charAt(index))))
+        {
+            throw new ObjectMappingException("Expected element termination with character \"" + endChar + "\" at index: " + index + " of expression: " + expression) ;
+        }
+        state.setIndex(index+1) ;
+        return result ;
+    }
+    
+    /**
+     * Skip whitespace from the specified location.
+     * @param state The ObjectMapper state.
+     */
+    private void skipWhitespace(final ObjectMapperState state)
+    {
+        final String expression = state.getExpression() ;
+        final int length = expression.length() ;
+        int index = state.getIndex() ;
+        while((index < length) && Character.isWhitespace(expression.charAt(index)))
+        {
+            index++ ;
+        }
+        state.setIndex(index) ;
+    }
+    
+    /**
+     * Current object mapper state
+     * @author kevin
+     *
+     */
+    private static final class ObjectMapperState
+    {
+        /**
+         * Expression being parsed.
+         */
+        private final String expression ;
+        /**
+         * Current index.
+         */
+        private int index ;
+        
+        /**
+         * Construct the mapper state.
+         * @param expression The expression to parse.
+         */
+        public ObjectMapperState(final String expression)
+        {
+            this.expression = expression ;
+        }
+        
+        /**
+         * Get the expression being parsed.
+         * @return the expression.
+         */
+        public String getExpression()
+        {
+            return expression ;
+        }
+        
+        /**
+         * Set the current index.
+         * @param index The current index.
+         */
+        public void setIndex(final int index)
+        {
+            this.index = index ;
+        }
+        
+        /**
+         * Get the current index.
+         * @return The current index.
+         */
+        public int getIndex()
+        {
+            return index ;
+        }
+    }
 }

Modified: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/FromMessageMapperUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/FromMessageMapperUnitTest.java	2007-08-31 15:48:41 UTC (rev 14784)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/FromMessageMapperUnitTest.java	2007-08-31 15:52:17 UTC (rev 14785)
@@ -62,6 +62,8 @@
         
         variableList.add("header.call.to");
         variableList.add("header.call.from");
+        variableList.add("'header'.'call'.to");
+        variableList.add("'header'.'\\call'.from");
         List<Object> pojos=mapper.createObjectList(message, variableList);
         
         Object object1 = pojos.get(0);
@@ -70,6 +72,12 @@
         Object object2 = pojos.get(1);
         assertTrue(object2.equals(eprFrom));
         
+        final Object quotedObject1 = pojos.get(2);
+        assertEquals(eprTo, quotedObject1);
+        
+        final Object quotedObject2 = pojos.get(3);
+        assertEquals(eprFrom, quotedObject2);
+        
     }
     public void testProperty () throws ObjectMappingException {
         ObjectMapper mapper = new ObjectMapper();
@@ -78,6 +86,7 @@
         
         message.getProperties().setProperty("property1", "some object");
         variableList.add("properties.property1");
+        variableList.add("'properties'.'property\\1'");
         
         TestPojo testPojo1 = new TestPojo();
         testPojo1.setCount(1);
@@ -88,14 +97,21 @@
         testPojo1.setTestPojo(testPojo2);
         message.getProperties().setProperty("property2", testPojo1);
         variableList.add("properties.property2.testPojo");
+        variableList.add("'properties'.'property2'.testPojo");
         
         List<Object> pojos=mapper.createObjectList(message, variableList);
         
         Object pojo1 = pojos.get(0);
         assertTrue("some object".equals(pojo1));
         
-        Object pojo2 = pojos.get(1);
+        final Object quotedPojo1 = pojos.get(1);
+        assertEquals("some object", quotedPojo1) ;
+        
+        Object pojo2 = pojos.get(2);
         assertTrue(testPojo2.equals(pojo2));
+        
+        final Object quotedPojo2 = pojos.get(3);
+        assertEquals(testPojo2, quotedPojo2);
     }
     
     public void testProperty_flatten() throws ObjectMappingException {
@@ -118,6 +134,7 @@
         
         message.getProperties().setProperty("allThePojos", allPojos);
         variableList.add("properties.allThePojos");
+        variableList.add("'properties'.'allThePojos'");
         
         List<Object> pojos=mapper.createObjectList(message, variableList);
         
@@ -126,6 +143,12 @@
         
         Object pojo2 = pojos.get(1);
         assertTrue(testPojo2.equals(pojo2));
+        
+        final Object quotedPojo1 = pojos.get(2);
+        assertEquals(testPojo1, quotedPojo1) ;
+        
+        final Object quotedPojo2 = pojos.get(3);
+        assertEquals(testPojo2, quotedPojo2);
     }
     
     public void testAttachment_hashmap() throws ObjectMappingException {
@@ -135,6 +158,7 @@
         
         message.getAttachment().put("attachment1", "some object");
         variableList.add("attachment.attachment1");
+        variableList.add("'attachment'.'attachment1'");
         
         TestPojo testPojo1 = new TestPojo();
         testPojo1.setCount(1);
@@ -145,14 +169,21 @@
         testPojo1.setTestPojo(testPojo2);
         message.getAttachment().put("attachment2", testPojo1);
         variableList.add("attachment.attachment2.testPojo");
+        variableList.add("'attachment'.'attachment2'.testPojo");
         
         List<Object> pojos=mapper.createObjectList(message, variableList);
         
         Object pojo1 = pojos.get(0);
         assertTrue("some object".equals(pojo1));
         
-        Object pojo2 = pojos.get(1);
+        final Object quotedPojo1 = pojos.get(0);
+        assertEquals("some object", quotedPojo1);
+        
+        Object pojo2 = pojos.get(2);
         assertTrue(testPojo2.equals(pojo2));  
+        
+        final Object quotedPojo2 = pojos.get(3);
+        assertEquals(testPojo2, quotedPojo2);  
     }
     
     public void testAttachment_list() throws ObjectMappingException{
@@ -162,6 +193,7 @@
         
         message.getAttachment().addItem("some object");
         variableList.add("attachment.0");
+        variableList.add("'attachment'.'0'");
         
         TestPojo testPojo1 = new TestPojo();
         testPojo1.setCount(1);
@@ -172,14 +204,21 @@
         testPojo1.setTestPojo(testPojo2);
         message.getAttachment().addItem(testPojo1);
         variableList.add("attachment.1.testPojo");
+        variableList.add("'attachment'.'1'.testPojo");
         
         List<Object> pojos=mapper.createObjectList(message, variableList);
         
         Object pojo1 = pojos.get(0);
         assertTrue("some object".equals(pojo1));
         
-        Object pojo2 = pojos.get(1);
+        final Object quotedPojo1 = pojos.get(1);
+        assertEquals("some object", quotedPojo1);
+        
+        Object pojo2 = pojos.get(2);
         assertTrue(testPojo2.equals(pojo2));
+        
+        final Object quotedPojo2 = pojos.get(3);
+        assertEquals(testPojo2, quotedPojo2);
     }
     
     public void testBody() throws ObjectMappingException {
@@ -189,6 +228,7 @@
         
         message.getBody().add("body1", "some object");
         variableList.add("body.body1");
+        variableList.add("'body'.'body1'");
         
         TestPojo testPojo1 = new TestPojo();
         testPojo1.setCount(1);
@@ -199,22 +239,33 @@
         testPojo1.setTestPojo(testPojo2);
         message.getBody().add("body2", testPojo1);
         variableList.add("body.body2.testPojo");
+        variableList.add("'body'.'body2'.testPojo");
         
         TestPojo testPojo3 = new TestPojo();
         //if the location is not specified we assume it is the body
         message.getBody().add("pojo3", testPojo3);
         variableList.add("pojo3");
+        variableList.add("'pojo3'");
         
         List<Object> pojos=mapper.createObjectList(message, variableList);
         
         Object pojo1 = pojos.get(0);
         assertTrue("some object".equals(pojo1));
         
-        Object pojo2 = pojos.get(1);
+        final Object quotedPojo1 = pojos.get(1);
+        assertEquals("some object", quotedPojo1);
+        
+        Object pojo2 = pojos.get(2);
         assertTrue(testPojo2.equals(pojo2));  
         
-        Object pojo3 = pojos.get(2);
+        final Object quotedPojo2 = pojos.get(3);
+        assertEquals(testPojo2, quotedPojo2);  
+        
+        Object pojo3 = pojos.get(4);
         assertTrue(testPojo3.equals(pojo3));
+        
+        final Object quotedPojo3 = pojos.get(5);
+        assertEquals(testPojo3, quotedPojo3);
     }
  
 }

Modified: labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/ToMessageMapperUnitTest.java
===================================================================
--- labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/ToMessageMapperUnitTest.java	2007-08-31 15:48:41 UTC (rev 14784)
+++ labs/jbossesb/trunk/product/rosetta/tests/src/org/jboss/soa/esb/message/mapping/ToMessageMapperUnitTest.java	2007-08-31 15:52:17 UTC (rev 14785)
@@ -49,6 +49,13 @@
         
         assertEquals(message.getHeader().getCall().getTo(),toEpr);
         
+        final Message message2 = MessageFactory.getInstance().getMessage();
+        
+        final String expression2="'header'.'call'.to";
+        objectMapper.setObjectOnMessage(message2, expression2, toEpr);
+        
+        assertEquals(toEpr, message2.getHeader().getCall().getTo());
+        
     }
     
     public void testBody() throws ObjectMappingException
@@ -64,5 +71,13 @@
         objectMapper.setObjectOnMessage(message, expression, pojo1);
         
         assertEquals(message.getBody().get("pojo1Name"),pojo1);
+        
+        final Message message2 = MessageFactory.getInstance().getMessage();
+        
+        final String expression2="'body'.'pojo1Name'";
+        
+        objectMapper.setObjectOnMessage(message2, expression2, pojo1);
+        
+        assertEquals(message2.getBody().get("pojo1Name"),pojo1);
     }
 }




More information about the jboss-svn-commits mailing list