diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/CycleDetector.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/CycleDetector.java deleted file mode 100644 index 346bced406..0000000000 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/CycleDetector.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed 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.springframework.integration.transformer; - -import java.beans.PropertyDescriptor; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.CollectionUtils; - -/** - * @author Oleg Zhurakousky - * @since 2.0 - */ -class CycleDetector { - private final ExpressionParser parser = new SpelExpressionParser(); - private final String[] defaultIgnorePakages = new String[]{ - "com.apple", - "com.sun", - "java.awt", - "java", - "javax", - "org.jcp", - "org.omg", - "sun" - }; - private boolean ignoreClassAttribute = true; - private boolean ignoreDefaultPackages = true; - /** - * - * @param target - * @param ignorePakages - */ - public void detectCycle(Object target, String... ignorePakages){ - Map> objectReferenceMap = new HashMap>(); - this.doDetect(target, objectReferenceMap, ignorePakages); - } - /* - * - */ - private void doDetect(Object target, Map> objectReferenceMap, String[] ignorePakages){ - if (propertyInIgnoredPackage(target, ignorePakages)){ - return; - } - if (collectionMapOrArray(target)){ - Iterable iterable = null; - if (target instanceof Collection) { - iterable = (Iterable) target; - } else if (target instanceof Map){ - iterable = ((Map) target).values(); - } else if (target.getClass().isArray()){ - iterable = CollectionUtils.arrayToList(target); - } - for (Object value : iterable) { - this.doDetect(value, objectReferenceMap, ignorePakages); - } - } else { - if (!objectReferenceMap.containsKey(target)){ - objectReferenceMap.put(target, new HashSet()); - } - EvaluationContext context = new StandardEvaluationContext(target); - BeanWrapperImpl bw = new BeanWrapperImpl(target); - PropertyDescriptor[] descriptors = bw.getPropertyDescriptors(); - for (PropertyDescriptor propertyDescriptor : descriptors) { - String propertyName = propertyDescriptor.getName(); - if (propertyName.equals("class") && ignoreClassAttribute){ - continue; // no need to process - } - Expression expression = parser.parseExpression(propertyName); - Object propertyValue = null; - try { - propertyValue = expression.getValue(context); - } catch (Exception e) {/*nothing to do, might only happen when 'ignoreClassAttribute' is set to false ('true' by default)*/} - - if (propertyValue != null){ - if (!collectionMapOrArray(propertyValue)){ - Set references = objectReferenceMap.get(target); - if (!references.contains(propertyValue)){ - references.add(propertyValue); - } - if (objectReferenceMap.containsKey(propertyValue)){ - references = objectReferenceMap.get(propertyValue); - if (references.contains(target)){ - throw new MessageTransformationException("Cyclic reference detected between: " + - propertyValue.getClass().getSimpleName() + " - " + target.getClass().getSimpleName()); - } - } - } - this.doDetect(propertyValue, objectReferenceMap, ignorePakages); - } - } - } - } - /* - * - */ - private boolean collectionMapOrArray(Object elementValue){ - return (elementValue instanceof Map || - elementValue instanceof Collection || - elementValue.getClass().isArray()); - } - /* - * - */ - private boolean propertyInIgnoredPackage(Object elementValue, String[] ignorePakagess){ - if (this.collectionMapOrArray(elementValue)){ - return false; - } - for (String packagePattern : ignorePakagess) { - if (elementValue.getClass().getPackage().getName().startsWith(packagePattern)){ - return true; - } - } - if (ignoreDefaultPackages){ - for (String packagePattern : defaultIgnorePakages) { - if (elementValue.getClass().getPackage().getName().startsWith(packagePattern)){ - return true; - } - } - } - return false; - } - public boolean isIgnoreClassAttribute() { - return ignoreClassAttribute; - } - - public void setIgnoreClassAttribute(boolean ignoreClassAttribute) { - this.ignoreClassAttribute = ignoreClassAttribute; - } - - public boolean isIgnoreDefaultPackages() { - return ignoreDefaultPackages; - } - - public void setIgnoreDefaultPackages(boolean ignoreDefaultPackages) { - this.ignoreDefaultPackages = ignoreDefaultPackages; - } -} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToMapTransformer.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToMapTransformer.java index f7d640c37c..e35a8659f3 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToMapTransformer.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToMapTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,20 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.transformer; +import java.util.Collection; +import java.util.HashMap; import java.util.Map; +import org.codehaus.jackson.map.ObjectMapper; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + /** - * Will transform an object graph into a flat Map where keys are valid SpEL expressions - * and values are of java.lang.* type. This means that this transformer will recursively navigate - * through the Object graph until the value could be java.lang.* - * It supports Collections, Maps and Arrays which means it will flatten Object's attributes that are defined as such:
+ * Will transform an object graph into a Map. It supports a conventional Map (map of maps) where complex attributes are + * represented as Map values as well as a flat Map where keys document the path to the value. It supports Collections, + * Maps and Arrays which means that for flat maps it will flatten an Object's properties as such:
* * private Map> testMapInMapData;
* private List departments;
* private String[] akaNames;
- * private Map> mapWithListData;
* * The resulting Map structure will look similar to this:
* @@ -34,20 +39,69 @@ import java.util.Map; * departments[0]=HR
* person.lname=Case * + * By default it will transform to a flat Map. If you need to transform to a Map of Maps set the 'shouldFlattenKeys' + * property to 'false' via the {@link ObjectToMapTransformer#setShouldFlattenKeys(boolean)} method. + * * @author Oleg Zhurakousky * @since 2.0 */ public class ObjectToMapTransformer extends AbstractPayloadTransformer> { - /* - * (non-Javadoc) - * @see org.springframework.integration.transformer.AbstractPayloadTransformer#transformPayload(java.lang.Object) - */ + private volatile boolean shouldFlattenKeys = true; + + public void setShouldFlattenKeys(boolean shouldFlattenKeys) { + this.shouldFlattenKeys = shouldFlattenKeys; + } + + @SuppressWarnings("unchecked") protected Map transformPayload(Object payload) throws Exception { - CycleDetector cycleDetector = new CycleDetector(); - cycleDetector.detectCycle(payload); - ObjectToSpelMapBuilder builder = new ObjectToSpelMapBuilder(); - return builder.buildSpelMap(payload); + ObjectMapper mapper = new ObjectMapper(); + Map result = new ObjectMapper().readValue(mapper.writeValueAsString(payload), Map.class); + if (this.shouldFlattenKeys) { + result = this.flattenMap(result); + } + return result; + } + + private Map flattenMap(Map result){ + Map resultMap = new HashMap(); + this.doFlatten("", result, resultMap); + return resultMap; + } + + private void doFlatten(String propertyPrefix, Map inputMap, Map resultMap){ + if (StringUtils.hasText(propertyPrefix)) { + propertyPrefix = propertyPrefix + "."; + } + for (String key : inputMap.keySet()) { + Object value = inputMap.get(key); + this.doProcessElement(propertyPrefix + key, value, resultMap); + } + } + + private void doProcessCollection(String propertyPrefix, Collection list, Map resultMap) { + int counter = 0; + for (Object element : list) { + this.doProcessElement(propertyPrefix + "[" + counter + "]", element, resultMap); + counter ++; + } + } + + @SuppressWarnings("unchecked") + private void doProcessElement(String propertyPrefix, Object element, Map resultMap) { + if (element instanceof Map) { + this.doFlatten(propertyPrefix, (Map) element, resultMap); + } + else if (element instanceof Collection) { + this.doProcessCollection(propertyPrefix, (Collection) element, resultMap); + } + else if (element != null && element.getClass().isArray()) { + Collection collection = CollectionUtils.arrayToList(element); + this.doProcessCollection(propertyPrefix, collection, resultMap); + } + else { + resultMap.put(propertyPrefix, element); + } } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToSpelMapBuilder.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToSpelMapBuilder.java deleted file mode 100644 index 3800959ee6..0000000000 --- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/ObjectToSpelMapBuilder.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed 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.springframework.integration.transformer; - -import java.beans.PropertyDescriptor; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.BeanWrapperImpl; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.CollectionUtils; - -/** - * @author Oleg Zhurakousky - * @since 2.0 - */ -class ObjectToSpelMapBuilder { - - private final ExpressionParser parser = new SpelExpressionParser(); - - private boolean serializeTypeName; - - - public Map buildSpelMap(Object rootObject) { - Map propertiesMap = new HashMap(); - EvaluationContext context = new StandardEvaluationContext(rootObject); - this.buildProperties(context, "", propertiesMap, rootObject); - return propertiesMap; - } - - private void buildProperties(EvaluationContext context, String parentPropertyPath, Map propertiesMap, Object object) { - BeanWrapperImpl bw = new BeanWrapperImpl(object); - PropertyDescriptor[] descriptors = bw.getPropertyDescriptors(); - for (PropertyDescriptor propertyDescriptor : descriptors) { - Class propertyType = propertyDescriptor.getPropertyType(); - String propertyName = propertyDescriptor.getName(); - String propertyPath = parentPropertyPath + propertyName; - if (propertyType.isArray() || Collection.class.isAssignableFrom(propertyType)) { - this.processArray(context, propertyPath, propertyName, propertyType, propertiesMap); - } - else if (propertyType.isAnonymousClass()) { - throw new IllegalArgumentException("anonymous class property transformation is not supported"); - } - else if (propertyType.isAssignableFrom(Map.class)) { - Expression expression = parser.parseExpression(propertyPath); - Map map = (Map) expression.getValue(context); - if (map != null) { - this.processMap(context, propertiesMap, map, parentPropertyPath, propertyName); - } - } - else { - Expression expression = parser.parseExpression(propertyPath); - Object propertyValue = expression.getValue(context); - if (propertyValue != null) { - this.processElementValue(context, propertyValue, propertyName, propertyPath, propertiesMap); - } - } - } - } - - private void processMap(EvaluationContext context, Map mappedProperties, Map mapToTransform, String propertyPath, String propertyName) { - Iterator mapIter = mapToTransform.keySet().iterator(); - while (mapIter.hasNext()) { - Object keyElement = mapIter.next(); - Object elementValue = mapToTransform.get(keyElement); - String mapPropertyPath = propertyPath + propertyName + "['" + keyElement.toString() + "']"; - if (elementValue.getClass().isArray() || elementValue instanceof Collection) { - this.processArray(context, mapPropertyPath, "", elementValue.getClass(), mappedProperties); - } - else if (elementValue instanceof Map) { - this.processMap(context, mappedProperties, (Map) elementValue, mapPropertyPath, ""); - } - else { - this.processElementValue(context, elementValue, propertyName, mapPropertyPath, mappedProperties); - } - } - } - - private void processArray(EvaluationContext context, String propertyPath, String propertyName, Class elementType, Map propertiesMap) { - Expression arrayExp = parser.parseExpression(propertyPath); - Object array = arrayExp.getValue(context); - List arrayElements = null; - if (elementType.isArray()) { - arrayElements = CollectionUtils.arrayToList(array); - } - else { - arrayElements = (List) array; - } - - int i = 0; - for (Object arrayElement : arrayElements) { - String arrayPropertyPath = propertyPath + "[" + i++ + "]"; - if (arrayElement instanceof Map) { - // last argument is empty because it is not a named property, but an array element - this.processMap(context, propertiesMap, (Map) arrayElement, arrayPropertyPath, ""); - } - else if (arrayElement.getClass().isArray()){ - this.processArray(context, arrayPropertyPath, propertyName, elementType, propertiesMap); - } - else { - this.processElementValue(context, arrayElement, propertyName, arrayPropertyPath, propertiesMap); - } - } - } - - private void processElementValue(EvaluationContext context, Object elementValue, String propertyName, String propertyPath, Map propertiesMap) { - // JDK packages considered shared, thus serializable - if (elementValue.getClass().getPackage().getName().startsWith("java.lang")) { - if (propertyName.equals("class") && !this.serializeTypeName) { - return; - } - else { - propertiesMap.put(propertyPath, elementValue); - } - } - else { - this.buildProperties(context, propertyPath + ".", propertiesMap, elementValue); - } - } - -} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/CycleDetectorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/CycleDetectorTests.java deleted file mode 100644 index f36be852ca..0000000000 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/CycleDetectorTests.java +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2002-2010 the original author or authors. - * - * Licensed 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.springframework.integration.transformer; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -/** - * @author Oleg Zhurakousky - * - */ -public class CycleDetectorTests { - @Test - public void testWithNoIgnoredPackages(){ - Parent parent = this.prepare(false); - CycleDetector builder = new CycleDetector(); - builder.setIgnoreDefaultPackages(false); - builder.detectCycle(parent); - // should not throw an exception - } - @Test - public void testWithNoIgnoredPackagesAndClassProperty(){ - Parent parent = this.prepare(false); - CycleDetector builder = new CycleDetector(); - builder.setIgnoreDefaultPackages(false); - builder.setIgnoreClassAttribute(false); - builder.detectCycle(parent); - // should not throw an exception - } - @Test - public void testWithAditionalIgnoredPackages(){ - Parent parent = this.prepare(true); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent, "org.springframework.integration.transformer"); - // should not throw an exception, however if you remove additional package from - // the above method there is a cycle in the domain core - } - - @Test - public void testObjectReferenceMapWithoutCycle(){ - Parent parent = this.prepare(false); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent); - // should not throw an exception - } - - @Test(expected=MessageTransformationException.class) - public void testObjectReferenceMapWithCycle(){ - Parent parent = this.prepare(true); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent); - } - @Test - public void testWithNoCyclesInArray(){ - Parent parent = this.prepare(false); - Foo[] foos = new Foo[]{new Foo(), new Foo()}; - parent.getAddress().setFoos(foos); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent); - } - @Test(expected=MessageTransformationException.class) - public void testWithCyclesInArray(){ - Parent parent = this.prepare(false); - Foo foo = new Foo(); - Bar bar = new Bar(); - foo.setBar(bar); - bar.setFoo(foo); - Foo[] foos = new Foo[]{foo, new Foo()}; - parent.getAddress().setFoos(foos); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent); - } - @Test - public void testWithNoCyclesInMapWithList(){ - Parent parent = this.prepare(false); - Foo fooA = new Foo(); - Foo fooB = new Foo(); - Foo[] foos = new Foo[]{fooA, fooB}; - parent.getAddress().setFoos(foos); - List fooList = new ArrayList(); - fooList.add(fooA); - fooList.add(fooB); - Map> mapOfFoos = new HashMap>(); - mapOfFoos.put("listOfFoos", fooList); - parent.getChild().setMapOfFoos(mapOfFoos); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent); - } - @Test(expected=MessageTransformationException.class) - public void testWithCyclesInMapWithList(){ - Parent parent = this.prepare(false); - Foo fooA = new Foo(); - Bar bar = new Bar(); - bar.setFoo(fooA); - fooA.setBar(bar); - Foo fooB = new Foo(); - Foo[] foos = new Foo[]{new Foo(), new Foo()}; - parent.getAddress().setFoos(foos); - List fooList = new ArrayList(); - fooList.add(fooA); - fooList.add(fooB); - Map> mapOfFoos = new HashMap>(); - mapOfFoos.put("listOfFoos", fooList); - parent.getChild().setMapOfFoos(mapOfFoos); - CycleDetector builder = new CycleDetector(); - builder.detectCycle(parent); - } - - //################# Test Classes ################### - public Parent prepare(boolean cycle){ - Parent parent = new Parent(); - Child child = new Child(); - Address address = new Address(); - address.setStreet("123 Main st"); - child.setAddress(address); - List nickNames = new ArrayList(); - nickNames.add("spanky"); - nickNames.add("goofy"); - child.setNickNames(nickNames); - child.setName("Seva"); - if (cycle){ - child.setParent(parent); - } - - parent.setAddress(address); - parent.setChild(child); - parent.setName("Oleg"); - return parent; - } - /* - * - */ - public static class Parent{ - private Address address; - private Child child; - private String name; - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - public Address getAddress() { - return address; - } - public void setAddress(Address address) { - this.address = address; - } - public Child getChild() { - return child; - } - public void setChild(Child child) { - this.child = child; - } - } - /* - * - */ - public static class Child{ - private String name; - private List nickNames; - private Map> mapOfFoos; - private Address address; - private Parent parent; - public Parent getParent() { - return parent; - } - - public void setParent(Parent parent) { - this.parent = parent; - } - - public List getNickNames() { - return nickNames; - } - - public void setNickNames(List nickNames) { - this.nickNames = nickNames; - } - - public Address getAddress() { - return address; - } - - public void setAddress(Address address) { - this.address = address; - } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - public Map> getMapOfFoos() { - return mapOfFoos; - } - - public void setMapOfFoos(Map> mapOfFoos) { - this.mapOfFoos = mapOfFoos; - } - } - /* - * - */ - public static class Address{ - private String street; - private Foo[] foos; - - public Foo[] getFoos() { - return foos; - } - - public void setFoos(Foo[] foos) { - this.foos = foos; - } - - public String getStreet() { - return street; - } - - public void setStreet(String street) { - this.street = street; - } - } - - public static class Foo{ - private Bar bar; - - public Bar getBar() { - return bar; - } - - public void setBar(Bar bar) { - this.bar = bar; - } - } - public static class Bar{ - private Foo foo; - - public Foo getFoo() { - return foo; - } - - public void setFoo(Foo foo) { - this.foo = foo; - } - } -} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToMapTransformerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToMapTransformerTests.java index 725cf74520..21013a808d 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToMapTransformerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/ObjectToMapTransformerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,19 @@ */ package org.springframework.integration.transformer; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertTrue; - +import java.io.IOException; +import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.JsonParseException; +import org.codehaus.jackson.map.JsonMappingException; import org.junit.Test; -import org.springframework.expression.EvaluationContext; +import org.springframework.context.expression.MapAccessor; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -33,6 +35,11 @@ import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.integration.Message; import org.springframework.integration.support.MessageBuilder; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; + +import static org.junit.Assert.assertNull; + /** * * @author Oleg Zhurakousky @@ -41,27 +48,101 @@ import org.springframework.integration.support.MessageBuilder; public class ObjectToMapTransformerTests { @SuppressWarnings("unchecked") @Test - public void testObjectToSpelMapTransformer(){ + public void testObjectToSpelMapTransformer() throws JsonParseException, JsonMappingException, JsonGenerationException, IOException{ Employee employee = this.buildEmployee(); - EvaluationContext context = new StandardEvaluationContext(employee); + StandardEvaluationContext context = new StandardEvaluationContext(); + context.addPropertyAccessor(new MapAccessor()); ExpressionParser parser = new SpelExpressionParser(); ObjectToMapTransformer transformer = new ObjectToMapTransformer(); Message message = MessageBuilder.withPayload(employee).build(); + Message transformedMessage = transformer.transform(message); Map transformedMap = (Map) transformedMessage.getPayload(); - + System.out.println(transformedMap); assertNotNull(transformedMap); - for (String key : transformedMap.keySet()) { - Expression expression = parser.parseExpression(key); - //System.out.println("Testing: " + key); - Object valueFromTheMap = transformedMap.get(key); - Object valueFromExpression = expression.getValue(context); - String packageNameOfValueType = valueFromTheMap.getClass().getPackage().getName(); - assertTrue(packageNameOfValueType.startsWith("java.lang")); - assertEquals(valueFromTheMap, valueFromExpression); - } + + Object valueFromTheMap = null; + Object valueFromExpression = null; + Expression expression = null; + + expression = parser.parseExpression("departments[0]"); + valueFromTheMap = transformedMap.get("departments[0]"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.address.coordinates"); + valueFromTheMap = transformedMap.get("person.address.coordinates"); + valueFromExpression = expression.getValue(context, employee, Map.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.akaNames[0]"); + valueFromTheMap = transformedMap.get("person.akaNames[0]"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("testMapInMapData.internalMapA.bar"); + valueFromTheMap = transformedMap.get("testMapInMapData.internalMapA.bar"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("companyAddress.street"); + valueFromTheMap = transformedMap.get("companyAddress.street"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.lname"); + valueFromTheMap = transformedMap.get("person.lname"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.address.mapWithListData.mapWithListTestData[1]"); + valueFromTheMap = transformedMap.get("person.address.mapWithListData.mapWithListTestData[1]"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("companyAddress.city"); + valueFromTheMap = transformedMap.get("companyAddress.city"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.akaNames[2]"); + valueFromTheMap = transformedMap.get("person.akaNames[2]"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.child"); + valueFromTheMap = transformedMap.get("person.child"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertNull(valueFromTheMap); + assertNull(valueFromExpression); + + expression = parser.parseExpression("testMapInMapData.internalMapA.foo"); + valueFromTheMap = transformedMap.get("testMapInMapData.internalMapA.foo"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.address.city"); + valueFromTheMap = transformedMap.get("person.address.city"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("companyAddress.coordinates.latitude[0]"); + valueFromTheMap = transformedMap.get("companyAddress.coordinates.latitude[0]"); + valueFromExpression = expression.getValue(context, employee, Integer.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("person.remarks[1].baz"); + valueFromTheMap = transformedMap.get("person.remarks[1].baz"); + valueFromExpression = expression.getValue(context, employee, String.class); + assertEquals(valueFromTheMap, valueFromExpression); + + expression = parser.parseExpression("listOfDates[0][1]"); + valueFromTheMap = new Date((Long) transformedMap.get("listOfDates[0][1]")); + valueFromExpression = expression.getValue(context, employee, Date.class); + assertEquals(valueFromTheMap, valueFromExpression); } + @Test(expected=MessageTransformationException.class) public void testObjectToSpelMapTransformerWithCycle(){ Employee employee = this.buildEmployee(); @@ -86,9 +167,22 @@ public class ObjectToMapTransformerTests { coordinates.put("longitude", new Long[]{(long)156}); companyAddress.setCoordinates(coordinates); + List datesA = new ArrayList(); + datesA.add(new Date(System.currentTimeMillis() + 10000)); + datesA.add(new Date(System.currentTimeMillis() + 20000)); + + List datesB = new ArrayList(); + datesB.add(new Date(System.currentTimeMillis() + 30000)); + datesB.add(new Date(System.currentTimeMillis() + 40000)); + + List> listOfDates = new ArrayList>(); + listOfDates.add(datesA); + listOfDates.add(datesB); + Employee employee = new Employee(); employee.setCompanyName("ABC Inc."); employee.setCompanyAddress(companyAddress); + employee.setListOfDates(listOfDates); ArrayList departments = new ArrayList(); departments.add("HR"); departments.add("IT"); @@ -98,6 +192,8 @@ public class ObjectToMapTransformerTests { person.setFname("Justin"); person.setLname("Case"); person.setAkaNames("Hard", "Use", "Beer"); + person.setBirthDate(new Date()); + person.setAge(new BigDecimal(10)); Address personAddress = new Address(); personAddress.setCity("Philly"); personAddress.setStreet("123 Main"); @@ -137,10 +233,17 @@ public class ObjectToMapTransformerTests { public static class Employee{ private List departments; + private List> listOfDates; private String companyName; private Person person; private Address companyAddress; private Map> testMapInMapData; + public List> getListOfDates() { + return listOfDates; + } + public void setListOfDates(List> listOfDates) { + this.listOfDates = listOfDates; + } public Map> getTestMapInMapData() { return testMapInMapData; } @@ -180,6 +283,24 @@ public class ObjectToMapTransformerTests { private String[] akaNames; private List> remarks; private Child child; + private BigDecimal age; + public BigDecimal getAge() { + return age; + } + + public void setAge(BigDecimal age) { + this.age = age; + } + + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + private Date birthDate; public Child getChild() { return child; }