diff --git a/webapp/src/freemarker/ext/dump/BaseDumpDirective.java b/webapp/src/freemarker/ext/dump/BaseDumpDirective.java index 9191900bd..1a8d9ce80 100644 --- a/webapp/src/freemarker/ext/dump/BaseDumpDirective.java +++ b/webapp/src/freemarker/ext/dump/BaseDumpDirective.java @@ -23,6 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import freemarker.core.Environment; +import freemarker.ext.beans.CollectionModel; import freemarker.ext.beans.StringModel; import freemarker.template.Template; import freemarker.template.TemplateBooleanModel; @@ -169,7 +170,11 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { if (model != null) { if ( model instanceof TemplateSequenceModel ) { - map.putAll( getTemplateModelDump( ( TemplateSequenceModel)model ) ); + if (model instanceof CollectionModel && ! ((CollectionModel)model).getSupportsIndexedAccess()) { + map.putAll( getTemplateModelDump( ( TemplateCollectionModel)model ) ); + } else { + map.putAll( getTemplateModelDump( ( TemplateSequenceModel)model ) ); + } } else if ( model instanceof TemplateNumberModel ) { map.putAll( getTemplateModelDump( (TemplateNumberModel)model ) ); diff --git a/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java b/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java index 61a866910..7791d91ad 100644 --- a/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java +++ b/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java @@ -28,12 +28,14 @@ import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Test; +import freemarker.core.CollectionAndSequence; import freemarker.core.Environment; import freemarker.ext.beans.BeansWrapper; +import freemarker.ext.beans.CollectionModel; import freemarker.ext.dump.BaseDumpDirective.DateType; import freemarker.ext.dump.BaseDumpDirective.Key; -import freemarker.ext.dump.BaseDumpDirective.Value; import freemarker.ext.dump.BaseDumpDirective.Type; +import freemarker.ext.dump.BaseDumpDirective.Value; import freemarker.template.Configuration; import freemarker.template.SimpleCollection; import freemarker.template.Template; @@ -445,14 +447,14 @@ public class DumpDirectiveTest { Map expectedDumpValue = new HashMap(); expectedDumpValue.put(Key.TYPE.toString(), Type.SEQUENCE); - List> myArrayexpectedDumpValue = new ArrayList>(myArray.length); + List> myArrayExpectedDumpValue = new ArrayList>(myArray.length); for ( String str : myArray) { Map itemDump = new HashMap(); itemDump.put(Key.TYPE.toString(), Type.STRING); itemDump.put(Key.VALUE.toString(), str); - myArrayexpectedDumpValue.add(itemDump); + myArrayExpectedDumpValue.add(itemDump); } - expectedDumpValue.put(Key.VALUE.toString(), myArrayexpectedDumpValue); + expectedDumpValue.put(Key.VALUE.toString(), myArrayExpectedDumpValue); Map expectedDump = new HashMap(); expectedDump.put(varName, expectedDumpValue); @@ -488,36 +490,36 @@ public class DumpDirectiveTest { Map expectedDumpValue = new HashMap(); expectedDumpValue.put(Key.TYPE.toString(), Type.SEQUENCE); - List> mixedListexpectedDumpValue = new ArrayList>(mixedList.size()); + List> mixedListExpectedDumpValue = new ArrayList>(mixedList.size()); - Map myStringexpectedDumpValue = new HashMap(); - myStringexpectedDumpValue.put(Key.TYPE.toString(), Type.STRING); - myStringexpectedDumpValue.put(Key.VALUE.toString(), myString); - mixedListexpectedDumpValue.add(myStringexpectedDumpValue); + Map myStringExpectedDumpValue = new HashMap(); + myStringExpectedDumpValue.put(Key.TYPE.toString(), Type.STRING); + myStringExpectedDumpValue.put(Key.VALUE.toString(), myString); + mixedListExpectedDumpValue.add(myStringExpectedDumpValue); - Map myIntexpectedDumpValue = new HashMap(); - myIntexpectedDumpValue.put(Key.TYPE.toString(), Type.NUMBER); - myIntexpectedDumpValue.put(Key.VALUE.toString(), myInt); - mixedListexpectedDumpValue.add(myIntexpectedDumpValue); + Map myIntExpectedDumpValue = new HashMap(); + myIntExpectedDumpValue.put(Key.TYPE.toString(), Type.NUMBER); + myIntExpectedDumpValue.put(Key.VALUE.toString(), myInt); + mixedListExpectedDumpValue.add(myIntExpectedDumpValue); - Map myBoolexpectedDumpValue = new HashMap(); - myBoolexpectedDumpValue.put(Key.TYPE.toString(), Type.BOOLEAN); - myBoolexpectedDumpValue.put(Key.VALUE.toString(), myBool); - mixedListexpectedDumpValue.add(myBoolexpectedDumpValue); + Map myBoolExpectedDumpValue = new HashMap(); + myBoolExpectedDumpValue.put(Key.TYPE.toString(), Type.BOOLEAN); + myBoolExpectedDumpValue.put(Key.VALUE.toString(), myBool); + mixedListExpectedDumpValue.add(myBoolExpectedDumpValue); - Map myListexpectedDumpValue = new HashMap(); - myListexpectedDumpValue.put(Key.TYPE.toString(), Type.SEQUENCE); - List> myListItemsexpectedDumpValue = new ArrayList>(myList.size()); + Map myListExpectedDumpValue = new HashMap(); + myListExpectedDumpValue.put(Key.TYPE.toString(), Type.SEQUENCE); + List> myListItemsExpectedDumpValue = new ArrayList>(myList.size()); for ( String animal : myList ) { Map itemDump = new HashMap(); itemDump.put(Key.TYPE.toString(), Type.STRING); itemDump.put(Key.VALUE.toString(), animal); - myListItemsexpectedDumpValue.add(itemDump); + myListItemsExpectedDumpValue.add(itemDump); } - myListexpectedDumpValue.put(Key.VALUE.toString(), myListItemsexpectedDumpValue); - mixedListexpectedDumpValue.add(myListexpectedDumpValue); + myListExpectedDumpValue.put(Key.VALUE.toString(), myListItemsExpectedDumpValue); + mixedListExpectedDumpValue.add(myListExpectedDumpValue); - expectedDumpValue.put(Key.VALUE.toString(), mixedListexpectedDumpValue); + expectedDumpValue.put(Key.VALUE.toString(), mixedListExpectedDumpValue); Map expectedDump = new HashMap(); expectedDump.put(varName, expectedDumpValue); @@ -541,14 +543,14 @@ public class DumpDirectiveTest { Map expectedDumpValue = new HashMap(); expectedDumpValue.put(Key.TYPE.toString(), Type.SEQUENCE); - List> myIntSetexpectedDumpValue = new ArrayList>(myIntSet.size()); + List> myIntSetExpectedDumpValue = new ArrayList>(myIntSet.size()); for ( int i : myIntSet ) { Map itemDump = new HashMap(); itemDump.put(Key.TYPE.toString(), Type.NUMBER); itemDump.put(Key.VALUE.toString(), i); - myIntSetexpectedDumpValue.add(itemDump); + myIntSetExpectedDumpValue.add(itemDump); } - expectedDumpValue.put(Key.VALUE.toString(), myIntSetexpectedDumpValue); + expectedDumpValue.put(Key.VALUE.toString(), myIntSetExpectedDumpValue); Map expectedDump = new HashMap(); expectedDump.put(varName, expectedDumpValue); @@ -557,7 +559,7 @@ public class DumpDirectiveTest { } @Test - public void dumpNumberCollection() { + public void dumpSimpleCollection() { String varName = "oddNums"; Map dataModel = new HashMap(); @@ -573,20 +575,85 @@ public class DumpDirectiveTest { Map expectedDumpValue = new HashMap(); expectedDumpValue.put(Key.TYPE.toString(), Type.COLLECTION); - List> myCollectionexpectedDumpValue = new ArrayList>(odds.size()); + List> myCollectionExpectedDumpValue = new ArrayList>(odds.size()); for ( int i : odds ) { Map itemDump = new HashMap(); itemDump.put(Key.TYPE.toString(), Type.NUMBER); itemDump.put(Key.VALUE.toString(), i); - myCollectionexpectedDumpValue.add(itemDump); + myCollectionExpectedDumpValue.add(itemDump); } - expectedDumpValue.put(Key.VALUE.toString(), myCollectionexpectedDumpValue); + expectedDumpValue.put(Key.VALUE.toString(), myCollectionExpectedDumpValue); Map expectedDump = new HashMap(); expectedDump.put(varName, expectedDumpValue); test(varName, dataModel, expectedDump); } + + @Test + public void dumpCollectionModel() { + + String varName = "oddNums"; + Map dataModel = new HashMap(); + + Set odds = new HashSet(); + for (int i=0; i <= 10; i++) { + if (i % 2 == 1) { + odds.add(i); + } + } + TemplateCollectionModel myCollection = new CollectionModel(odds, new BeansWrapper()); + dataModel.put(varName, myCollection); + + Map expectedDumpValue = new HashMap(); + expectedDumpValue.put(Key.TYPE.toString(), Type.COLLECTION); + List> myCollectionExpectedDumpValue = new ArrayList>(odds.size()); + for ( int i : odds ) { + Map itemDump = new HashMap(); + itemDump.put(Key.TYPE.toString(), Type.NUMBER); + itemDump.put(Key.VALUE.toString(), i); + myCollectionExpectedDumpValue.add(itemDump); + } + expectedDumpValue.put(Key.VALUE.toString(), myCollectionExpectedDumpValue); + + Map expectedDump = new HashMap(); + expectedDump.put(varName, expectedDumpValue); + + test(varName, dataModel, expectedDump); + } + + @Test + public void dumpCollectionAndSequenceModel() { + + String varName = "oddNums"; + Map dataModel = new HashMap(); + + Set odds = new HashSet(); + for (int i=0; i <= 10; i++) { + if (i % 2 == 1) { + odds.add(i); + } + } + TemplateCollectionModel coll = new CollectionModel(odds, new BeansWrapper()); + TemplateCollectionModel myCollection = new CollectionAndSequence(coll); + dataModel.put(varName, myCollection); + + Map expectedDumpValue = new HashMap(); + expectedDumpValue.put(Key.TYPE.toString(), Type.SEQUENCE); + List> myCollectionExpectedDumpValue = new ArrayList>(odds.size()); + for ( int i : odds ) { + Map itemDump = new HashMap(); + itemDump.put(Key.TYPE.toString(), Type.NUMBER); + itemDump.put(Key.VALUE.toString(), i); + myCollectionExpectedDumpValue.add(itemDump); + } + expectedDumpValue.put(Key.VALUE.toString(), myCollectionExpectedDumpValue); + + Map expectedDump = new HashMap(); + expectedDump.put(varName, expectedDumpValue); + + test(varName, dataModel, expectedDump); + } @Test public void dumpHash() {