diff --git a/webapp/src/freemarker/ext/dump/BaseDumpDirective.java b/webapp/src/freemarker/ext/dump/BaseDumpDirective.java index 0b7be7545..6bc27b250 100644 --- a/webapp/src/freemarker/ext/dump/BaseDumpDirective.java +++ b/webapp/src/freemarker/ext/dump/BaseDumpDirective.java @@ -7,6 +7,7 @@ import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,6 +18,7 @@ import org.apache.commons.logging.LogFactory; import freemarker.core.Environment; import freemarker.template.Template; import freemarker.template.TemplateBooleanModel; +import freemarker.template.TemplateCollectionModel; import freemarker.template.TemplateDateModel; import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; @@ -25,6 +27,7 @@ import freemarker.template.TemplateHashModelEx; import freemarker.template.TemplateMethodModel; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; +import freemarker.template.TemplateModelIterator; import freemarker.template.TemplateNumberModel; import freemarker.template.TemplateScalarModel; import freemarker.template.TemplateSequenceModel; @@ -91,6 +94,11 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { } else if (model instanceof TemplateSequenceModel){ map.putAll( getTemplateModelData( ( TemplateSequenceModel)model ) ); + } else if (model instanceof TemplateCollectionModel) { + map.putAll( getTemplateModelData( ( TemplateCollectionModel)model ) ); + + // Nodes and transforms not included here + } else { map.putAll( getTemplateModelData( (TemplateModel)model ) ); } @@ -146,6 +154,8 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { } private Map getTemplateModelData(TemplateHashModel model) throws TemplateModelException { + // The data model is a hash; when else do we get here? + log.debug("Dumping model " + model); Map map = new HashMap(); map.put("type", "Hash"); //map.put("value", model.getAsBoolean()); @@ -167,11 +177,33 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { private Map getTemplateModelData(TemplateHashModelEx model) throws TemplateModelException { Map map = new HashMap(); - map.put("type", "HashModelEx");; - //map.put("value", model.getAsDate()); + map.put("type", "HashEx"); + Map items = new HashMap(); + // keys() gets only values visible to template + TemplateCollectionModel keys = model.keys(); + TemplateModelIterator iModel = keys.iterator(); + while (iModel.hasNext()) { + String key = iModel.next().toString(); + TemplateModel value = model.get(key); + items.put(key, getData(value)); + } + map.put("value", items); return map; } - + + private Map getTemplateModelData(TemplateCollectionModel model) throws TemplateModelException { + Map map = new HashMap(); + map.put("type", "Collection"); + List> items = new ArrayList>(); + TemplateModelIterator iModel = model.iterator(); + while (iModel.hasNext()) { + TemplateModel m = iModel.next(); + items.add(getData(m)); + } + map.put("value", items); + return map; + } + private Map getTemplateModelData(TemplateMethodModel model, String varName) throws TemplateModelException { Map map = new HashMap(); map.put("type", "Method"); @@ -181,7 +213,7 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { private Map getTemplateModelData(TemplateDirectiveModel model, String varName) throws TemplateModelException { Map map = new HashMap(); - map.put("type", "Directive");; + map.put("type", "Directive"); map.put("help", getHelp(model, varName)); return map; } @@ -227,5 +259,5 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { out.write(sw.toString()); } - + } diff --git a/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java b/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java index 08189c540..c2a295e83 100644 --- a/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java +++ b/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java @@ -14,8 +14,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -24,7 +26,9 @@ import org.junit.Test; import freemarker.core.Environment; import freemarker.template.Configuration; +import freemarker.template.SimpleCollection; import freemarker.template.Template; +import freemarker.template.TemplateCollectionModel; import freemarker.template.TemplateDirectiveBody; import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; @@ -53,8 +57,9 @@ public class DumpDirectiveTest { public void dumpString() { String varName = "dog"; - String value = "Rover"; Map dataModel = new HashMap(); + + String value = "Rover"; dataModel.put(varName, value); Map expected = new HashMap(); @@ -68,9 +73,10 @@ public class DumpDirectiveTest { @Test public void dumpBoolean() { - String varName = "hasSiteAdminAccess"; - boolean value = true; + String varName = "isLoggedIn"; Map dataModel = new HashMap(); + + boolean value = true; dataModel.put(varName, value); Map expected = new HashMap(); @@ -85,8 +91,9 @@ public class DumpDirectiveTest { public void dumpNumber() { String varName = "tabCount"; - int value = 7; Map dataModel = new HashMap(); + + int value = 7; dataModel.put(varName, value); Map expected = new HashMap(); @@ -101,8 +108,9 @@ public class DumpDirectiveTest { public void dumpSimpleDate() { String varName = "now"; - Date now = new Date(); Map dataModel = new HashMap(); + + Date now = new Date(); dataModel.put(varName, now); Map expected = new HashMap(); @@ -118,8 +126,9 @@ public class DumpDirectiveTest { public void dumpDateTime() { String varName = "timestamp"; - Timestamp ts = new Timestamp(1302297332043L); Map dataModel = new HashMap(); + + Timestamp ts = new Timestamp(1302297332043L); dataModel.put(varName, ts); Map expected = new HashMap(); @@ -135,8 +144,9 @@ public class DumpDirectiveTest { public void dumpSqlDate() { String varName = "date"; - java.sql.Date date = new java.sql.Date(1302297332043L); Map dataModel = new HashMap(); + + java.sql.Date date = new java.sql.Date(1302297332043L); dataModel.put(varName, date); Map expected = new HashMap(); @@ -152,8 +162,9 @@ public class DumpDirectiveTest { public void dumpTime() { String varName = "time"; - Time time = new Time(1302297332043L); Map dataModel = new HashMap(); + + Time time = new Time(1302297332043L); dataModel.put(varName, time); Map expected = new HashMap(); @@ -171,8 +182,9 @@ public class DumpDirectiveTest { public void dumpHelplessMethod() { String varName = "square"; - TemplateMethodModel value = new HelplessMethod(); Map dataModel = new HashMap(); + + TemplateMethodModel value = new HelplessMethod(); dataModel.put(varName, value); Map expected = new HashMap(); @@ -187,8 +199,9 @@ public class DumpDirectiveTest { public void dumpHelpfulMethod() { String varName = "square"; - TemplateMethodModel value = new HelpfulMethod(); Map dataModel = new HashMap(); + + TemplateMethodModel value = new HelpfulMethod(); dataModel.put(varName, value); Map expected = new HashMap(); @@ -203,8 +216,9 @@ public class DumpDirectiveTest { public void dumpMethodWithBadHelp() { String varName = "square"; - TemplateMethodModel value = new MethodWithBadHelp(); Map dataModel = new HashMap(); + + TemplateMethodModel value = new MethodWithBadHelp(); dataModel.put(varName, value); Map expected = new HashMap(); @@ -219,8 +233,9 @@ public class DumpDirectiveTest { public void dumpHelplessDirective() { String varName = "dump"; - TemplateDirectiveModel value = new HelplessDirective(); Map dataModel = new HashMap(); + + TemplateDirectiveModel value = new HelplessDirective(); dataModel.put(varName, value); Map expected = new HashMap(); @@ -234,9 +249,10 @@ public class DumpDirectiveTest { @Test public void dumpHelpfulDirective() { - String varName = "dump"; - TemplateDirectiveModel value = new HelpfulDirective(); + String varName = "dump"; Map dataModel = new HashMap(); + + TemplateDirectiveModel value = new HelpfulDirective(); dataModel.put(varName, value); Map expected = new HashMap(); @@ -251,8 +267,9 @@ public class DumpDirectiveTest { public void dumpDirectiveWithBadHelp() { String varName = "dump"; - TemplateDirectiveModel value = new DirectiveWithBadHelp(); Map dataModel = new HashMap(); + + TemplateDirectiveModel value = new DirectiveWithBadHelp(); dataModel.put(varName, value); Map expected = new HashMap(); @@ -266,8 +283,9 @@ public class DumpDirectiveTest { @Test public void dumpStringList() { - String varName = "fruit"; + String varName = "fruit"; Map dataModel = new HashMap(); + List list = new ArrayList(); list.add("apples"); list.add("bananas"); @@ -277,36 +295,38 @@ public class DumpDirectiveTest { Map expected = new HashMap(); expected.put("name", varName); expected.put("type", "Sequence"); - List> listDump = new ArrayList>(); + List> dump = new ArrayList>(); for ( String str : list) { Map map = new HashMap(); map.put("type", "String"); map.put("value", str); - listDump.add(map); + dump.add(map); } - expected.put("value", listDump); + expected.put("value", dump); test(varName, dataModel, expected); } @Test public void dumpStringArray() { - String varName = "fruit"; + + String varName = "fruit"; Map dataModel = new HashMap(); + String[] list = { "apples", "bananas", "oranges" }; dataModel.put(varName, list); Map expected = new HashMap(); expected.put("name", varName); expected.put("type", "Sequence"); - List> listDump = new ArrayList>(); + List> dump = new ArrayList>(); for ( String str : list) { Map map = new HashMap(); map.put("type", "String"); map.put("value", str); - listDump.add(map); + dump.add(map); } - expected.put("value", listDump); + expected.put("value", dump); test(varName, dataModel, expected); } @@ -314,8 +334,9 @@ public class DumpDirectiveTest { @Test public void dumpMixedList() { - String varName = "stuff"; + String varName = "stuff"; Map dataModel = new HashMap(); + List list = new ArrayList(); list.add("apples"); list.add(4); @@ -332,40 +353,99 @@ public class DumpDirectiveTest { expected.put("name", varName); expected.put("type", "Sequence"); - List> listValue = new ArrayList>(); + List> dump = new ArrayList>(); Map stringMap = new HashMap(); stringMap.put("type", "String"); stringMap.put("value", "apples"); - listValue.add(stringMap); + dump.add(stringMap); Map numberMap = new HashMap(); numberMap.put("type", "Number"); numberMap.put("value", 4); - listValue.add(numberMap); + dump.add(numberMap); Map booleanMap = new HashMap(); booleanMap.put("type", "Boolean"); booleanMap.put("value", false); - listValue.add(booleanMap); + dump.add(booleanMap); Map sequenceMap = new HashMap(); sequenceMap.put("type", "Sequence"); - List> animalList = new ArrayList>(); + List> animalDump = new ArrayList>(); for ( String animal : animals ) { Map animalMap = new HashMap(); animalMap.put("type", "String"); animalMap.put("value", animal); - animalList.add(animalMap); + animalDump.add(animalMap); } - sequenceMap.put("value", animalList); - listValue.add(sequenceMap); + sequenceMap.put("value", animalDump); + dump.add(sequenceMap); - expected.put("value", listValue); + expected.put("value", dump); test(varName, dataModel, expected); } + @Test + public void dumpNumberSet() { + + 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); + } + } + dataModel.put(varName, odds); + + Map expected = new HashMap(); + expected.put("name", varName); + expected.put("type", "Sequence"); + List> dump = new ArrayList>(); + for ( int i : odds ) { + Map map = new HashMap(); + map.put("type", "Number"); + map.put("value", i); + dump.add(map); + } + expected.put("value", dump); + + test(varName, dataModel, expected); + } + + @Test + public void dumpNumberCollection() { + + 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 collection = new SimpleCollection(odds); + dataModel.put(varName, collection); + + Map expected = new HashMap(); + expected.put("name", varName); + expected.put("type", "Collection"); + List> dump = new ArrayList>(); + for ( int i : odds ) { + Map map = new HashMap(); + map.put("type", "Number"); + map.put("value", i); + dump.add(map); + } + expected.put("value", dump); + + test(varName, dataModel, expected); + } + @Test public void dumpHash() { @@ -373,11 +453,35 @@ public class DumpDirectiveTest { // RY Do these with different BeansWrappers @Test - public void dumpHashEx() { + public void dumpStringToStringMap() { + + String varName = "capitals"; + Map dataModel = new HashMap(); + Map capitals = new HashMap(); + capitals.put("Albany", "New York"); + capitals.put("St. Paul", "Minnesota"); + capitals.put("Austin", "Texas"); + capitals.put("Sacramento", "California"); + capitals.put("Richmond", "Virginia"); + dataModel.put(varName, capitals); + + Map expected = new HashMap(); + expected.put("name", varName); + expected.put("type", "HashEx"); + Map dump = new HashMap(); + for ( String key : capitals.keySet() ) { + Map capitalDump = new HashMap(); + capitalDump.put("type", "String"); + capitalDump.put("value", capitals.get(key)); + dump.put(key, capitalDump); + } + expected.put("value", dump); + + test(varName, dataModel, expected); } - /////////////////////////// Private helper classes and methods /////////////////////////// + /////////////////////////// Private stub classes and helper methods /////////////////////////// private void test(String varName, Map dataModel, Map expected) { try {