NIHVIVO-2470 Initial work on new dump template. Handle undefined variables.

This commit is contained in:
ryounes 2011-04-20 21:23:38 +00:00
parent 4bff64ca12
commit 84f779238c
9 changed files with 96 additions and 56 deletions

View file

@ -316,6 +316,9 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
map.put("dump", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.DumpDirective()); map.put("dump", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.DumpDirective());
map.put("dumpAll", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.DumpAllDirective()); map.put("dumpAll", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.DumpAllDirective());
map.put("help", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.HelpDirective()); map.put("help", new edu.cornell.mannlib.vitro.webapp.web.directives.dump.HelpDirective());
map.put("dump1", new freemarker.ext.dump.DumpDirective());
map.put("dumpAll1", new freemarker.ext.dump.DumpAllDirective());
map.put("help1", new freemarker.ext.dump.HelpDirective());
map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective()); map.put("url", new edu.cornell.mannlib.vitro.webapp.web.directives.UrlDirective());
map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective()); map.put("widget", new edu.cornell.mannlib.vitro.webapp.web.directives.WidgetDirective());
return map; return map;

View file

@ -50,15 +50,17 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel {
private static final Log log = LogFactory.getLog(BaseDumpDirective.class); private static final Log log = LogFactory.getLog(BaseDumpDirective.class);
Pattern PROPERTY_NAME_PATTERN = Pattern.compile("^(get|is)\\w"); protected static final String TEMPLATE_DEFAULT = "dump1.ftl"; // change to dump.ftl when old dump is removed
protected static final String VALUE_UNDEFINED = "Undefined";
protected static final Pattern PROPERTY_NAME_PATTERN = Pattern.compile("^(get|is)\\w");
enum Key { enum Key {
DATE_TYPE("dateType"),
METHODS("methods"), METHODS("methods"),
PROPERTIES("properties"), PROPERTIES("properties"),
TYPE("type"), TYPE("type"),
VALUE("value"), VALUE("value");
DATE_TYPE("dateType");
private final String key; private final String key;
Key(String key) { Key(String key) {
@ -71,17 +73,18 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel {
} }
enum Type { enum Type {
STRING("String"),
NUMBER("Number"),
BOOLEAN("Boolean"), BOOLEAN("Boolean"),
COLLECTION("Collection"),
DATE("Date"), DATE("Date"),
SEQUENCE("Sequence"), DIRECTIVE("Directive"),
HASH("Hash"), HASH("Hash"),
// Technically it's a HashEx, but for the templates call it a Hash // Technically it's a HashEx, but for the templates call it a Hash
HASH_EX("Hash"), // ("HashEx") HASH_EX("Hash"), // ("HashEx")
COLLECTION("Collection"), METHOD("Method"),
METHOD("Method"), NUMBER("Number"),
DIRECTIVE("Directive"); SEQUENCE("Sequence"),
STRING("String"),
UNDEFINED("Undefined");
private final String type; private final String type;
@ -124,21 +127,22 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel {
Map<String, Object> value = new HashMap<String, Object>(); Map<String, Object> value = new HashMap<String, Object>();
// Don't return null if model == null. We still want to send the map to the template. if (model == null) {
if (model != null) { value.put(Key.TYPE.toString(), Type.UNDEFINED);
// TemplateMethodModel and TemplateDirectiveModel objects can only be value.put(Key.VALUE.toString(), VALUE_UNDEFINED);
// included in the data model at the top level.
if (model instanceof TemplateMethodModel) { // TemplateMethodModel and TemplateDirectiveModel objects can only be
value.putAll( getTemplateModelDump( ( TemplateMethodModel)model, varName ) ); // included in the data model at the top level.
} else if (model instanceof TemplateMethodModel) {
} else if (model instanceof TemplateDirectiveModel) { value.putAll( getTemplateModelDump( ( TemplateMethodModel)model, varName ) );
value.putAll( getTemplateModelDump( ( TemplateDirectiveModel)model, varName ) );
} else if (model instanceof TemplateDirectiveModel) {
} else { value.putAll( getTemplateModelDump( ( TemplateDirectiveModel)model, varName ) );
value.putAll(getDump(model));
} } else {
value.putAll(getDump(model));
} }
Map<String, Object> dump = new HashMap<String, Object>(); Map<String, Object> dump = new HashMap<String, Object>();
dump.put(varName, value); dump.put(varName, value);
return dump; return dump;
@ -455,9 +459,13 @@ public abstract class BaseDumpDirective implements TemplateDirectiveModel {
return map; return map;
} }
protected void dump(String templateName, Map<String, Object> map, Environment env) protected void dump(String templateName, Map<String, Object> dump, Environment env)
throws TemplateException, IOException { throws TemplateException, IOException {
// Wrap the dump in another map so the template has a handle to iterate through
// the values: <#list dump?keys as key>...</#list>
Map<String, Map<String, Object>> map = new HashMap<String, Map<String, Object>>();
map.put("dump", dump);
Template template = env.getConfiguration().getTemplate(templateName); Template template = env.getConfiguration().getTemplate(templateName);
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
template.process(map, sw); template.process(map, sw);

View file

@ -4,7 +4,6 @@ package freemarker.ext.dump;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -48,7 +47,7 @@ public class DumpAllDirective extends BaseDumpDirective {
} }
SortedMap<String, Object> dataModelDump = getDataModelDump(env); SortedMap<String, Object> dataModelDump = getDataModelDump(env);
dump("dump-all.ftl", dataModelDump, env); dump(TEMPLATE_DEFAULT, dataModelDump, env);
} }
SortedMap<String, Object> getDataModelDump(Environment env) throws TemplateModelException { SortedMap<String, Object> getDataModelDump(Environment env) throws TemplateModelException {

View file

@ -37,16 +37,10 @@ public class DumpDirective extends BaseDumpDirective {
"The dump directive doesn't allow nested content."); "The dump directive doesn't allow nested content.");
} }
Object o = params.get("var"); String varName = params.get("var").toString();
if ( !(o instanceof SimpleScalar)) {
throw new TemplateModelException(
"Value of parameter 'var' must be a string.");
}
String varName = ((SimpleScalar)o).getAsString();
Map<String, Object> map = getTemplateVariableDump(varName, env); Map<String, Object> map = getTemplateVariableDump(varName, env);
dump("dumpvar.ftl", map, env); dump(TEMPLATE_DEFAULT, map, env);
} }
@Override @Override

View file

@ -41,12 +41,7 @@ public class HelpDirective extends BaseDumpDirective {
"Must specify 'for' argument."); "Must specify 'for' argument.");
} }
if ( !(o instanceof SimpleScalar)) { String varName = params.get("var").toString();
throw new TemplateModelException(
"Value of parameter 'for' must be a string.");
}
String varName = ((SimpleScalar)o).getAsString();
TemplateHashModel dataModel = env.getDataModel(); TemplateHashModel dataModel = env.getDataModel();
Object templateModel = dataModel.get(varName); Object templateModel = dataModel.get(varName);
@ -61,7 +56,7 @@ public class HelpDirective extends BaseDumpDirective {
} }
Map<String, Object> map = getTemplateVariableDump(varName, env); Map<String, Object> map = getTemplateVariableDump(varName, env);
dump("dumpvar.ftl", map, env); dump(TEMPLATE_DEFAULT, map, env);
} }
@Override @Override

View file

@ -71,6 +71,22 @@ public class DumpDirectiveTest {
Logger.getLogger(BaseDumpDirective.class).setLevel(Level.OFF); Logger.getLogger(BaseDumpDirective.class).setLevel(Level.OFF);
} }
@Test
public void dumpUndefinedValue() {
String varName = "dog";
Map<String, Object> dataModel = new HashMap<String, Object>();
Map<String, Object> expectedDumpValue = new HashMap<String, Object>();
expectedDumpValue.put(Key.TYPE.toString(), Type.UNDEFINED);
expectedDumpValue.put(Key.VALUE.toString(), BaseDumpDirective.VALUE_UNDEFINED);
Map<String, Object> expectedDump = new HashMap<String, Object>();
expectedDump.put(varName, expectedDumpValue);
test(varName, dataModel, expectedDump);
}
@Test @Test
public void dumpString() { public void dumpString() {

View file

@ -1,13 +0,0 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Template for displaying directive describe -->
<div class="dump">
<h3>Methods available to variable <em>${var}</em></h3>
<#list methods as method>
${method}<br />
</#list>
</div>
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/dump.css" />')}

View file

@ -1 +0,0 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->

View file

@ -0,0 +1,39 @@
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
<#-- Template for dump directives -->
<#-- Styles here are temporary; move to css file once stylesheets.add() works -->
<style>
ul.dump {
padding-top: .75em;
padding-bottom: .75em;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
margin-bottom: .5em;
}
ul.dump li p {
margin-bottom: .5em;
}
</style>
<#-- <pre><@dumper.dump dump /></pre> -->
<#if dump?keys?has_content>
<ul class="dump">
<#list dump?keys as key>
<li>
<#assign value = dump[key] />
<p><strong>Variable name:</strong> ${key}</p>
<#if value.type??><p><strong>Type:</strong> ${value.type}</p></#if>
<#-- <p><strong>Value:</strong> ${value.value}</p> -->
<#-- What to do here depends on time. Test either ${var.type} or ${var.value} -->
<#-- <p><strong>Value:</strong> ${var.value}</p> -->
</li>
</#list>
</ul>
</#if>
<#-- This will work after we move stylesheets to Configuration sharedVariables
${stylesheets.add('<link rel="stylesheet" href="/css/fmdump.css">')}
-->