NIHVIVO-2479 Finalize dump template
This commit is contained in:
parent
27b78c2760
commit
8f0b6f7b01
5 changed files with 327 additions and 43 deletions
|
@ -0,0 +1,253 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
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.commons.lang.time.DateUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||
import freemarker.ext.beans.BeansWrapper;
|
||||
import freemarker.template.SimpleCollection;
|
||||
import freemarker.template.TemplateModelException;
|
||||
|
||||
/**
|
||||
* Test of dump directives
|
||||
* @author rjy7
|
||||
*
|
||||
*/
|
||||
public class DumpTestController extends FreemarkerHttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log log = LogFactory.getLog(TestController.class);
|
||||
private static final String TEMPLATE_DEFAULT = "test.ftl";
|
||||
|
||||
@Override
|
||||
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||
//Portal portal = vreq.getPortal();
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
|
||||
body.put("title", "Freemarker Test");
|
||||
|
||||
body.put("dog", "Rover");
|
||||
body.put("int", 7);
|
||||
body.put("bool", false);
|
||||
body.put("now", new Date());
|
||||
|
||||
java.sql.Date date = new java.sql.Date(1302297332043L);
|
||||
body.put("date", date);
|
||||
|
||||
Time time = new Time(1302297332043L);
|
||||
body.put("time", time);
|
||||
|
||||
Timestamp ts = new Timestamp(1302297332043L);
|
||||
body.put("timestamp", ts);
|
||||
|
||||
// List of strings
|
||||
List<String> fruit = new ArrayList<String>();
|
||||
fruit.add("apples");
|
||||
fruit.add("bananas");
|
||||
fruit.add("peaches");
|
||||
body.put("fruit", fruit);
|
||||
|
||||
// Mixed list
|
||||
List<Object> mixedList = new ArrayList<Object>();
|
||||
|
||||
String myString = "apples";
|
||||
mixedList.add(myString);
|
||||
|
||||
int myInt = 4;
|
||||
mixedList.add(myInt);
|
||||
|
||||
boolean myBool = true;
|
||||
mixedList.add(myBool);
|
||||
|
||||
List<String> myList = new ArrayList<String>();
|
||||
myList.add("dog");
|
||||
myList.add("cat");
|
||||
myList.add("elephant");
|
||||
mixedList.add(myList);
|
||||
body.put("mixedList", mixedList);
|
||||
|
||||
// Collection (non-indexable)
|
||||
Set<Integer> odds = new HashSet<Integer>();
|
||||
for (int i=0; i <= 10; i++) {
|
||||
if (i % 2 == 1) {
|
||||
odds.add(i);
|
||||
}
|
||||
}
|
||||
body.put("oddNums", new SimpleCollection(odds));
|
||||
|
||||
// String-string map
|
||||
Map<String, String> myMap = new HashMap<String, String>();
|
||||
myMap.put("Albany", "New York");
|
||||
myMap.put("St. Paul", "Minnesota");
|
||||
myMap.put("Austin", "Texas");
|
||||
myMap.put("Sacramento", "California");
|
||||
myMap.put("Richmond", "Virginia");
|
||||
body.put("capitals", myMap);
|
||||
|
||||
|
||||
// Mixed map
|
||||
Map<String, Object> mixedMap = new HashMap<String, Object>();
|
||||
|
||||
mixedMap.put("myString", myString);
|
||||
mixedMap.put("myBoolean", myBool);
|
||||
mixedMap.put("myNumber", myInt);
|
||||
Date myDate = new Date();
|
||||
mixedMap.put("myDate", myDate);
|
||||
mixedMap.put("myList", myList);
|
||||
mixedMap.put("capitals", myMap);
|
||||
body.put("mixedMap", mixedMap);
|
||||
|
||||
// Java object
|
||||
Employee jdoe = getEmployee();
|
||||
body.put("employeeLimited", jdoe);
|
||||
try {
|
||||
body.put("employeeInvisible", wrap(jdoe, BeansWrapper.EXPOSE_NOTHING));
|
||||
body.put("employeeFull", wrap(jdoe, BeansWrapper.EXPOSE_SAFE));
|
||||
} catch (TemplateModelException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return new TemplateResponseValues(TEMPLATE_DEFAULT, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTitle(String siteName, VitroRequest vreq) {
|
||||
return "Test";
|
||||
}
|
||||
|
||||
public static class Employee {
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String nickname;
|
||||
private Date birthdate;
|
||||
private boolean married;
|
||||
private int id;
|
||||
private String middleName;
|
||||
private List<String> favoriteColors;
|
||||
private Employee supervisor;
|
||||
private float salary;
|
||||
|
||||
Employee(String firstName, String lastName, int id, Date birthdate) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.middleName = null; // test a null value
|
||||
this.birthdate = birthdate;
|
||||
this.married = true;
|
||||
this.id = id;
|
||||
this.nickname = "";
|
||||
this.favoriteColors = new ArrayList<String>();
|
||||
count++;
|
||||
}
|
||||
|
||||
protected void setSupervisor(Employee supervisor) {
|
||||
this.supervisor = supervisor;
|
||||
}
|
||||
|
||||
void setSalary(float salary) {
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public void setFavoriteColors(String...colors) {
|
||||
for (String color : colors) {
|
||||
favoriteColors.add(color);
|
||||
}
|
||||
}
|
||||
|
||||
float getSalary() {
|
||||
return salary;
|
||||
}
|
||||
|
||||
public static int getEmployeeCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Public accessor methods for templates */
|
||||
|
||||
public String getFullName() {
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
|
||||
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 int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isMarried() {
|
||||
return married;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getFormerId() {
|
||||
return id % 10000;
|
||||
}
|
||||
|
||||
public Employee getSupervisor() {
|
||||
return supervisor;
|
||||
}
|
||||
|
||||
public List<String> getFavoriteColors() {
|
||||
return favoriteColors;
|
||||
}
|
||||
}
|
||||
|
||||
private Employee getEmployee() {
|
||||
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.set(1982, Calendar.MAY, 5);
|
||||
c = DateUtils.truncate(c, Calendar.DATE);
|
||||
Employee jdoe = new Employee("John", "Doe", 34523, c.getTime());
|
||||
jdoe.setFavoriteColors("blue", "green");
|
||||
jdoe.setSalary(65000);
|
||||
|
||||
c.clear();
|
||||
c.set(1975, Calendar.OCTOBER, 25);
|
||||
c = DateUtils.truncate(c, Calendar.DATE);
|
||||
Employee jsmith = new Employee("Jane", "Smith", 78234, c.getTime());
|
||||
jsmith.setFavoriteColors("red", "orange");
|
||||
|
||||
jdoe.setSupervisor(jsmith);
|
||||
|
||||
return jdoe;
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
return UrlBuilder.getUrl(path);
|
||||
}
|
||||
|
||||
protected TemplateModel wrap(int exposureLevel, Object obj) throws TemplateModelException {
|
||||
protected TemplateModel wrap(Object obj, int exposureLevel) throws TemplateModelException {
|
||||
BeansWrapper wrapper = getBeansWrapper(exposureLevel);
|
||||
return wrapper.wrap(obj);
|
||||
}
|
||||
|
@ -271,7 +271,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet {
|
|||
// instead of the configuration's object wrapper, which doesn't. The templates can
|
||||
// add stylesheets and scripts to the lists by calling their add() methods.
|
||||
try {
|
||||
return wrap(BeansWrapper.EXPOSE_SAFE, new Tags());
|
||||
return wrap(new Tags(), BeansWrapper.EXPOSE_SAFE);
|
||||
} catch (TemplateModelException e) {
|
||||
log.error("Error creating Tags template model");
|
||||
return null;
|
||||
|
|
|
@ -133,7 +133,7 @@ public class IndividualController extends FreemarkerHttpServlet {
|
|||
* This is still safe, because we are only putting BaseTemplateModel objects
|
||||
* into the data model: no real data can be modified.
|
||||
*/
|
||||
body.put("individual", wrap(BeansWrapper.EXPOSE_SAFE, itm));
|
||||
body.put("individual", wrap(itm, BeansWrapper.EXPOSE_SAFE));
|
||||
body.put("headContent", getRdfLinkTag(itm));
|
||||
|
||||
String template = getIndividualTemplate(individual, vreq);
|
||||
|
|
|
@ -1011,7 +1011,7 @@ public class DumpDirectiveTest {
|
|||
// Properties
|
||||
SortedMap<String, Object> propertiesExpectedDump = new TreeMap<String, Object>();
|
||||
|
||||
if (exposureLevel != BeansWrapper.EXPOSE_NOTHING) {
|
||||
if (exposureLevel < BeansWrapper.EXPOSE_NOTHING) {
|
||||
|
||||
Map<String, Object> birthdateExpectedDump = new HashMap<String, Object>();
|
||||
birthdateExpectedDump.put(Key.TYPE.toString(), Type.DATE);
|
||||
|
@ -1078,7 +1078,7 @@ public class DumpDirectiveTest {
|
|||
private List<String> getEmployeeMethodsExpectedDump(int exposureLevel) {
|
||||
|
||||
List<String> expectedDump = new ArrayList<String>();
|
||||
if (exposureLevel == BeansWrapper.EXPOSE_SAFE || exposureLevel == BeansWrapper.EXPOSE_ALL) {
|
||||
if (exposureLevel <= BeansWrapper.EXPOSE_SAFE) {
|
||||
expectedDump.add("getEmployeeCount");
|
||||
expectedDump.add("getName(String)");
|
||||
expectedDump.add("setFavoriteColors(Strings)");
|
||||
|
@ -1095,7 +1095,7 @@ public class DumpDirectiveTest {
|
|||
SortedMap<String, Object> propertiesExpectedDump = new TreeMap<String, Object>();
|
||||
|
||||
// Properties
|
||||
if (exposureLevel != BeansWrapper.EXPOSE_NOTHING) {
|
||||
if (exposureLevel < BeansWrapper.EXPOSE_NOTHING) {
|
||||
|
||||
Map<String, Object> birthdateExpectedDump = new HashMap<String, Object>();
|
||||
birthdateExpectedDump.put(Key.TYPE.toString(), Type.DATE);
|
||||
|
|
|
@ -31,6 +31,10 @@ div.dump {
|
|||
.dump ul li.item .value {
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.dump ul.methods li {
|
||||
margin-bottom: .25em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="dump">
|
||||
|
@ -44,40 +48,62 @@ div.dump {
|
|||
<ul>
|
||||
<#list dump?keys as key>
|
||||
<li>
|
||||
<p><strong>Variable name:</strong> ${key}</p>
|
||||
<@doMap dump[key] />
|
||||
<p><strong>Variable name:</strong> ${key}</p>
|
||||
|
||||
<#local type = dump[key].type>
|
||||
<#if type == "Directive" || type == "Method">
|
||||
<@doMethod dump[key] />
|
||||
<#else>
|
||||
<@doTypeAndValue dump[key] />
|
||||
</#if>
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#macro doMap map>
|
||||
<#if map.type?has_content>
|
||||
<p><strong>Type:</strong> ${map.type}</p>
|
||||
<#macro doTypeAndValue map>
|
||||
<#local type = map.type!>
|
||||
<#if type?has_content>
|
||||
<p><strong>Type:</strong> ${type}</p>
|
||||
|
||||
<#if map.dateType?has_content>
|
||||
<p><strong>Date type:</strong> ${map.dateType}</p>
|
||||
</#if>
|
||||
</#if>
|
||||
|
||||
<#if map.type == "Directive" || map.type == "Method">
|
||||
<@doHelp map.help! />
|
||||
<#else>
|
||||
<@doValue map.type map.value! />
|
||||
</#if>
|
||||
|
||||
|
||||
<#local value = map.value!>
|
||||
<#if value??>
|
||||
<div class="values">
|
||||
<#if type?contains(".")><@doObjectValue value />
|
||||
<#elseif value?is_sequence><@doSequenceValue value type />
|
||||
<#elseif value?is_hash_ex><@doMapValue value />
|
||||
<#else><@doScalarValue value />
|
||||
</#if>
|
||||
</div>
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#macro doValue type value="">
|
||||
<div class="values">
|
||||
<#if value??>
|
||||
<#if value?is_sequence><@doSequenceValue value type/>
|
||||
<#elseif value?is_hash_ex><@doMapValue value />
|
||||
<#else><@doScalarValue type value />
|
||||
</#if>
|
||||
</#if>
|
||||
</div>
|
||||
<#macro doObjectValue obj>
|
||||
<#if obj.properties?has_content>
|
||||
<p><strong>Properties:</strong></p>
|
||||
<ul class="properties">
|
||||
<#list obj.properties?keys as property>
|
||||
<@liItem>
|
||||
${property} => <@divValue><@doTypeAndValue obj.properties[property] /></@divValue>
|
||||
</@liItem>
|
||||
</#list>
|
||||
</ul>
|
||||
</#if>
|
||||
|
||||
<#if obj.methods?has_content>
|
||||
<p><strong>Methods:</strong</p>
|
||||
<ul class="methods">
|
||||
<#list obj.methods as method>
|
||||
<@liItem>${method}</@liItem>
|
||||
</#list>
|
||||
</ul>
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#macro doSequenceValue seq type>
|
||||
|
@ -85,14 +111,13 @@ div.dump {
|
|||
<#if seq?has_content>
|
||||
<ul class="sequence">
|
||||
<#list seq as item>
|
||||
<li class="item">
|
||||
<@liItem>
|
||||
<#if type == "Sequence">
|
||||
Item ${item_index}:
|
||||
<@valueDiv><@doMap item /></@valueDiv>
|
||||
<#else><@doMap item />
|
||||
</#if>
|
||||
|
||||
</li>
|
||||
<@divValue><@doTypeAndValue item /></@divValue>
|
||||
<#else><@doTypeAndValue item />
|
||||
</#if>
|
||||
</@liItem>
|
||||
</#list>
|
||||
</ul>
|
||||
<#else>no values
|
||||
|
@ -104,33 +129,35 @@ div.dump {
|
|||
<#if map?has_content>
|
||||
<ul class="map">
|
||||
<#list map?keys as key>
|
||||
<li class="item">
|
||||
${key} => <@valueDiv><@doMap map[key] /></@valueDiv>
|
||||
</li>
|
||||
<@liItem>
|
||||
${key} => <@divValue><@doTypeAndValue map[key] /></@divValue>
|
||||
</@liItem>
|
||||
</#list>
|
||||
</ul>
|
||||
<#else>no values
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#macro doScalarValue type value>
|
||||
<#macro doScalarValue value>
|
||||
<strong>Value:</strong>
|
||||
|
||||
<#if value?is_string || value?is_number>${value}
|
||||
<#if value?is_string>${value}
|
||||
<#elseif value?is_number>${value?c}
|
||||
<#elseif value?is_boolean>${value?string}
|
||||
<#elseif value?is_date>${value?string("EEEE, MMMM dd, yyyy hh:mm:ss a zzz")}
|
||||
<#else>no value
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#macro doHelp help="">
|
||||
<#macro doMethod method>
|
||||
<p><strong>Type:</strong> ${method.type}</p>
|
||||
<#local help = method.help>
|
||||
<#if help?has_content>
|
||||
<p><strong>Help:</strong><p>
|
||||
<ul class="help">
|
||||
<#list help?keys as key>
|
||||
<li>
|
||||
<#local value = help[key]>
|
||||
<@valueDiv>
|
||||
<@divValue>
|
||||
<#if value?is_string><p><strong>${key?capitalize}:</strong> ${value}</p>
|
||||
<#else>
|
||||
<p><strong>${key?capitalize}:</strong></p>
|
||||
|
@ -146,17 +173,21 @@ div.dump {
|
|||
</#if>
|
||||
</ul>
|
||||
</#if>
|
||||
</@valueDiv>
|
||||
</@divValue>
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#macro valueDiv>
|
||||
<#macro divValue>
|
||||
<div class="value"><#nested></div>
|
||||
</#macro>
|
||||
|
||||
<#macro liItem>
|
||||
<li class="item"><#nested></li>
|
||||
</#macro>
|
||||
|
||||
|
||||
<#-- This will work after we move stylesheets to Configuration sharedVariables
|
||||
${stylesheets.add('<link rel="stylesheet" href="/css/fmdump.css">')}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue