NIHVIVO-3628 convert PropertyListConfig and InvalidConfigurationException from inner classes on ObjectPropertyTemplateModel to top-level classes. Combine InvalidConfigurationException with InvalidConfigFileException. Adjust tests accordingly.
This commit is contained in:
parent
6a4228f099
commit
11d32685cf
8 changed files with 313 additions and 269 deletions
|
@ -71,7 +71,7 @@ public class CustomListViewConfigFile {
|
||||||
// Might be empty but will not be null.
|
// Might be empty but will not be null.
|
||||||
private final String postprocessorName;
|
private final String postprocessorName;
|
||||||
|
|
||||||
public CustomListViewConfigFile(Reader reader) throws InvalidConfigFileException {
|
public CustomListViewConfigFile(Reader reader) throws InvalidConfigurationException {
|
||||||
Document doc = parseDocument(reader);
|
Document doc = parseDocument(reader);
|
||||||
selectQueryElement = parseSelectQuery(doc);
|
selectQueryElement = parseSelectQuery(doc);
|
||||||
constructQueries = parseConstructQueries(doc);
|
constructQueries = parseConstructQueries(doc);
|
||||||
|
@ -80,9 +80,9 @@ public class CustomListViewConfigFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Document parseDocument(Reader reader)
|
private Document parseDocument(Reader reader)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
if (reader == null) {
|
if (reader == null) {
|
||||||
throw new InvalidConfigFileException("Config file reader is null.");
|
throw new InvalidConfigurationException("Config file reader is null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -91,18 +91,18 @@ public class CustomListViewConfigFile {
|
||||||
Document doc = db.parse(new InputSource(reader));
|
Document doc = db.parse(new InputSource(reader));
|
||||||
return doc;
|
return doc;
|
||||||
} catch (ParserConfigurationException e) {
|
} catch (ParserConfigurationException e) {
|
||||||
throw new InvalidConfigFileException("Problem with XML parser.", e);
|
throw new InvalidConfigurationException("Problem with XML parser.", e);
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
throw new InvalidConfigFileException(
|
throw new InvalidConfigurationException(
|
||||||
"Config file is not valid XML: " + e.getMessage(), e);
|
"Config file is not valid XML: " + e.getMessage(), e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new InvalidConfigFileException("Unable to read config file.",
|
throw new InvalidConfigurationException("Unable to read config file.",
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element parseSelectQuery(Document doc)
|
private Element parseSelectQuery(Document doc)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
Element element = getExactlyOneElement(doc, TAG_SELECT);
|
Element element = getExactlyOneElement(doc, TAG_SELECT);
|
||||||
elementMustNotBeEmpty(element);
|
elementMustNotBeEmpty(element);
|
||||||
return element;
|
return element;
|
||||||
|
@ -120,14 +120,14 @@ public class CustomListViewConfigFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parseTemplateName(Document doc)
|
private String parseTemplateName(Document doc)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
Element element = getExactlyOneElement(doc, TAG_TEMPLATE);
|
Element element = getExactlyOneElement(doc, TAG_TEMPLATE);
|
||||||
elementMustNotBeEmpty(element);
|
elementMustNotBeEmpty(element);
|
||||||
return element.getTextContent();
|
return element.getTextContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parsePostprocessorName(Document doc)
|
private String parsePostprocessorName(Document doc)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
Element element = getZeroOrOneElement(doc, TAG_POSTPROCESSOR);
|
Element element = getZeroOrOneElement(doc, TAG_POSTPROCESSOR);
|
||||||
if (element == null) {
|
if (element == null) {
|
||||||
return "";
|
return "";
|
||||||
|
@ -148,40 +148,40 @@ public class CustomListViewConfigFile {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element getExactlyOneElement(Document doc, String tagName)
|
private Element getExactlyOneElement(Document doc, String tagName)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
List<Element> elements = getElements(doc, tagName);
|
List<Element> elements = getElements(doc, tagName);
|
||||||
|
|
||||||
if (elements.size() == 1) {
|
if (elements.size() == 1) {
|
||||||
return elements.get(0);
|
return elements.get(0);
|
||||||
} else if (elements.isEmpty()) {
|
} else if (elements.isEmpty()) {
|
||||||
throw new InvalidConfigFileException("Config file must contain a "
|
throw new InvalidConfigurationException("Config file must contain a "
|
||||||
+ tagName + " element");
|
+ tagName + " element");
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidConfigFileException(
|
throw new InvalidConfigurationException(
|
||||||
"Config file may not contain more than one " + tagName
|
"Config file may not contain more than one " + tagName
|
||||||
+ " element");
|
+ " element");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element getZeroOrOneElement(Document doc, String tagName)
|
private Element getZeroOrOneElement(Document doc, String tagName)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
List<Element> elements = getElements(doc, tagName);
|
List<Element> elements = getElements(doc, tagName);
|
||||||
if (elements.size() == 1) {
|
if (elements.size() == 1) {
|
||||||
return elements.get(0);
|
return elements.get(0);
|
||||||
} else if (elements.isEmpty()) {
|
} else if (elements.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidConfigFileException(
|
throw new InvalidConfigurationException(
|
||||||
"Config file may not contain more than one " + tagName
|
"Config file may not contain more than one " + tagName
|
||||||
+ " element");
|
+ " element");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void elementMustNotBeEmpty(Element element)
|
private void elementMustNotBeEmpty(Element element)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
String contents = element.getTextContent();
|
String contents = element.getTextContent();
|
||||||
if (contents.trim().isEmpty()) {
|
if (contents.trim().isEmpty()) {
|
||||||
throw new InvalidConfigFileException("In a config file, the <"
|
throw new InvalidConfigurationException("In a config file, the <"
|
||||||
+ element.getTagName() + "> element must not be empty.");
|
+ element.getTagName() + "> element must not be empty.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,13 +249,4 @@ public class CustomListViewConfigFile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InvalidConfigFileException extends Exception {
|
|
||||||
public InvalidConfigFileException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidConfigFileException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that there is a problem with the custom configuration. Perhaps the
|
||||||
|
* file can't be found, can't be parsed, or the information it contains is
|
||||||
|
* erroneous.
|
||||||
|
*/
|
||||||
|
public class InvalidConfigurationException extends Exception {
|
||||||
|
|
||||||
|
public InvalidConfigurationException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidConfigurationException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidConfigurationException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidConfigurationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.CollatedObjectPropertyTemplateModel;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DefaultObjectPropertyDataPostProcessor;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyDataPostProcessor;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel.ConfigError;
|
||||||
|
import freemarker.cache.TemplateLoader;
|
||||||
|
import freemarker.template.Configuration;
|
||||||
|
|
||||||
|
public class PropertyListConfig {
|
||||||
|
private static final Log log = LogFactory.getLog(PropertyListConfig.class);
|
||||||
|
|
||||||
|
|
||||||
|
private static final String CONFIG_FILE_PATH = "/config/";
|
||||||
|
private static final String DEFAULT_CONFIG_FILE_NAME = "listViewConfig-default.xml";
|
||||||
|
|
||||||
|
/* NB The default post-processor is not the same as the post-processor for the default view. The latter
|
||||||
|
* actually defines its own post-processor, whereas the default post-processor is used for custom views
|
||||||
|
* that don't define a post-processor, to ensure that the standard post-processing applies.
|
||||||
|
*
|
||||||
|
* edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DefaultObjectPropertyDataPostProcessor
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO Lump these together into the PropertyListConfigContext
|
||||||
|
private final ObjectPropertyTemplateModel optm;
|
||||||
|
private final VitroRequest vreq;
|
||||||
|
|
||||||
|
private boolean isDefaultConfig;
|
||||||
|
private Set<String> constructQueries;
|
||||||
|
private String selectQuery;
|
||||||
|
private String templateName;
|
||||||
|
private ObjectPropertyDataPostProcessor postprocessor; // never null
|
||||||
|
|
||||||
|
public PropertyListConfig(ObjectPropertyTemplateModel optm, VitroRequest vreq, ObjectProperty op, boolean editing)
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
|
||||||
|
this.optm = optm;
|
||||||
|
this.vreq = vreq;
|
||||||
|
WebappDaoFactory wadf = vreq.getWebappDaoFactory();
|
||||||
|
|
||||||
|
// Get the custom config filename
|
||||||
|
String configFileName = wadf.getObjectPropertyDao().getCustomListViewConfigFileName(op);
|
||||||
|
if (configFileName == null) { // no custom config; use default config
|
||||||
|
configFileName = DEFAULT_CONFIG_FILE_NAME;
|
||||||
|
}
|
||||||
|
log.debug("Using list view config file " + configFileName + " for object property " + op.getURI());
|
||||||
|
|
||||||
|
String configFilePath = getConfigFilePath(configFileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
File config = new File(configFilePath);
|
||||||
|
if ( ! isDefaultConfig(configFileName) && ! config.exists() ) {
|
||||||
|
log.warn("Can't find config file " + configFilePath + " for object property " + op.getURI() + "\n" +
|
||||||
|
". Using default config file instead.");
|
||||||
|
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE_NAME);
|
||||||
|
// Should we test for the existence of the default, and throw an error if it doesn't exist?
|
||||||
|
}
|
||||||
|
setValuesFromConfigFile(configFilePath, wadf, editing);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error processing config file " + configFilePath + " for object property " + op.getURI(), e);
|
||||||
|
// What should we do here?
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! isDefaultConfig(configFileName) ) {
|
||||||
|
ConfigError configError = checkConfiguration();
|
||||||
|
if ( configError != null ) { // the configuration contains an error
|
||||||
|
// If this is a collated property, throw an error: this results in creating an
|
||||||
|
// UncollatedPropertyTemplateModel instead.
|
||||||
|
if (optm instanceof CollatedObjectPropertyTemplateModel) {
|
||||||
|
throw new InvalidConfigurationException(configError.getMessage());
|
||||||
|
}
|
||||||
|
// Otherwise, switch to the default config
|
||||||
|
log.warn("Invalid list view config for object property " + op.getURI() +
|
||||||
|
" in " + configFilePath + ":\n" +
|
||||||
|
configError + " Using default config instead.");
|
||||||
|
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE_NAME);
|
||||||
|
setValuesFromConfigFile(configFilePath, wadf, editing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isDefaultConfig = isDefaultConfig(configFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDefaultConfig(String configFileName) {
|
||||||
|
return configFileName.equals(DEFAULT_CONFIG_FILE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigError checkConfiguration() {
|
||||||
|
|
||||||
|
ConfigError error = optm.checkQuery(selectQuery);
|
||||||
|
if (error != null) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(selectQuery)) {
|
||||||
|
return ConfigError.NO_SELECT_QUERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( StringUtils.isBlank(templateName)) {
|
||||||
|
return ConfigError.NO_TEMPLATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration fmConfig = (Configuration) vreq.getAttribute("freemarkerConfig");
|
||||||
|
TemplateLoader tl = fmConfig.getTemplateLoader();
|
||||||
|
try {
|
||||||
|
if ( tl.findTemplateSource(templateName) == null ) {
|
||||||
|
return ConfigError.TEMPLATE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error finding template " + templateName, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setValuesFromConfigFile(String configFilePath, WebappDaoFactory wdf,
|
||||||
|
boolean editing) {
|
||||||
|
try {
|
||||||
|
FileReader reader = new FileReader(configFilePath);
|
||||||
|
CustomListViewConfigFile configFileContents = new CustomListViewConfigFile(reader);
|
||||||
|
|
||||||
|
boolean collated = optm instanceof CollatedObjectPropertyTemplateModel;
|
||||||
|
|
||||||
|
selectQuery = configFileContents.getSelectQuery(collated, editing);
|
||||||
|
templateName = configFileContents.getTemplateName();
|
||||||
|
constructQueries = configFileContents.getConstructQueries();
|
||||||
|
|
||||||
|
String postprocessorName = configFileContents.getPostprocessorName();
|
||||||
|
postprocessor = getPostProcessor(postprocessorName, optm, wdf, configFilePath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error processing config file " + configFilePath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObjectPropertyDataPostProcessor getPostProcessor(
|
||||||
|
String className,
|
||||||
|
ObjectPropertyTemplateModel optm,
|
||||||
|
WebappDaoFactory wdf, String configFilePath) {
|
||||||
|
try {
|
||||||
|
if (StringUtils.isBlank(className)) {
|
||||||
|
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> clazz = Class.forName(className);
|
||||||
|
Constructor<?> constructor = clazz.getConstructor(ObjectPropertyTemplateModel.class, WebappDaoFactory.class);
|
||||||
|
return (ObjectPropertyDataPostProcessor) constructor.newInstance(optm, wdf);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
log.warn("Error processing config file '" + configFilePath
|
||||||
|
+ "': can't load postprocessor class '" + className
|
||||||
|
+ "'. " + "Using default postprocessor.", e);
|
||||||
|
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
log.warn("Error processing config file '" + configFilePath
|
||||||
|
+ "': postprocessor class '" + className
|
||||||
|
+ "' does not have a constructor that takes "
|
||||||
|
+ "ObjectPropertyTemplateModel and WebappDaoFactory. "
|
||||||
|
+ "Using default postprocessor.", e);
|
||||||
|
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
log.warn("Error processing config file '" + configFilePath
|
||||||
|
+ "': postprocessor class '" + className + "' does "
|
||||||
|
+ "not implement ObjectPropertyDataPostProcessor. "
|
||||||
|
+ "Using default postprocessor.", e);
|
||||||
|
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("Error processing config file '" + configFilePath
|
||||||
|
+ "': can't create postprocessor instance of class '"
|
||||||
|
+ className + "'. " + "Using default postprocessor.", e);
|
||||||
|
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getConfigFilePath(String filename) {
|
||||||
|
return vreq.getSession().getServletContext().getRealPath(CONFIG_FILE_PATH + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSelectQuery() {
|
||||||
|
return this.selectQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getConstructQueries() {
|
||||||
|
return this.constructQueries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemplateName() {
|
||||||
|
return this.templateName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDefaultListView() {
|
||||||
|
return this.isDefaultConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectPropertyDataPostProcessor getPostprocessor() {
|
||||||
|
return this.postprocessor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
|
||||||
|
|
||||||
public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
|
public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
|
||||||
return subclasses.isEmpty();
|
return subclasses.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigError checkQuery(String queryString) {
|
public ConfigError checkQuery(String queryString) {
|
||||||
|
|
||||||
if (StringUtils.isBlank(queryString)) {
|
if (StringUtils.isBlank(queryString)) {
|
||||||
return ConfigError.NO_SELECT_QUERY;
|
return ConfigError.NO_SELECT_QUERY;
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -31,10 +27,8 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.ParamMa
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyStatementDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.CustomListViewConfigFile;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.PropertyListConfig;
|
||||||
import freemarker.cache.TemplateLoader;
|
|
||||||
import freemarker.template.Configuration;
|
|
||||||
|
|
||||||
public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel {
|
public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel {
|
||||||
|
|
||||||
|
@ -59,7 +53,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
// ?subject ?property ?\w+
|
// ?subject ?property ?\w+
|
||||||
Pattern.compile("\\?" + KEY_SUBJECT + "\\s+\\?" + KEY_PROPERTY + "\\s+\\?(\\w+)");
|
Pattern.compile("\\?" + KEY_SUBJECT + "\\s+\\?" + KEY_PROPERTY + "\\s+\\?(\\w+)");
|
||||||
|
|
||||||
protected static enum ConfigError {
|
public static enum ConfigError {
|
||||||
NO_SELECT_QUERY("Missing select query specification"),
|
NO_SELECT_QUERY("Missing select query specification"),
|
||||||
NO_SUBCLASS_SELECT("Query does not select a subclass variable"),
|
NO_SUBCLASS_SELECT("Query does not select a subclass variable"),
|
||||||
NO_SUBCLASS_ORDER_BY("Query does not sort first by subclass variable"),
|
NO_SUBCLASS_ORDER_BY("Query does not sort first by subclass variable"),
|
||||||
|
@ -93,7 +87,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
|
|
||||||
// Get the config for this object property
|
// Get the config for this object property
|
||||||
try {
|
try {
|
||||||
config = new PropertyListConfig(op, editing);
|
config = new PropertyListConfig(this, vreq, op, editing);
|
||||||
} catch (InvalidConfigurationException e) {
|
} catch (InvalidConfigurationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -146,7 +140,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
return Route.OBJECT_PROPERTY_EDIT;
|
return Route.OBJECT_PROPERTY_EDIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigError checkQuery(String queryString) {
|
public ConfigError checkQuery(String queryString) {
|
||||||
if (StringUtils.isBlank(queryString)) {
|
if (StringUtils.isBlank(queryString)) {
|
||||||
return ConfigError.NO_SELECT_QUERY;
|
return ConfigError.NO_SELECT_QUERY;
|
||||||
}
|
}
|
||||||
|
@ -154,19 +148,19 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSelectQuery() {
|
private String getSelectQuery() {
|
||||||
return config.selectQuery;
|
return config.getSelectQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> getConstructQueries() {
|
private Set<String> getConstructQueries() {
|
||||||
return config.constructQueries;
|
return config.getConstructQueries();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getTemplateName() {
|
protected String getTemplateName() {
|
||||||
return config.templateName;
|
return config.getTemplateName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean hasDefaultListView() {
|
protected boolean hasDefaultListView() {
|
||||||
return config.isDefaultConfig;
|
return config.isDefaultListView();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String getImageUploadUrl(String subjectUri, String action) {
|
protected static String getImageUploadUrl(String subjectUri, String action) {
|
||||||
|
@ -227,14 +221,8 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
logData(data);
|
logData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectPropertyDataPostProcessor postprocessor = config.postprocessor;
|
ObjectPropertyDataPostProcessor postprocessor = config.getPostprocessor();
|
||||||
if (postprocessor == null) {
|
|
||||||
log.debug("No postprocessor for property " + getUri());
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
log.debug("Using postprocessor " + postprocessor.getClass().getName() + " for property " + getUri());
|
log.debug("Using postprocessor " + postprocessor.getClass().getName() + " for property " + getUri());
|
||||||
}
|
|
||||||
|
|
||||||
postprocessor.process(data);
|
postprocessor.process(data);
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
|
@ -331,174 +319,6 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
return objectKey;
|
return objectKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PropertyListConfig {
|
|
||||||
|
|
||||||
private static final String CONFIG_FILE_PATH = "/config/";
|
|
||||||
private static final String DEFAULT_CONFIG_FILE_NAME = "listViewConfig-default.xml";
|
|
||||||
|
|
||||||
/* NB The default post-processor is not the same as the post-processor for the default view. The latter
|
|
||||||
* actually defines its own post-processor, whereas the default post-processor is used for custom views
|
|
||||||
* that don't define a post-processor, to ensure that the standard post-processing applies.
|
|
||||||
*
|
|
||||||
* edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.DefaultObjectPropertyDataPostProcessor
|
|
||||||
*/
|
|
||||||
|
|
||||||
private boolean isDefaultConfig;
|
|
||||||
private Set<String> constructQueries;
|
|
||||||
private String selectQuery;
|
|
||||||
private String templateName;
|
|
||||||
private ObjectPropertyDataPostProcessor postprocessor = null;
|
|
||||||
|
|
||||||
PropertyListConfig(ObjectProperty op, boolean editing)
|
|
||||||
throws InvalidConfigurationException {
|
|
||||||
|
|
||||||
// Get the custom config filename
|
|
||||||
String configFileName = vreq.getWebappDaoFactory().getObjectPropertyDao().getCustomListViewConfigFileName(op);
|
|
||||||
if (configFileName == null) { // no custom config; use default config
|
|
||||||
configFileName = DEFAULT_CONFIG_FILE_NAME;
|
|
||||||
}
|
|
||||||
log.debug("Using list view config file " + configFileName + " for object property " + op.getURI());
|
|
||||||
|
|
||||||
String configFilePath = getConfigFilePath(configFileName);
|
|
||||||
|
|
||||||
try {
|
|
||||||
File config = new File(configFilePath);
|
|
||||||
if ( ! isDefaultConfig(configFileName) && ! config.exists() ) {
|
|
||||||
log.warn("Can't find config file " + configFilePath + " for object property " + op.getURI() + "\n" +
|
|
||||||
". Using default config file instead.");
|
|
||||||
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE_NAME);
|
|
||||||
// Should we test for the existence of the default, and throw an error if it doesn't exist?
|
|
||||||
}
|
|
||||||
setValuesFromConfigFile(configFilePath, vreq.getWebappDaoFactory(), editing);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error processing config file " + configFilePath + " for object property " + op.getURI(), e);
|
|
||||||
// What should we do here?
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! isDefaultConfig(configFileName) ) {
|
|
||||||
ConfigError configError = checkConfiguration();
|
|
||||||
if ( configError != null ) { // the configuration contains an error
|
|
||||||
// If this is a collated property, throw an error: this results in creating an
|
|
||||||
// UncollatedPropertyTemplateModel instead.
|
|
||||||
if (ObjectPropertyTemplateModel.this instanceof CollatedObjectPropertyTemplateModel) {
|
|
||||||
throw new InvalidConfigurationException(configError.getMessage());
|
|
||||||
}
|
|
||||||
// Otherwise, switch to the default config
|
|
||||||
log.warn("Invalid list view config for object property " + op.getURI() +
|
|
||||||
" in " + configFilePath + ":\n" +
|
|
||||||
configError + " Using default config instead.");
|
|
||||||
configFilePath = getConfigFilePath(DEFAULT_CONFIG_FILE_NAME);
|
|
||||||
setValuesFromConfigFile(configFilePath, vreq.getWebappDaoFactory(), editing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isDefaultConfig = isDefaultConfig(configFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDefaultConfig(String configFileName) {
|
|
||||||
return configFileName.equals(DEFAULT_CONFIG_FILE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConfigError checkConfiguration() {
|
|
||||||
|
|
||||||
ConfigError error = ObjectPropertyTemplateModel.this.checkQuery(selectQuery);
|
|
||||||
if (error != null) {
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isBlank(selectQuery)) {
|
|
||||||
return ConfigError.NO_SELECT_QUERY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( StringUtils.isBlank(templateName)) {
|
|
||||||
return ConfigError.NO_TEMPLATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration fmConfig = (Configuration) vreq.getAttribute("freemarkerConfig");
|
|
||||||
TemplateLoader tl = fmConfig.getTemplateLoader();
|
|
||||||
try {
|
|
||||||
if ( tl.findTemplateSource(templateName) == null ) {
|
|
||||||
return ConfigError.TEMPLATE_NOT_FOUND;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
log.error("Error finding template " + templateName, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setValuesFromConfigFile(String configFilePath, WebappDaoFactory wdf,
|
|
||||||
boolean editing) {
|
|
||||||
try {
|
|
||||||
FileReader reader = new FileReader(configFilePath);
|
|
||||||
CustomListViewConfigFile configFileContents = new CustomListViewConfigFile(reader);
|
|
||||||
|
|
||||||
boolean collated = ObjectPropertyTemplateModel.this instanceof CollatedObjectPropertyTemplateModel;
|
|
||||||
|
|
||||||
selectQuery = configFileContents.getSelectQuery(collated, editing);
|
|
||||||
templateName = configFileContents.getTemplateName();
|
|
||||||
constructQueries = configFileContents.getConstructQueries();
|
|
||||||
|
|
||||||
String postprocessorName = configFileContents.getPostprocessorName();
|
|
||||||
postprocessor = getPostProcessor(postprocessorName, ObjectPropertyTemplateModel.this, wdf, configFilePath);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error processing config file " + configFilePath, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ObjectPropertyDataPostProcessor getPostProcessor(
|
|
||||||
String className,
|
|
||||||
ObjectPropertyTemplateModel optm,
|
|
||||||
WebappDaoFactory wdf, String configFilePath) {
|
|
||||||
try {
|
|
||||||
if (StringUtils.isBlank(className)) {
|
|
||||||
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> clazz = Class.forName(className);
|
|
||||||
Constructor<?> constructor = clazz.getConstructor(ObjectPropertyTemplateModel.class, WebappDaoFactory.class);
|
|
||||||
return (ObjectPropertyDataPostProcessor) constructor.newInstance(optm, wdf);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
log.warn("Error processing config file '" + configFilePath
|
|
||||||
+ "': can't load postprocessor class '" + className
|
|
||||||
+ "'. " + "Using default postprocessor.", e);
|
|
||||||
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
log.warn("Error processing config file '" + configFilePath
|
|
||||||
+ "': postprocessor class '" + className
|
|
||||||
+ "' does not have a constructor that takes "
|
|
||||||
+ "ObjectPropertyTemplateModel and WebappDaoFactory. "
|
|
||||||
+ "Using default postprocessor.", e);
|
|
||||||
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
log.warn("Error processing config file '" + configFilePath
|
|
||||||
+ "': postprocessor class '" + className + "' does "
|
|
||||||
+ "not implement ObjectPropertyDataPostProcessor. "
|
|
||||||
+ "Using default postprocessor.", e);
|
|
||||||
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("Error processing config file '" + configFilePath
|
|
||||||
+ "': can't create postprocessor instance of class '"
|
|
||||||
+ className + "'. " + "Using default postprocessor.", e);
|
|
||||||
return new DefaultObjectPropertyDataPostProcessor(optm, wdf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getConfigFilePath(String filename) {
|
|
||||||
return servletContext.getRealPath(CONFIG_FILE_PATH + filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class InvalidConfigurationException extends Exception {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
protected InvalidConfigurationException(String s) {
|
|
||||||
super(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Template properties */
|
/* Template properties */
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
|
@ -506,7 +326,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTemplate() {
|
public String getTemplate() {
|
||||||
return config.templateName;
|
return getTemplateName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean isCollatedBySubclass();
|
public abstract boolean isCollatedBySubclass();
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
|
||||||
|
|
||||||
public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
|
public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateModel {
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@ import org.junit.matchers.JUnitMatchers;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.CustomListViewConfigFile;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.CustomListViewConfigFile.InvalidConfigFileException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: when testing, an "empty" element may be self-closing, or with
|
* Note: when testing, an "empty" element may be self-closing, or with
|
||||||
|
@ -59,19 +57,19 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readerIsNull() throws InvalidConfigFileException {
|
public void readerIsNull() throws InvalidConfigurationException {
|
||||||
expectException("Config file reader is null.");
|
expectException("Config file reader is null.");
|
||||||
configFile = new CustomListViewConfigFile(null);
|
configFile = new CustomListViewConfigFile(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void readerThrowsIOException() throws InvalidConfigFileException {
|
public void readerThrowsIOException() throws InvalidConfigurationException {
|
||||||
expectException("Unable to read config file.");
|
expectException("Unable to read config file.");
|
||||||
configFile = new CustomListViewConfigFile(new ExplodingReader());
|
configFile = new CustomListViewConfigFile(new ExplodingReader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void invalidXml() throws InvalidConfigFileException {
|
public void invalidXml() throws InvalidConfigurationException {
|
||||||
suppressSyserr(); // catch the error report from the XML parser
|
suppressSyserr(); // catch the error report from the XML parser
|
||||||
expectException(JUnitMatchers
|
expectException(JUnitMatchers
|
||||||
.containsString("Config file is not valid XML:"));
|
.containsString("Config file is not valid XML:"));
|
||||||
|
@ -79,14 +77,14 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectQueryMissing() throws InvalidConfigFileException {
|
public void selectQueryMissing() throws InvalidConfigurationException {
|
||||||
expectException("Config file must contain a query-select element");
|
expectException("Config file must contain a query-select element");
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<template>template.ftl</template>" + "</list-view-config>");
|
+ "<template>template.ftl</template>" + "</list-view-config>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectQueryMultiple() throws InvalidConfigFileException {
|
public void selectQueryMultiple() throws InvalidConfigurationException {
|
||||||
expectException("Config file may not contain more than one query-select element");
|
expectException("Config file may not contain more than one query-select element");
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
|
@ -95,21 +93,21 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectQueryEmpty() throws InvalidConfigFileException {
|
public void selectQueryEmpty() throws InvalidConfigurationException {
|
||||||
expectException("In a config file, the <query-select> element must not be empty.");
|
expectException("In a config file, the <query-select> element must not be empty.");
|
||||||
readConfigFile("<list-view-config>" + "<query-select/>"
|
readConfigFile("<list-view-config>" + "<query-select/>"
|
||||||
+ "<template>template.ftl</template>" + "</list-view-config>");
|
+ "<template>template.ftl</template>" + "</list-view-config>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void templateNameMissing() throws InvalidConfigFileException {
|
public void templateNameMissing() throws InvalidConfigurationException {
|
||||||
expectException("Config file must contain a template element");
|
expectException("Config file must contain a template element");
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>" + "</list-view-config>");
|
+ "<query-select>SELECT</query-select>" + "</list-view-config>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void templateNameMultiple() throws InvalidConfigFileException {
|
public void templateNameMultiple() throws InvalidConfigurationException {
|
||||||
expectException("Config file may not contain more than one template element");
|
expectException("Config file may not contain more than one template element");
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
|
@ -118,7 +116,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void templateNameEmpty() throws InvalidConfigFileException {
|
public void templateNameEmpty() throws InvalidConfigurationException {
|
||||||
expectException("In a config file, the <template> element must not be empty.");
|
expectException("In a config file, the <template> element must not be empty.");
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
|
@ -126,7 +124,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postprocessorNameMultiple() throws InvalidConfigFileException {
|
public void postprocessorNameMultiple() throws InvalidConfigurationException {
|
||||||
expectException("Config file may not contain more than one postprocessor element");
|
expectException("Config file may not contain more than one postprocessor element");
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
|
@ -140,7 +138,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void minimalSuccess() throws InvalidConfigFileException {
|
public void minimalSuccess() throws InvalidConfigurationException {
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
+ "<template>template.ftl</template>" + "</list-view-config>");
|
+ "<template>template.ftl</template>" + "</list-view-config>");
|
||||||
|
@ -149,7 +147,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void maximalSuccess() throws InvalidConfigFileException {
|
public void maximalSuccess() throws InvalidConfigurationException {
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
+ "<query-construct>CONSTRUCT ONE</query-construct>"
|
+ "<query-construct>CONSTRUCT ONE</query-construct>"
|
||||||
|
@ -163,7 +161,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void postprocessorEmptyIsOK() throws InvalidConfigFileException {
|
public void postprocessorEmptyIsOK() throws InvalidConfigurationException {
|
||||||
readConfigFile("<list-view-config>"
|
readConfigFile("<list-view-config>"
|
||||||
+ "<query-select>SELECT</query-select>"
|
+ "<query-select>SELECT</query-select>"
|
||||||
+ "<query-construct>CONSTRUCT</query-construct>"
|
+ "<query-construct>CONSTRUCT</query-construct>"
|
||||||
|
@ -174,28 +172,28 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectCollatedEditing() throws InvalidConfigFileException {
|
public void selectCollatedEditing() throws InvalidConfigurationException {
|
||||||
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
||||||
assertConfigFile(true, true, "SELECT collated1 collated2 ", constructs(),
|
assertConfigFile(true, true, "SELECT collated1 collated2 ", constructs(),
|
||||||
"template.ftl", "");
|
"template.ftl", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectCollatedNotEditing() throws InvalidConfigFileException {
|
public void selectCollatedNotEditing() throws InvalidConfigurationException {
|
||||||
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
||||||
assertConfigFile(true, false, "SELECT collated1 collated2 critical",
|
assertConfigFile(true, false, "SELECT collated1 collated2 critical",
|
||||||
constructs(), "template.ftl", "");
|
constructs(), "template.ftl", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectNotCollatedEditing() throws InvalidConfigFileException {
|
public void selectNotCollatedEditing() throws InvalidConfigurationException {
|
||||||
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
||||||
assertConfigFile(false, true, "SELECT ", constructs(),
|
assertConfigFile(false, true, "SELECT ", constructs(),
|
||||||
"template.ftl", "");
|
"template.ftl", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectNotCollatedNotEditing() throws InvalidConfigFileException {
|
public void selectNotCollatedNotEditing() throws InvalidConfigurationException {
|
||||||
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
readConfigFile(XML_WITH_RICH_SELECT_CLAUSE);
|
||||||
assertConfigFile(false, false, "SELECT critical", constructs(),
|
assertConfigFile(false, false, "SELECT critical", constructs(),
|
||||||
"template.ftl", "");
|
"template.ftl", "");
|
||||||
|
@ -215,17 +213,17 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private void expectException(String message) {
|
private void expectException(String message) {
|
||||||
thrown.expect(InvalidConfigFileException.class);
|
thrown.expect(InvalidConfigurationException.class);
|
||||||
thrown.expectMessage(message);
|
thrown.expectMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectException(Matcher<String> matcher) {
|
private void expectException(Matcher<String> matcher) {
|
||||||
thrown.expect(InvalidConfigFileException.class);
|
thrown.expect(InvalidConfigurationException.class);
|
||||||
thrown.expectMessage(matcher);
|
thrown.expectMessage(matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readConfigFile(String xmlString)
|
private void readConfigFile(String xmlString)
|
||||||
throws InvalidConfigFileException {
|
throws InvalidConfigurationException {
|
||||||
StringReader reader = new StringReader(xmlString);
|
StringReader reader = new StringReader(xmlString);
|
||||||
configFile = new CustomListViewConfigFile(reader);
|
configFile = new CustomListViewConfigFile(reader);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.log4j.Level;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
@ -39,7 +38,8 @@ import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
||||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel.InvalidConfigurationException;
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.InvalidConfigurationException;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview.PropertyListConfig;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
|
|
||||||
public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
|
@ -204,7 +204,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
throws InvalidConfigurationException {
|
throws InvalidConfigurationException {
|
||||||
// TODO if we can't translate the path, log the error and use the
|
// TODO if we can't translate the path, log the error and use the
|
||||||
// default.
|
// default.
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
op = buildOperation("fileHasNoRealPath");
|
op = buildOperation("fileHasNoRealPath");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void configFileNotFound() throws InvalidConfigurationException {
|
public void configFileNotFound() throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("configFileDoesNotExist");
|
op = buildOperation("configFileDoesNotExist");
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
@Test
|
@Test
|
||||||
public void configFileNotValidXml() throws InvalidConfigurationException {
|
public void configFileNotValidXml() throws InvalidConfigurationException {
|
||||||
suppressSyserr();
|
suppressSyserr();
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("notValidXml");
|
op = buildOperation("notValidXml");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -248,7 +248,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
@Test
|
@Test
|
||||||
public void selectQueryNodeIsNotFound()
|
public void selectQueryNodeIsNotFound()
|
||||||
throws InvalidConfigurationException {
|
throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("selectQueryNodeNotFound");
|
op = buildOperation("selectQueryNodeNotFound");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -259,7 +259,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void selectQueryNodeIsBlank() throws InvalidConfigurationException {
|
public void selectQueryNodeIsBlank() throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("selectQueryNodeBlank");
|
op = buildOperation("selectQueryNodeBlank");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -273,7 +273,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
//
|
//
|
||||||
@Test
|
@Test
|
||||||
public void templateNodeNotFound() throws InvalidConfigurationException {
|
public void templateNodeNotFound() throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("templateNodeNotFound");
|
op = buildOperation("templateNodeNotFound");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -284,7 +284,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void templateNodeIsEmpty() throws InvalidConfigurationException {
|
public void templateNodeIsEmpty() throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("templateNodeIsEmpty");
|
op = buildOperation("templateNodeIsEmpty");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -295,7 +295,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void templateDoesNotExist() throws InvalidConfigurationException {
|
public void templateDoesNotExist() throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("templateDoesNotExist");
|
op = buildOperation("templateDoesNotExist");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -414,7 +414,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
@Test
|
@Test
|
||||||
public void postProcessorClassNotFound()
|
public void postProcessorClassNotFound()
|
||||||
throws InvalidConfigurationException {
|
throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("postProcessorClassNotFound");
|
op = buildOperation("postProcessorClassNotFound");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -428,7 +428,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
@Test
|
@Test
|
||||||
public void postProcessorClassIsNotSuitable()
|
public void postProcessorClassIsNotSuitable()
|
||||||
throws InvalidConfigurationException {
|
throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("postProcessorClassNotSuitable");
|
op = buildOperation("postProcessorClassNotSuitable");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -442,7 +442,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
@Test
|
@Test
|
||||||
public void postProcessorClassHasWrongConstructor()
|
public void postProcessorClassHasWrongConstructor()
|
||||||
throws InvalidConfigurationException {
|
throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("postProcessorWrongConstructor");
|
op = buildOperation("postProcessorWrongConstructor");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -456,7 +456,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
@Test
|
@Test
|
||||||
public void postProcessorConstructorThrowsAnException()
|
public void postProcessorConstructorThrowsAnException()
|
||||||
throws InvalidConfigurationException {
|
throws InvalidConfigurationException {
|
||||||
captureLogsFromOPTM();
|
captureLogsFromPropertyListConfig();
|
||||||
|
|
||||||
op = buildOperation("postProcessorConstructorThrowsException");
|
op = buildOperation("postProcessorConstructorThrowsException");
|
||||||
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
@ -498,11 +498,10 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capture the log for ObjectPropertyTemplateModel and suppress it from the
|
* Capture the log for PropertyListConfig and suppress it from the console.
|
||||||
* console.
|
|
||||||
*/
|
*/
|
||||||
private void captureLogsFromOPTM() {
|
private void captureLogsFromPropertyListConfig() {
|
||||||
captureLogOutput(ObjectPropertyTemplateModel.class, logMessages, true);
|
captureLogOutput(PropertyListConfig.class, logMessages, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertLogMessagesContains(String message, String expected) {
|
private void assertLogMessagesContains(String message, String expected) {
|
||||||
|
@ -548,17 +547,10 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
Field configField = ObjectPropertyTemplateModel.class
|
Field configField = ObjectPropertyTemplateModel.class
|
||||||
.getDeclaredField("config");
|
.getDeclaredField("config");
|
||||||
configField.setAccessible(true);
|
configField.setAccessible(true);
|
||||||
Object config = configField.get(optm);
|
PropertyListConfig config = (PropertyListConfig) configField
|
||||||
|
.get(optm);
|
||||||
Class<?> configClass = Class
|
|
||||||
.forName("edu.cornell.mannlib.vitro.webapp.web."
|
|
||||||
+ "templatemodels.individual."
|
|
||||||
+ "ObjectPropertyTemplateModel$PropertyListConfig");
|
|
||||||
|
|
||||||
Field ppField = configClass.getDeclaredField("postprocessor");
|
|
||||||
ppField.setAccessible(true);
|
|
||||||
Object pp = ppField.get(config);
|
|
||||||
|
|
||||||
|
ObjectPropertyDataPostProcessor pp = config.getPostprocessor();
|
||||||
if (pp == null) {
|
if (pp == null) {
|
||||||
assertNull(message + " - postprocessor is null", expected);
|
assertNull(message + " - postprocessor is null", expected);
|
||||||
} else {
|
} else {
|
||||||
|
@ -607,7 +599,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ConfigError checkQuery(String queryString) {
|
public ConfigError checkQuery(String queryString) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue