[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>
+ * - [<location>]
+ * - <name>
+ * - <property path>
+ * </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", <name>.
+ */
+ 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