diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpAllDirective.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpAllDirective.java deleted file mode 100644 index 55813b2ed..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpAllDirective.java +++ /dev/null @@ -1,97 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.web.directives.dump; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.web.directives.BaseTemplateDirectiveModel; -import edu.cornell.mannlib.vitro.webapp.web.methods.BaseTemplateMethodModel; -import freemarker.core.Environment; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateException; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.utility.DeepUnwrap; - -public class DumpAllDirective extends BaseTemplateDirectiveModel { - - private static final Log log = LogFactory.getLog(DumpAllDirective.class); - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - - if (params.size() != 0) { - throw new TemplateModelException( - "The dumpAll directive doesn't allow parameters."); - } - if (loopVars.length != 0) { - throw new TemplateModelException( - "The dumpAll directive doesn't allow loop variables."); - } - if (body != null) { - throw new TemplateModelException( - "The dumpAll directive doesn't allow nested content."); - } - - TemplateHashModel dataModel = env.getDataModel(); - @SuppressWarnings("unchecked") - Map dm = (Map) DeepUnwrap.permissiveUnwrap(dataModel); - List varNames = new ArrayList(dm.keySet()); - Collections.sort(varNames); - - DumpHelper helper = new DumpHelper(env); - List models = new ArrayList(); - List directives = new ArrayList(); - List methods = new ArrayList(); - - for (String var : varNames) { - Object value = dm.get(var); - if (value instanceof BaseTemplateDirectiveModel) { - String help = ((BaseTemplateDirectiveModel) value).help(var, env); - directives.add(help); - } else if (value instanceof BaseTemplateMethodModel) { - String help = ((BaseTemplateMethodModel) value).help(var, env); - methods.add(help); - } else { - models.add(helper.getVariableDump(var)); - } - } - - Map map = new HashMap(); - map.put("models", models); - map.put("directives", directives); - map.put("methods", methods); - map.put("containingTemplate", env.getTemplate().getName()); - - helper.writeDump("dumpAll.ftl", map, "template data model", dataModel); - - } - - @Override - public String help(String name, Environment env) { - Map map = new HashMap(); - - map.put("name", name); - - map.put("effect", "Dump the contents of the template data model."); - - map.put("comments", "Sequences (lists and arrays) are enclosed in square brackets. Hashes are enclosed in curly braces."); - - List examples = new ArrayList(); - examples.add("<@" + name + " />"); - map.put("examples", examples); - - return mergeToHelpTemplate(map, env); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpDirective.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpDirective.java deleted file mode 100644 index 5713e911e..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpDirective.java +++ /dev/null @@ -1,77 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.web.directives.dump; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.web.directives.BaseTemplateDirectiveModel; -import freemarker.core.Environment; -import freemarker.template.Configuration; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateException; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; - -public class DumpDirective extends BaseTemplateDirectiveModel { - - private static final Log log = LogFactory.getLog(DumpDirective.class); - - @SuppressWarnings("unchecked") - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - - if (loopVars.length != 0) { - throw new TemplateModelException( - "The dump directive doesn't allow loop variables."); - } - if (body != null) { - throw new TemplateModelException( - "The dump directive doesn't allow nested content."); - } - - Object o = params.get("var"); - if ( !(o instanceof SimpleScalar)) { - throw new TemplateModelException( - "Value of parameter 'var' must be a string."); - } - - String var = ((SimpleScalar)o).getAsString(); - DumpHelper helper = new DumpHelper(env); - Map map = new HashMap(); - map.put("var", helper.getVariableDump(var)); - - helper.writeDump("dump.ftl", map, var, env.getDataModel()); - } - - @Override - public String help(String name, Environment env) { - Map map = new HashMap(); - - map.put("name", name); - - map.put("effect", "Dump the contents of a template variable."); - - map.put("comments", "Sequences (lists and arrays) are enclosed in square brackets. Hashes are enclosed in curly braces."); - - Map params = new HashMap(); - params.put("var", "name of variable to dump"); - map.put("params", params); - - List examples = new ArrayList(); - examples.add("<@" + name + " var=\"urls\" />"); - map.put("examples", examples); - - return mergeToHelpTemplate(map, env); - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpHelper.java deleted file mode 100644 index a32ba2a72..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/DumpHelper.java +++ /dev/null @@ -1,292 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.web.directives.dump; - -import java.io.IOException; -import java.io.Writer; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.web.directives.BaseTemplateDirectiveModel; -import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; -import freemarker.core.Environment; -import freemarker.ext.beans.BeanModel; -import freemarker.ext.beans.BeansWrapper; -import freemarker.ext.beans.WrapperExtractor; -import freemarker.template.Configuration; -import freemarker.template.TemplateBooleanModel; -import freemarker.template.TemplateDateModel; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateNumberModel; -import freemarker.template.TemplateScalarModel; -import freemarker.template.TemplateSequenceModel; -import freemarker.template.utility.DeepUnwrap; - -public class DumpHelper { - - private static final Log log = LogFactory.getLog(DumpHelper.class); - - private Environment env = null; - - public DumpHelper(Environment env) { - this.env = env; - } - - public String getVariableDump(String varName) { - Map map = getVariableDumpData(varName); - return BaseTemplateDirectiveModel.processTemplateToString("dump-var.ftl", map, env); - } - - private Map getVariableDumpData(String varName) { - TemplateHashModel dataModel = env.getDataModel(); - - TemplateModel wrappedModel = null; - try { - wrappedModel = dataModel.get(varName); - } catch (TemplateModelException e) { - log.error("Error getting value of template model '" + varName + "' from data model."); - } - - Map map = new HashMap(); - map.put("var", varName); - - // RY Separate out here into a method that gets the rest of the map. This method will - // be called recursively on the result of invoking a method (for a BaseTemplateModel) or - // the members of a hash or sequence. See NewDumpHelper.getVariableDumpData(). - - // DON'T return null if wrappedModel == null. We still want to return the map to the template. - if (wrappedModel != null) { - Object unwrappedModel = null; - try { - unwrappedModel = DeepUnwrap.permissiveUnwrap(wrappedModel); - } catch (TemplateModelException e) { - log.error("Cannot unwrap template model " + varName + "."); - return null; - } - - // Just use toString() method for now. Handles nested collections. Could make more sophisticated later. - // wrappedModel.toString() gives wrong results in the case of, e.g., a boolean value in a hash. tm.toString() may - // return a TemplateBooleanModel object, while unwrappedModel.toString() returns "true" or "false." - String value = unwrappedModel.toString(); // wrappedModel.toString(); - String className = unwrappedModel.getClass().getName(); - String type = null; - - // For basic Java types such as string, date, boolean, it's most helpful for the dump to - // show the shorthand type assigned below, rather than the Java class name. But for our - // BaseTemplateModel objects, show the actual class, since that provides additional - // information about the object (available methods, for example) that it is helpful to - // view in the dump. Not sure if we should handle our application-specific, non-template - // model objects in the same way. For now, these get assigned a shorthand type below. - - // if (wrappedModel instanceof TemplateHashModelEx) - - // a subcase of this is unwrappedModel instanceof BaseTemplateModel - if (unwrappedModel instanceof BaseTemplateModel) { - map.putAll(getBaseTemplateModelValues(wrappedModel, (BaseTemplateModel)unwrappedModel)); - type = className; - // Do TemplateHashModel case first, because wrappedModel of (at least some) POJOs are - // StringModels, which are both TemplateScalarModels and TemplateHashModels - } else if (wrappedModel instanceof TemplateHashModel) { - type = "Hash"; - } else if (wrappedModel instanceof TemplateScalarModel) { - type = "String"; - } else if (wrappedModel instanceof TemplateDateModel) { - type = "Date"; - } else if (wrappedModel instanceof TemplateNumberModel) { - type = "Number"; - } else if (wrappedModel instanceof TemplateBooleanModel) { - type = "Boolean"; - try { - value = ((TemplateBooleanModel) wrappedModel).getAsBoolean() ? "true" : "false"; - } catch (TemplateModelException e) { - log.error("Error getting boolean value for " + varName + "."); - } - } else if (wrappedModel instanceof TemplateSequenceModel){ - type = "Sequence"; - - } else { - // One of the above cases should have applied. Just in case not, show the Java class name. - type = className; - } - - map.put("type", type); - - // Don't overwrite value returned from getTemplateModelValues(). - if (! map.containsKey("value")) { - map.put("value", value); - } - - } - - return map; - } - - private int getExposureLevel(TemplateModel model, BaseTemplateModel unwrappedModel) { - - int exposureLevel; - // Get the exposure level of the BeansWrapper that wrapped this object. - if (model instanceof BeanModel) { - exposureLevel = WrapperExtractor.getWrapperExposureLevel((BeanModel) model); - log.debug("Exposure level for class " + unwrappedModel.getClass().getCanonicalName() + " wrapped as " + model.getClass() + " = " + exposureLevel); - // We don't expect to get here, since we are dealing only with BaseTemplateModel objects, which get wrapped into BeanModel objects, - // but it's here as a safety net. - } else { - HttpServletRequest request = (HttpServletRequest) env.getCustomAttribute("request"); - Configuration config = (Configuration) request.getAttribute("freemarkerConfig"); - BeansWrapper wrapper = (BeansWrapper) config.getObjectWrapper(); - exposureLevel = WrapperExtractor.getWrapperExposureLevel(wrapper); - log.debug("Class " + unwrappedModel.getClass().getCanonicalName() + " wrapped as " + model.getClass() + " uses default exposure level " + exposureLevel); - } - - return exposureLevel; - } - - List getMethodsAvailableToTemplate(TemplateModel wrappedModel, BaseTemplateModel unwrappedModel) { - int exposureLevel = getExposureLevel(wrappedModel, unwrappedModel); - return getMethodsAvailableToTemplate(exposureLevel, unwrappedModel); - } - - private List getMethodsAvailableToTemplate(int exposureLevel, BaseTemplateModel unwrappedModel) { - List availableMethods = new ArrayList(); - - Class cls = unwrappedModel.getClass(); - Method[] classMethods = cls.getMethods(); - for (Method method : classMethods) { - - // Exclude static methods - int mod = method.getModifiers(); - if (Modifier.isStatic(mod)) { - continue; - } - - // Include only methods declared on BaseTemplateModel or a subclass; - // exclude methods inherited from higher up the hierarchy like - // toString(), getClass(), etc. - Class c = method.getDeclaringClass(); - if ( ! BaseTemplateModel.class.isAssignableFrom(c)) { - continue; - } - - // If the method takes arguments, then it is not available to the template unless - // the exposure level of the BeansWrapper that wrapped the object allows it. - Class[] params = method.getParameterTypes(); - if (params.length > 0 && exposureLevel > BeansWrapper.EXPOSE_SAFE) { - continue; - } - - availableMethods.add(method); - } - - return availableMethods; - } - - protected String getMethodDisplayName(Method method) { - String methodName = method.getName(); - Class[] paramTypes = method.getParameterTypes(); - if (paramTypes.length > 0) { - List paramTypeList = new ArrayList(paramTypes.length); - for (Class cls : paramTypes) { - String name = cls.getName(); - String[] nameParts = name.split("\\."); - String typeName = nameParts[nameParts.length-1]; - typeName = typeName.replaceAll(";", "s"); - typeName = typeName.substring(0,1).toLowerCase() + typeName.substring(1); - paramTypeList.add(typeName); - } - methodName += "(" + StringUtils.join(paramTypeList, ", ") + ")"; - } else { - methodName = methodName.replaceAll("^(get|is)", ""); - methodName = methodName.substring(0, 1).toLowerCase() + methodName.substring(1); - } - - return methodName; - } - - private Map getBaseTemplateModelValues(TemplateModel wrappedModel, BaseTemplateModel unwrappedModel) { - int exposureLevel = getExposureLevel(wrappedModel, unwrappedModel); - return getBaseTemplateModelValues(unwrappedModel, exposureLevel); - } - - private Map getBaseTemplateModelValues(BaseTemplateModel model, int exposureLevel) { - Map map = new HashMap(); - map.put("value", model.toString()); - - List availableMethods = getMethodsAvailableToTemplate(exposureLevel, model); - SortedMap properties = new TreeMap(); - List methods = new ArrayList(); - for (Method method : availableMethods) { - String key = getMethodDisplayName(method); - if (key.endsWith(")")) { - methods.add(key); - } else { - try { - Object result = method.invoke(model); - // RY Here we need to recurse in order to dump the full value of - // the result, by calling a method formed from the second part - // of getVariableDumpData. - String value; - if (result == null) { - value = "null"; - } else if (result instanceof BaseTemplateModel) { - value = getTemplateModelDump((BaseTemplateModel)result, exposureLevel); - } else { - // Don't use ?html in the template, because then the output of - // getTemplateModelDump, which is html, gets escaped too. - value = StringEscapeUtils.escapeHtml(result.toString()); - } - properties.put(key, value); - } catch (Exception e) { - log.error(e, e); - continue; - } - } - } - - map.put("type", model.getClass().getName()); - map.put("properties", properties); - Collections.sort(methods); - map.put("methods", methods); - return map; - } - - private String getTemplateModelDump(BaseTemplateModel model, int exposureLevel) { - Map map = getBaseTemplateModelValues(model, exposureLevel); - return BaseTemplateDirectiveModel.processTemplateToString("dump-var.ftl", map, env); - } - - public void writeDump(String templateName, Map map, String modelName, TemplateHashModel dataModel) { - - // Add objects to data model of calling template that are needed by - // all dump templates. - try { - map.put("stylesheets", dataModel.get("stylesheets")); - map.put("urls", dataModel.get("urls")); - } catch (TemplateModelException e) { - log.error("Error getting values from data model."); - } - - String output = BaseTemplateDirectiveModel.processTemplateToString(templateName, map, env); - Writer out = env.getOut(); - try { - out.write(output); - } catch (IOException e) { - log.error("Error writing dump of " + modelName + "."); - } - } - -} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/HelpDirective.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/HelpDirective.java deleted file mode 100644 index 6b5091248..000000000 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/web/directives/dump/HelpDirective.java +++ /dev/null @@ -1,107 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package edu.cornell.mannlib.vitro.webapp.web.directives.dump; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.web.directives.BaseTemplateDirectiveModel; -import edu.cornell.mannlib.vitro.webapp.web.methods.BaseTemplateMethodModel; -import freemarker.core.Environment; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateException; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.utility.DeepUnwrap; - -public class HelpDirective extends BaseTemplateDirectiveModel { - - private static final Log log = LogFactory.getLog(HelpDirective.class); - - @SuppressWarnings("unchecked") - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - - if (loopVars.length != 0) { - throw new TemplateModelException( - "The help directive doesn't allow loop variables."); - } - if (body != null) { - throw new TemplateModelException( - "The help directive doesn't allow nested content."); - } - - Object o = params.get("for"); - - if ( o == null) { - throw new TemplateModelException( - "Must specify 'for' argument."); - } - - if ( !(o instanceof SimpleScalar)) { - throw new TemplateModelException( - "Value of parameter 'for' must be a string."); - } - - String name = ((SimpleScalar)o).getAsString(); - TemplateHashModel dataModel = env.getDataModel(); - Map dm = (Map) DeepUnwrap.permissiveUnwrap(dataModel); - Object value = dm.get(name); - - if (value == null) { - throw new TemplateModelException( - "Value of parameter '" + name + "' must be the name of a directive or method"); - } - - String help; - String type; - if (value instanceof BaseTemplateDirectiveModel) { - help = ((BaseTemplateDirectiveModel) value).help(name, env); - type = "directive"; - } else if (value instanceof BaseTemplateMethodModel) { - help = ((BaseTemplateMethodModel) value).help(name, env); - type = "method"; - } else { - throw new TemplateModelException( - "Value of parameter '" + name + "' must be the name of a directive or method"); - } - - Map map = new HashMap(); - map.put("help", help); - map.put("type", type); - - DumpHelper helper = new DumpHelper(env); - helper.writeDump("help.ftl", map, name, dataModel); - - } - - @Override - public String help(String name, Environment env) { - Map map = new HashMap(); - - map.put("name", name); - - map.put("effect", "Output help for a directive or method."); - - Map params = new HashMap(); - params.put("for", "name of directive or method"); - map.put("params", params); - - List examples = new ArrayList(); - examples.add("<@" + name + " for=\"dump\" />"); - examples.add("<@" + name + " for=\"profileUrl\" />"); - map.put("examples", examples); - - return mergeToHelpTemplate(map, env); - } - -} diff --git a/webapp/src/freemarker/ext/beans/WrapperExtractor.java b/webapp/src/freemarker/ext/beans/WrapperExtractor.java deleted file mode 100644 index 7ed256885..000000000 --- a/webapp/src/freemarker/ext/beans/WrapperExtractor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* $This file is distributed under the terms of the license in /doc/license.txt$ */ - -package freemarker.ext.beans; - -/** - * Class to extract information about the wrapper used to wrap an object in - * the template model. This is something of a hack: the class belongs to - * package freemarker.ext.beans so we can get at protected members of - * BeanModel and BeansWrapper. The Freemarker API unfortunately provides - * no way to get the wrapper that is used to wrap an object in the - * template data model. - */ -public class WrapperExtractor { - - public static BeansWrapper getWrapper(BeanModel model) { - return model.wrapper; - } - - public static int getWrapperExposureLevel(BeanModel model) { - return model.wrapper.getExposureLevel(); - } - - public static int getWrapperExposureLevel(BeansWrapper wrapper) { - return wrapper.getExposureLevel(); - } - -}