diff --git a/webapp/src/freemarker/ext/dump/BaseDumpDirective.java b/webapp/src/freemarker/ext/dump/BaseDumpDirective.java index 7c71a16eb..0bda58c7a 100644 --- a/webapp/src/freemarker/ext/dump/BaseDumpDirective.java +++ b/webapp/src/freemarker/ext/dump/BaseDumpDirective.java @@ -137,16 +137,23 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { // Don't return null if model == null. We still want to send the map to the template. if (model != null) { - // Do TemplateHashModel cases first, because models of some Java objects are - // StringModels, and so are both TemplateScalarModels and TemplateHashModelExs. - if (model instanceof TemplateHashModelEx) { - map.putAll( getTemplateModelData( ( TemplateHashModelEx)model ) ); - - } else if (model instanceof TemplateHashModel) { - map.putAll( getTemplateModelData( ( TemplateHashModel)model ) ); - - } else if (model instanceof TemplateScalarModel) { - map.putAll( getTemplateModelData( (TemplateScalarModel)model ) ); + // NumberModel is both TemplateNumberModel and TemplateHashModelEx. Similarly for + // BooleanModel, DateModel, etc. These are the types used for property values obtained + // via getObjectData(). So the TemplateHashModelEx case has to follow TemplateNumberModel, + // etc. + if (model instanceof TemplateScalarModel) { + if (! (model instanceof TemplateHashModelEx)) { + map.putAll( getTemplateModelData( (TemplateScalarModel)model ) ); + } else { + Object unwrappedModel = DeepUnwrap.permissiveUnwrap(model); + // StringModel can wrap either a String or a complex Java object. We have to + // unwrap the model to find out which it is. + if (unwrappedModel instanceof String) { + map.putAll( getTemplateModelData( (TemplateScalarModel)model ) ); + } else { + map.putAll( getTemplateModelData( ( TemplateHashModelEx)model ) ); + } + } } else if (model instanceof TemplateBooleanModel) { map.putAll( getTemplateModelData( (TemplateBooleanModel)model ) ); @@ -162,16 +169,24 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel { } else if (model instanceof TemplateCollectionModel) { map.putAll( getTemplateModelData( ( TemplateCollectionModel)model ) ); - - // Nodes and transforms not included here + + } else if (model instanceof TemplateHashModelEx) { + map.putAll( getTemplateModelData( ( TemplateHashModelEx)model ) ); + + } else if (model instanceof TemplateHashModel) { + map.putAll( getTemplateModelData( ( TemplateHashModel)model ) ); + + // Nodes and transforms not included here } else { map.putAll( getTemplateModelData( (TemplateModel)model ) ); } + } else { + map.put(Key.VALUE.toString(), "null"); } return map; - } + } private Map getTemplateModelData(TemplateScalarModel model) throws TemplateModelException { Map map = new HashMap(); diff --git a/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java b/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java index 491e23c80..574817f95 100644 --- a/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java +++ b/webapp/test/freemarker/ext/dump/DumpDirectiveTest.java @@ -12,7 +12,6 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Calendar; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -139,6 +138,25 @@ public class DumpDirectiveTest { test(varName, dataModel, expectedDump); } + @Test + public void dumpCalendarDate() { + + String varName = "myDate"; + Map dataModel = new HashMap(); + + Calendar c = Calendar.getInstance(); + c.set(91, Calendar.MAY, 5); + Date myDate = c.getTime(); + dataModel.put("myDate", myDate); + + Map expectedDump = new HashMap(); + expectedDump.put(Key.NAME.toString(), varName); + expectedDump.put(Key.TYPE.toString(), Type.DATE); + expectedDump.put(Key.DATE_TYPE.toString(), DateType.UNKNOWN); + expectedDump.put(Key.VALUE.toString(), myDate); + + test(varName, dataModel, expectedDump); + } @Test public void dumpDateTime() { @@ -652,27 +670,19 @@ public class DumpDirectiveTest { expectedDump.put(Key.NAME.toString(), varName); expectedDump.put(Key.TYPE.toString(), "freemarker.ext.dump.DumpDirectiveTest$Employee"); - SortedMap properties = new TreeMap(); - Calendar c = Calendar.getInstance(); - c.set(75, Calendar.MAY, 5); - properties.put("birthdate", c.getTime()); - properties.put("fullName", "John Doe"); - properties.put("id", 34523); - properties.put("nickname", ""); - properties.put("supervisees", ""); - properties.put("supervisor", ""); + SortedMap propertiesExpectedDump = getPropertiesExpectedDump(); - expectedDump.put(Key.VALUE.toString(), properties); + expectedDump.put(Key.VALUE.toString(), propertiesExpectedDump); - //Map dump = getDump(varName, dataModel); - //assertEquals(expectedDump, dump); + Map dump = getDump(varName, dataModel); + assertEquals(expectedDump, dump); // Test the sorting of the methods -// List expectedKeys = new ArrayList(properties.keySet()); -// @SuppressWarnings("unchecked") -// Map methodsActualDump = (Map) dump.get(Key.VALUE.toString()); -// List actualKeys = new ArrayList(methodsActualDump.keySet()); - //assertEquals(expectedKeys, actualKeys); + List expectedKeys = new ArrayList(propertiesExpectedDump.keySet()); + @SuppressWarnings("unchecked") + Map methodsActualDump = (Map) dump.get(Key.VALUE.toString()); + List actualKeys = new ArrayList(methodsActualDump.keySet()); + assertEquals(expectedKeys, actualKeys); } @Test @@ -692,17 +702,9 @@ public class DumpDirectiveTest { expectedDump.put(Key.NAME.toString(), varName); expectedDump.put(Key.TYPE.toString(), "freemarker.ext.dump.DumpDirectiveTest$Employee"); - SortedMap properties = new TreeMap(); - Calendar c = Calendar.getInstance(); - c.set(75, Calendar.MAY, 5); - properties.put("birthdate", c.getTime()); - properties.put("fullName", "John Doe"); - properties.put("id", 34523); - properties.put("nickname", ""); - properties.put("supervisees", ""); - properties.put("supervisor", ""); - - expectedDump.put(Key.VALUE.toString(), properties); + SortedMap methodsExpectedDump = getPropertiesExpectedDump(); + // methodsExpectedDump.putAll(...); + expectedDump.put(Key.VALUE.toString(), methodsExpectedDump); //Map dump = getDump(varName, dataModel); //assertEquals(expectedDump, dump); @@ -732,17 +734,9 @@ public class DumpDirectiveTest { expectedDump.put(Key.NAME.toString(), varName); expectedDump.put(Key.TYPE.toString(), "freemarker.ext.dump.DumpDirectiveTest$Employee"); - SortedMap properties = new TreeMap(); - Calendar c = Calendar.getInstance(); - c.set(75, Calendar.MAY, 5); - properties.put("birthdate", c.getTime()); - properties.put("fullName", "John Doe"); - properties.put("id", 34523); - properties.put("nickname", ""); - properties.put("supervisees", ""); - properties.put("supervisor", ""); - - expectedDump.put(Key.VALUE.toString(), properties); + SortedMap methodsExpectedDump = getPropertiesExpectedDump(); + // methodsExpectedDump.putAll(...); + expectedDump.put(Key.VALUE.toString(), methodsExpectedDump); //Map dump = getDump(varName, dataModel); //assertEquals(expectedDump, dump); @@ -884,7 +878,9 @@ public class DumpDirectiveTest { private String lastName; private String nickname; private Date birthdate; + private boolean married; private int id; + private String middleName; private Employee supervisor; private List supervisees; private float salary; @@ -892,7 +888,9 @@ public class DumpDirectiveTest { Employee(String firstName, String lastName, Date birthdate, int id) { this.firstName = firstName; this.lastName = lastName; + this.middleName = null; // test a null value this.birthdate = birthdate; + this.married = true; this.id = id; this.nickname = ""; count++; @@ -932,18 +930,26 @@ public class DumpDirectiveTest { public String getName(String which) { return which == "first" ? firstName : lastName; } + + public String getMiddleName() { + return middleName; + } public String getNickname() { return nickname; } - public Date getBirthdate() { - return birthdate; - } +// public Date getBirthdate() { +// return birthdate; +// } public int getId() { return id; } + + public boolean isMarried() { + return married; + } @Deprecated public int getFormerId() { @@ -964,22 +970,72 @@ public class DumpDirectiveTest { c.set(75, Calendar.MAY, 5); Employee jdoe = new Employee("John", "Doe", c.getTime(), 34523); - c.set(65, Calendar.AUGUST, 10); - Employee jsmith = new Employee("Jane", "Smith", c.getTime(), 78234); - - c.set(80, Calendar.JUNE, 20); - Employee mjones = new Employee("Michael", "Jones", c.getTime(), 65432); - - c.set(81, Calendar.NOVEMBER, 30); - Employee mturner = new Employee("Mary", "Turner", c.getTime(), 89531); +// c.set(65, Calendar.AUGUST, 10); +// Employee jsmith = new Employee("Jane", "Smith", c.getTime(), 78234); +// +// c.set(80, Calendar.JUNE, 20); +// Employee mjones = new Employee("Michael", "Jones", c.getTime(), 65432); +// +// c.set(81, Calendar.NOVEMBER, 30); +// Employee mturner = new Employee("Mary", "Turner", c.getTime(), 89531); List supervisees = new ArrayList(); - supervisees.add(mjones); - supervisees.add(mturner); +// supervisees.add(mjones); +// supervisees.add(mturner); //jdoe.setSupervisor(jsmith); //jdoe.setSupervisees(supervisees); jdoe.setSalary(65000); return jdoe; } + + private SortedMap getPropertiesExpectedDump() { + SortedMap propertiesExpectedDump = new TreeMap(); + + Map birthdateExpectedDump = new HashMap(); + birthdateExpectedDump.put(Key.TYPE.toString(), Type.DATE); + birthdateExpectedDump.put(Key.DATE_TYPE.toString(), DateType.UNKNOWN); + Calendar c = Calendar.getInstance(); + c.set(75, Calendar.MAY, 5); + birthdateExpectedDump.put(Key.VALUE.toString(), c.getTime()); + //propertiesExpectedDump.put("birthdate", birthdateExpectedDump); + + Map fullNameExpectedDump = new HashMap(); + fullNameExpectedDump.put(Key.TYPE.toString(), Type.STRING); + fullNameExpectedDump.put(Key.VALUE.toString(), "John Doe"); + propertiesExpectedDump.put("fullName", fullNameExpectedDump); + + Map idExpectedDump = new HashMap(); + idExpectedDump.put(Key.TYPE.toString(), Type.NUMBER); + idExpectedDump.put(Key.VALUE.toString(), 34523); + propertiesExpectedDump.put("id", idExpectedDump); + + Map nicknameExpectedDump = new HashMap(); + nicknameExpectedDump.put(Key.TYPE.toString(), Type.STRING); + nicknameExpectedDump.put(Key.VALUE.toString(), ""); + propertiesExpectedDump.put("nickname", nicknameExpectedDump); + + Map middleNameExpectedDump = new HashMap(); + middleNameExpectedDump.put(Key.VALUE.toString(), "null"); + propertiesExpectedDump.put("middleName", middleNameExpectedDump); + + Map marriedExpectedDump = new HashMap(); + marriedExpectedDump.put(Key.TYPE.toString(), Type.BOOLEAN); + marriedExpectedDump.put(Key.VALUE.toString(), true); + propertiesExpectedDump.put("married", marriedExpectedDump); + + Map superviseesExpectedDump = new HashMap(); + //superviseesExpectedDump.put(Key.TYPE.toString(), Type.SEQUENCE); + superviseesExpectedDump.put(Key.VALUE.toString(), "null"); + propertiesExpectedDump.put("supervisees", superviseesExpectedDump); + + Map supervisorExpectedDump = new HashMap(); + //supervisorExpectedDump.put(Key.TYPE.toString(), "freemarker.ext.dump.DumpDirectiveTest$Employee"); + supervisorExpectedDump.put(Key.VALUE.toString(), "null"); + propertiesExpectedDump.put("supervisor", supervisorExpectedDump); + + return propertiesExpectedDump; + } + + }