NIHVIVO-3628 Create unit tests to cover the parsing and interpreting of custom list view config files.
This commit is contained in:
parent
3ceff9e0a5
commit
b53f26a375
26 changed files with 1282 additions and 20 deletions
|
@ -97,6 +97,24 @@ public abstract class AbstractTestClass {
|
||||||
Logger.getLogger(category).setLevel(level);
|
Logger.getLogger(category).setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capture the log for this class to this Writer. Choose whether or not to
|
||||||
|
* suppress it from the console.
|
||||||
|
*/
|
||||||
|
protected void captureLogOutput(Class<?> clazz, Writer writer,
|
||||||
|
boolean suppress) {
|
||||||
|
PatternLayout layout = new PatternLayout("%p %m%n");
|
||||||
|
|
||||||
|
ConsoleAppender appender = new ConsoleAppender();
|
||||||
|
appender.setWriter(writer);
|
||||||
|
appender.setLayout(layout);
|
||||||
|
|
||||||
|
Logger logger = Logger.getLogger(clazz);
|
||||||
|
logger.removeAllAppenders();
|
||||||
|
logger.setAdditivity(!suppress);
|
||||||
|
logger.addAppender(appender);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Control standard output or error output.
|
// Control standard output or error output.
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,683 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub;
|
||||||
|
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
|
||||||
|
import stubs.freemarker.cache.TemplateLoaderStub;
|
||||||
|
import stubs.javax.servlet.ServletContextStub;
|
||||||
|
import stubs.javax.servlet.http.HttpServletRequestStub;
|
||||||
|
import stubs.javax.servlet.http.HttpSessionStub;
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
|
||||||
|
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.BaseTemplateModel;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel.InvalidConfigurationException;
|
||||||
|
import freemarker.template.Configuration;
|
||||||
|
|
||||||
|
public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
||||||
|
AbstractTestClass {
|
||||||
|
|
||||||
|
private static File configDir;
|
||||||
|
|
||||||
|
private ObjectPropertyTemplateModel optm;
|
||||||
|
|
||||||
|
private ObjectProperty op;
|
||||||
|
|
||||||
|
private WebappDaoFactoryStub wadf;
|
||||||
|
private ObjectPropertyDaoStub opDao;
|
||||||
|
|
||||||
|
private ServletContextStub ctx;
|
||||||
|
private HttpSessionStub session;
|
||||||
|
private HttpServletRequestStub hreq;
|
||||||
|
private VitroRequest vreq;
|
||||||
|
|
||||||
|
private IndividualImpl subject;
|
||||||
|
|
||||||
|
private TemplateLoaderStub tl;
|
||||||
|
|
||||||
|
private StringWriter logMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In general, we expect no exception, but individual tests may override,
|
||||||
|
* like this:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* thrown.expect(InvalidConfigurationException.class);
|
||||||
|
* thrown.expectMessage("Bozo");
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void createConfigFiles() throws IOException {
|
||||||
|
configDir = createTempDirectory("configDir");
|
||||||
|
createConfigFile("constructQueryMissing");
|
||||||
|
createConfigFile("constructQueryMultiple");
|
||||||
|
createConfigFile("default");
|
||||||
|
createConfigFile("notValidXml");
|
||||||
|
createConfigFile("postProcessorClassNotFound");
|
||||||
|
createConfigFile("postProcessorClassNotSuitable");
|
||||||
|
createConfigFile("postProcessorConstructorThrowsException");
|
||||||
|
createConfigFile("postProcessorNameEmpty");
|
||||||
|
createConfigFile("postProcessorOK");
|
||||||
|
createConfigFile("postProcessorWrongConstructor");
|
||||||
|
createConfigFile("selectQueryNodeBlank");
|
||||||
|
createConfigFile("selectQueryNodeNotFound");
|
||||||
|
createConfigFile("selectQuerySubNodes");
|
||||||
|
createConfigFile("selectQueryNoSubNodes");
|
||||||
|
createConfigFile("selectQueryCollatedValid");
|
||||||
|
createConfigFile("selectQueryCollatedNoSelect");
|
||||||
|
createConfigFile("selectQueryCollatedNoOrder");
|
||||||
|
createConfigFile("templateNodeIsEmpty");
|
||||||
|
createConfigFile("templateNodeNotFound");
|
||||||
|
createConfigFile("templateDoesNotExist");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Copy a file from the classpath into the temporary config directory. */
|
||||||
|
private static void createConfigFile(String shortName) throws IOException {
|
||||||
|
String fullName = "testConfig-" + shortName + ".xml";
|
||||||
|
Class<?> clazz = ObjectPropertyTemplateModel_PropertyListConfigTest.class;
|
||||||
|
String contents = readAll(clazz.getResourceAsStream(fullName));
|
||||||
|
createFile(configDir, fullName, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
logMessages = new StringWriter();
|
||||||
|
|
||||||
|
opDao = new ObjectPropertyDaoStub();
|
||||||
|
wadf = new WebappDaoFactoryStub();
|
||||||
|
wadf.setObjectPropertyDao(opDao);
|
||||||
|
|
||||||
|
ctx = new ServletContextStub();
|
||||||
|
// create paths for all of the files in the temporary config directory.
|
||||||
|
ctx.setRealPaths("/config", configDir);
|
||||||
|
// add a path to match the hard-coded default path.
|
||||||
|
ctx.setRealPath("/config/listViewConfig-default.xml",
|
||||||
|
ctx.getRealPath("/config/testConfig-default.xml"));
|
||||||
|
|
||||||
|
session = new HttpSessionStub();
|
||||||
|
session.setServletContext(ctx);
|
||||||
|
hreq = new HttpServletRequestStub();
|
||||||
|
hreq.setSession(session);
|
||||||
|
|
||||||
|
vreq = new VitroRequest(hreq);
|
||||||
|
vreq.setWebappDaoFactory(wadf);
|
||||||
|
|
||||||
|
subject = new IndividualImpl();
|
||||||
|
|
||||||
|
BaseTemplateModel.setServletContext(ctx);
|
||||||
|
|
||||||
|
Configuration fmConfig = new Configuration();
|
||||||
|
vreq.setAttribute("freemarkerConfig", fmConfig);
|
||||||
|
tl = new TemplateLoaderStub();
|
||||||
|
tl.createTemplate("propStatement-default.ftl", "");
|
||||||
|
fmConfig.setTemplateLoader(tl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void cleanup() {
|
||||||
|
if (configDir != null) {
|
||||||
|
purgeDirectoryRecursively(configDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO - don't swallow the exception if we can't create a config.
|
||||||
|
// TODO - baseTemplateModel shouldn't require the servlet context to be set
|
||||||
|
// statically!!! ServletContext shouldn't be a static field.
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// The tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//
|
||||||
|
// Null arguments
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void operationIsNull() throws InvalidConfigurationException {
|
||||||
|
// TODO This should throw a more predictable NullPointerException
|
||||||
|
optm = new NonCollatingOPTM(null, subject, vreq, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void subjectIsNull() throws InvalidConfigurationException {
|
||||||
|
// TODO This should throw a more predictable NullPointerException
|
||||||
|
op = buildOperation("default");
|
||||||
|
optm = new NonCollatingOPTM(op, null, vreq, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = NullPointerException.class)
|
||||||
|
public void requestIsNull() throws InvalidConfigurationException {
|
||||||
|
// TODO This should throw a more predictable NullPointerException
|
||||||
|
op = buildOperation("default");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locating the file.
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configFileNotSpecified() throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("default");
|
||||||
|
opDao.setCustomListViewConfigFileName(op, null);
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
assertEquals("uses default config", true, optm.hasDefaultListView());
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Ignore
|
||||||
|
@Test
|
||||||
|
public void configFilePathCantBeTranslated()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
// TODO if we can't translate the path, log the error and use the
|
||||||
|
// default.
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
op = buildOperation("fileHasNoRealPath");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
// Throws an exception because we don't test for a null path from the
|
||||||
|
// ServletContext.
|
||||||
|
assertLogMessagesContains("no real path", "at java.io.File.<init>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configFileNotFound() throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("configFileDoesNotExist");
|
||||||
|
|
||||||
|
// There should be a real path, but no file at that location.
|
||||||
|
String bogusFilepath = new File(configDir, "doesNotExist")
|
||||||
|
.getAbsolutePath();
|
||||||
|
String path = "/config/" + opDao.getCustomListViewConfigFileName(op);
|
||||||
|
ctx.setRealPath(path, bogusFilepath);
|
||||||
|
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("file not found", "Can't find config file");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configFileNotValidXml() throws InvalidConfigurationException {
|
||||||
|
suppressSyserr();
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("notValidXml");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("not valid XML", "SAXParseException");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Problems with the <query-select> node
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectQueryNodeIsNotFound()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("selectQueryNodeNotFound");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("no select query",
|
||||||
|
"Missing select query specification");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectQueryNodeIsBlank() throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("selectQueryNodeBlank");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("blank select query",
|
||||||
|
"Missing select query specification");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Problems with the <template> node
|
||||||
|
//
|
||||||
|
@Test
|
||||||
|
public void templateNodeNotFound() throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("templateNodeNotFound");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("no template node",
|
||||||
|
"Missing template specification");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void templateNodeIsEmpty() throws InvalidConfigurationException {
|
||||||
|
// TODO fix this so it doesn't throw a NullPointerException - use
|
||||||
|
// textValue() or something
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("templateNodeIsEmpty");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("empty template node",
|
||||||
|
"Missing template specification");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void templateDoesNotExist() throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("templateDoesNotExist");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
assertLogMessagesContains("template doesn't exist",
|
||||||
|
"Specified template does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Optional tags in the select query.
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectSubNodesCollatedCritical()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("selectQuerySubNodes");
|
||||||
|
optm = new SimpleCollatingOPTM(op, subject, vreq, false);
|
||||||
|
assertSelectQuery("collated, critical",
|
||||||
|
"Plain collated plain critical plain collated plain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectSubNodesCollatedUncritical()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("selectQuerySubNodes");
|
||||||
|
optm = new SimpleCollatingOPTM(op, subject, vreq, true);
|
||||||
|
assertSelectQuery("collated, UNcritical",
|
||||||
|
"Plain collated plain plain collated plain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectSubNodesUncollatedCritical()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("selectQuerySubNodes");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
assertSelectQuery("UNcollated, critical",
|
||||||
|
"Plain plain critical plain plain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectSubNodesUncollatedUncritical()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("selectQuerySubNodes");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, true);
|
||||||
|
assertSelectQuery("UNcollated, UNcritical", "Plain plain plain plain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectNoSubNodesCollatedCritical()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("selectQueryNoSubNodes");
|
||||||
|
optm = new SimpleCollatingOPTM(op, subject, vreq, false);
|
||||||
|
assertSelectQuery("simple collated, critical", "Plain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void collatedNoSubclassSelector()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
thrown.expect(InvalidConfigurationException.class);
|
||||||
|
thrown.expectMessage("Query does not select a subclass variable");
|
||||||
|
|
||||||
|
op = buildOperation("selectQueryCollatedNoSelect");
|
||||||
|
optm = new CheckingCollatingOPTM(op, subject, vreq, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void collatedNoSubclassOrder() throws InvalidConfigurationException {
|
||||||
|
thrown.expect(InvalidConfigurationException.class);
|
||||||
|
thrown.expectMessage("Query does not sort first by subclass variable");
|
||||||
|
|
||||||
|
op = buildOperation("selectQueryCollatedNoOrder");
|
||||||
|
optm = new CheckingCollatingOPTM(op, subject, vreq, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void collatedValid() throws InvalidConfigurationException {
|
||||||
|
// Throws no exception
|
||||||
|
op = buildOperation("selectQueryCollatedValid");
|
||||||
|
optm = new CheckingCollatingOPTM(op, subject, vreq, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Construct query
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void constructQueryNodeMissing()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("constructQueryMissing");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, true);
|
||||||
|
// Not an error.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void constructQueryMultipleValues()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("constructQueryMultiple");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, true);
|
||||||
|
assertConstructQueries("multiple construct queries", "ONE", "TWO",
|
||||||
|
"THREE");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PostProcessor
|
||||||
|
//
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessorNameEmpty() throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
|
||||||
|
op = buildOperation("postProcessorNameEmpty");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
// TODO This should not cause an error. If it did, it should not swallow
|
||||||
|
// the exception. It should use the default PP.
|
||||||
|
assertLogMessagesContains("pp name empty", "NullPointerException");
|
||||||
|
assertPostProcessorClass("pp name empty", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessorClassNotFound()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
setLoggerLevel(ObjectPropertyTemplateModel.class, Level.DEBUG);
|
||||||
|
|
||||||
|
op = buildOperation("postProcessorClassNotFound");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
// TODO this should log an error.
|
||||||
|
assertLogMessagesContains("pp class not found",
|
||||||
|
"Cannot find postprocessor specified");
|
||||||
|
assertPostProcessorClass("pp class not found",
|
||||||
|
DefaultObjectPropertyDataPostProcessor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessorClassIsNotSuitable()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
setLoggerLevel(ObjectPropertyTemplateModel.class, Level.DEBUG);
|
||||||
|
|
||||||
|
op = buildOperation("postProcessorClassNotSuitable");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
// TODO this should log an error.
|
||||||
|
assertLogMessagesContains("pp doesn't implement required interface",
|
||||||
|
"Cannot find postprocessor specified");
|
||||||
|
assertPostProcessorClass("pp doesn't implement required interface",
|
||||||
|
DefaultObjectPropertyDataPostProcessor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessorClassHasWrongConstructor()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
setLoggerLevel(ObjectPropertyTemplateModel.class, Level.DEBUG);
|
||||||
|
|
||||||
|
op = buildOperation("postProcessorWrongConstructor");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
// TODO this should log an error.
|
||||||
|
assertLogMessagesContains("pp has wrong constructor",
|
||||||
|
"Cannot find postprocessor specified");
|
||||||
|
assertPostProcessorClass("pp has wrong constructor",
|
||||||
|
DefaultObjectPropertyDataPostProcessor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessorConstructorThrowsAnException()
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
captureLogsFromOPTM();
|
||||||
|
setLoggerLevel(ObjectPropertyTemplateModel.class, Level.DEBUG);
|
||||||
|
|
||||||
|
op = buildOperation("postProcessorConstructorThrowsException");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
|
||||||
|
// TODO this should log an error.
|
||||||
|
assertLogMessagesContains("pp throws an exception",
|
||||||
|
"Cannot find postprocessor specified");
|
||||||
|
assertPostProcessorClass("pp throws an exception",
|
||||||
|
DefaultObjectPropertyDataPostProcessor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessorOK() throws InvalidConfigurationException {
|
||||||
|
op = buildOperation("postProcessorOK");
|
||||||
|
optm = new NonCollatingOPTM(op, subject, vreq, false);
|
||||||
|
assertPostProcessorClass("pp OK", PostProcessorOK.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up an operation with name "foobar" and adds it to the
|
||||||
|
* ObjectPropertyDaoStub.
|
||||||
|
*
|
||||||
|
* The URI will be "http://foobar", and the ListViewConfig file will be
|
||||||
|
* "testConfig-foobar.xml". That file is assumed to exist already, and to be
|
||||||
|
* mapped in the ServletContextStub.
|
||||||
|
*/
|
||||||
|
private ObjectProperty buildOperation(String name) {
|
||||||
|
ObjectProperty property = new ObjectProperty();
|
||||||
|
property.setURI("http://" + name);
|
||||||
|
|
||||||
|
opDao.addObjectProperty(property);
|
||||||
|
opDao.setCustomListViewConfigFileName(property, "testConfig-" + name
|
||||||
|
+ ".xml");
|
||||||
|
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capture the log for ObjectPropertyTemplateModel and suppress it from the
|
||||||
|
* console.
|
||||||
|
*/
|
||||||
|
private void captureLogsFromOPTM() {
|
||||||
|
captureLogOutput(ObjectPropertyTemplateModel.class, logMessages, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertLogMessagesContains(String message, String expected) {
|
||||||
|
if (logMessages.toString().contains(expected)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fail(message + "\nLOG\n" + logMessages + "\nDOES NOT CONTAIN\n"
|
||||||
|
+ expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertSelectQuery(String message, String expected) {
|
||||||
|
String actual = "BOGUS";
|
||||||
|
try {
|
||||||
|
Method m = ObjectPropertyTemplateModel.class.getDeclaredMethod(
|
||||||
|
"getSelectQuery", new Class<?>[0]);
|
||||||
|
m.setAccessible(true);
|
||||||
|
actual = (String) m.invoke(optm, new Object[0]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(message + " - " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(message, expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void assertConstructQueries(String message, String... expectedArray) {
|
||||||
|
Set<String> expected = new HashSet<String>(Arrays.asList(expectedArray));
|
||||||
|
Set<String> actual = null;
|
||||||
|
try {
|
||||||
|
Method m = ObjectPropertyTemplateModel.class.getDeclaredMethod(
|
||||||
|
"getConstructQueries", new Class<?>[0]);
|
||||||
|
m.setAccessible(true);
|
||||||
|
actual = (Set<String>) m.invoke(optm, new Object[0]);
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(message + " - " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqualSets(message, expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertPostProcessorClass(String message, Class<?> expected) {
|
||||||
|
try {
|
||||||
|
Field configField = ObjectPropertyTemplateModel.class
|
||||||
|
.getDeclaredField("config");
|
||||||
|
configField.setAccessible(true);
|
||||||
|
Object config = 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);
|
||||||
|
|
||||||
|
if (pp == null) {
|
||||||
|
assertNull(message + " - postprocessor is null", expected);
|
||||||
|
} else {
|
||||||
|
assertEquals(message, expected, pp.getClass());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
fail(message + " - " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Supporting classes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private static class NonCollatingOPTM extends ObjectPropertyTemplateModel {
|
||||||
|
NonCollatingOPTM(ObjectProperty op, Individual subject,
|
||||||
|
VitroRequest vreq, boolean editing)
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
super(op, subject, vreq, editing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isEmpty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCollatedBySubclass() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No populated properties and we don't do syntax checking on the select
|
||||||
|
* query.
|
||||||
|
*/
|
||||||
|
private static class SimpleCollatingOPTM extends
|
||||||
|
CollatedObjectPropertyTemplateModel {
|
||||||
|
SimpleCollatingOPTM(ObjectProperty op, Individual subject,
|
||||||
|
VitroRequest vreq, boolean editing)
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
super(op, subject, vreq, editing, Collections
|
||||||
|
.<ObjectProperty> emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ConfigError checkQuery(String queryString) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** No populated properties but we do check the syntax of the select query. */
|
||||||
|
private static class CheckingCollatingOPTM extends
|
||||||
|
CollatedObjectPropertyTemplateModel {
|
||||||
|
CheckingCollatingOPTM(ObjectProperty op, Individual subject,
|
||||||
|
VitroRequest vreq, boolean editing)
|
||||||
|
throws InvalidConfigurationException {
|
||||||
|
super(op, subject, vreq, editing, Collections
|
||||||
|
.<ObjectProperty> emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Does not have a constructor with the correct arguments */
|
||||||
|
public static class PostProcessorHasWrongConstructor implements
|
||||||
|
ObjectPropertyDataPostProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(List<Map<String, String>> data) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructor throws an exception */
|
||||||
|
public static class PostProcessorThrowsException implements
|
||||||
|
ObjectPropertyDataPostProcessor {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public PostProcessorThrowsException(ObjectPropertyTemplateModel optm,
|
||||||
|
WebappDaoFactory wadf) {
|
||||||
|
throw new RuntimeException("Constructor throws exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(List<Map<String, String>> data) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Acceptable postprocessor */
|
||||||
|
public static class PostProcessorOK implements
|
||||||
|
ObjectPropertyDataPostProcessor {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public PostProcessorOK(ObjectPropertyTemplateModel optm,
|
||||||
|
WebappDaoFactory wadf) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(List<Map<String, String>> data) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
No construct query. Should throw an error.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
More than one construct query.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>ONE</query-construct>
|
||||||
|
<query-construct>TWO</query-construct>
|
||||||
|
<query-construct>THREE</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Default list view configuration for unit tests in this directory.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This would be valid except for the XML error.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct/>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
postprocessor tag refers to a non-existent class.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
|
||||||
|
<postprocessor>edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel_PropertyListConfigTest$NoSuchClass</postprocessor>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
postprocessor tag refers to a class that does not implement the required interface.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
|
||||||
|
<postprocessor>edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel_PropertyListConfigTest$ClassNotSuitable</postprocessor>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
postprocessor tag refers to a class that does not implement the required interface.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
|
||||||
|
<postprocessor>edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel_PropertyListConfigTest$PostProcessorThrowsException</postprocessor>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Has a postprocessor tag with no contents. Should use the default.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
|
||||||
|
<postprocessor></postprocessor>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
postprocessor tag references an acceptable class.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
|
||||||
|
<postprocessor>edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel_PropertyListConfigTest$PostProcessorOK</postprocessor>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This postprocessor is unacceptable because it doesn't have the required constructor.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
|
||||||
|
<postprocessor>edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.ObjectPropertyTemplateModel_PropertyListConfigTest$PostProcessorWrongConstructor</postprocessor>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Config file with no subclass ordering. Should throw an error on a collated property
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>SELECT ?subclass O_R_D_E_R BY ?subclass</query-select>
|
||||||
|
<query-construct> Construct </query-construct>
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Config file with no subclass selector. Should throw an error on a collated property
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>S_E_L_E_C_T ?subclass ORDER BY ?subclass</query-select>
|
||||||
|
<query-construct> Construct </query-construct>
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Config file with subclass selector and subclass ordering. Should not throw an error on a collated property
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>SELECT ?subclass ORDER BY ?subclass</query-select>
|
||||||
|
<query-construct> Construct </query-construct>
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Test this with collated and uncollated, critical and uncritical, to insure that we don't need the nested tags.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>Plain.</query-select>
|
||||||
|
<query-construct> Construct </query-construct>
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Invalid - <query-select> is blank.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Invalid - no <query-select> node.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Test this with collated and uncollated, critical and non-critical,
|
||||||
|
to be sure that we include or omit the appropriate text.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>Plain <collated>collated </collated>plain <critical-data-required>critical </critical-data-required>plain <collated>collated </collated>plain.</query-select>
|
||||||
|
<query-construct> Construct </query-construct>
|
||||||
|
<template>propStatement-default.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Template file does not exist. Should throw an exception.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template>propStatement-doesNotExist.ftl</template>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Template node is empty - should throw an exception.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
<template/>
|
||||||
|
</list-view-config>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
No template node. Should throw an exception.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<list-view-config>
|
||||||
|
<query-select>
|
||||||
|
SELECT <collated> ?subclass </collated>
|
||||||
|
?object
|
||||||
|
WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
<collated>
|
||||||
|
?object a ?subclass.
|
||||||
|
</collated>
|
||||||
|
}
|
||||||
|
</query-select>
|
||||||
|
|
||||||
|
<query-construct>
|
||||||
|
CONSTRUCT {
|
||||||
|
?subject ?property ?object .
|
||||||
|
} WHERE {
|
||||||
|
?subject ?property ?object
|
||||||
|
}
|
||||||
|
</query-construct>
|
||||||
|
|
||||||
|
</list-view-config>
|
|
@ -26,18 +26,32 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private final Map<String, ObjectProperty> opMap = new HashMap<String, ObjectProperty>();
|
private final Map<String, ObjectProperty> opMap = new HashMap<String, ObjectProperty>();
|
||||||
|
private final Map<String, String> configFilesMap = new HashMap<String, String>();
|
||||||
|
|
||||||
public void addObjectProperty(ObjectProperty predicate) {
|
public void addObjectProperty(ObjectProperty property) {
|
||||||
if (predicate == null) {
|
if (property == null) {
|
||||||
throw new NullPointerException("predicate may not be null.");
|
throw new NullPointerException("predicate may not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String uri = predicate.getURI();
|
String uri = property.getURI();
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
throw new NullPointerException("uri may not be null.");
|
throw new NullPointerException("uri may not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
opMap.put(uri, predicate);
|
opMap.put(uri, property);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCustomListViewConfigFileName(ObjectProperty property, String filename) {
|
||||||
|
if (property == null) {
|
||||||
|
throw new NullPointerException("property may not be null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = property.getURI();
|
||||||
|
if (uri == null) {
|
||||||
|
throw new NullPointerException("uri may not be null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
configFilesMap.put(uri, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -46,9 +60,24 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI) {
|
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI) {
|
||||||
|
if (objectPropertyURI == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return opMap.get(objectPropertyURI);
|
return opMap.get(objectPropertyURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCustomListViewConfigFileName(ObjectProperty objectProperty) {
|
||||||
|
if (objectProperty == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String uri = objectProperty.getURI();
|
||||||
|
if (uri == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return configFilesMap.get(uri);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Un-implemented methods
|
// Un-implemented methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -241,10 +270,4 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
||||||
"ObjectPropertyDaoStub.getObjectPropertyList() not implemented.");
|
"ObjectPropertyDaoStub.getObjectPropertyList() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getCustomListViewConfigFileName(ObjectProperty objectProperty) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"ObjectPropertyDaoStub.getCustomListViewConfigFileName() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
||||||
private ObjectPropertyStatementDao objectPropertyStatementDao;
|
private ObjectPropertyStatementDao objectPropertyStatementDao;
|
||||||
private OntologyDao ontologyDao;
|
private OntologyDao ontologyDao;
|
||||||
private UserAccountsDao userAccountsDao;
|
private UserAccountsDao userAccountsDao;
|
||||||
|
private VClassDao vClassDao;
|
||||||
|
|
||||||
public void setDefaultNamespace(String defaultNamespace) {
|
public void setDefaultNamespace(String defaultNamespace) {
|
||||||
this.defaultNamespace = defaultNamespace;
|
this.defaultNamespace = defaultNamespace;
|
||||||
|
@ -82,6 +83,10 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
||||||
this.userAccountsDao = userAccountsDao;
|
this.userAccountsDao = userAccountsDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVClassDao(VClassDao vClassDao) {
|
||||||
|
this.vClassDao = vClassDao;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Stub methods
|
// Stub methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -130,6 +135,11 @@ return this.objectPropertyStatementDao; }
|
||||||
return this.userAccountsDao;
|
return this.userAccountsDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VClassDao getVClassDao() {
|
||||||
|
return this.vClassDao;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Un-implemented methods
|
// Un-implemented methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -194,12 +204,6 @@ return this.objectPropertyStatementDao; }
|
||||||
"WebappDaoFactory.getDatatypeDao() not implemented.");
|
"WebappDaoFactory.getDatatypeDao() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public VClassDao getVClassDao() {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"WebappDaoFactory.getVClassDao() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataPropertyStatementDao getDataPropertyStatementDao() {
|
public DataPropertyStatementDao getDataPropertyStatementDao() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
|
58
webapp/test/stubs/freemarker/cache/TemplateLoaderStub.java
vendored
Normal file
58
webapp/test/stubs/freemarker/cache/TemplateLoaderStub.java
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package stubs.freemarker.cache;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import freemarker.cache.TemplateLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple implementation where the templates are stored a strings in a map
|
||||||
|
* instead of as files, and where the "template source" objects are just the
|
||||||
|
* template names.
|
||||||
|
*/
|
||||||
|
public class TemplateLoaderStub implements TemplateLoader {
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Stub infrastructure
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private final Map<String, String> templateMap = new HashMap<String, String>();
|
||||||
|
|
||||||
|
public void createTemplate(String name, String contents) {
|
||||||
|
templateMap.put(name, contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Stub methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object findTemplateSource(String name) throws IOException {
|
||||||
|
if (templateMap.containsKey(name)) {
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeTemplateSource(Object templateSource) throws IOException {
|
||||||
|
// Nothing to close
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLastModified(Object templateSource) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Reader getReader(Object templateSource, String encoding)
|
||||||
|
throws IOException {
|
||||||
|
return new StringReader(templateMap.get(templateSource));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
package stubs.javax.servlet;
|
package stubs.javax.servlet;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -17,11 +18,14 @@ import javax.servlet.Servlet;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple stand-in for the {@link ServletContext}, for use in unit tests.
|
* A simple stand-in for the {@link ServletContext}, for use in unit tests.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class ServletContextStub implements ServletContext {
|
public class ServletContextStub implements ServletContext {
|
||||||
|
private static final Log log = LogFactory.getLog(ServletContextStub.class);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Stub infrastructure
|
// Stub infrastructure
|
||||||
|
@ -54,12 +58,26 @@ public class ServletContextStub implements ServletContext {
|
||||||
throw new NullPointerException("path may not be null.");
|
throw new NullPointerException("path may not be null.");
|
||||||
}
|
}
|
||||||
if (filepath == null) {
|
if (filepath == null) {
|
||||||
|
log.debug("removing real path for '" + path + "'");
|
||||||
realPaths.remove(path);
|
realPaths.remove(path);
|
||||||
} else {
|
} else {
|
||||||
|
log.debug("adding real path for '" + path + "' = '" + filepath
|
||||||
|
+ "'");
|
||||||
realPaths.put(path, filepath);
|
realPaths.put(path, filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call setRealPath for each of the files in this directory (non-recursive).
|
||||||
|
* Use the prefix, a separator, and the filename as the path.
|
||||||
|
*/
|
||||||
|
public void setRealPaths(String pathPrefix, File dir) {
|
||||||
|
for (File file : dir.listFiles()) {
|
||||||
|
setRealPath(pathPrefix + File.separatorChar + file.getName(),
|
||||||
|
file.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Stub methods
|
// Stub methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -104,7 +122,9 @@ public class ServletContextStub implements ServletContext {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getRealPath(String path) {
|
public String getRealPath(String path) {
|
||||||
return realPaths.get(path);
|
String real = realPaths.get(path);
|
||||||
|
log.debug("Real path for '" + path + "' is '" + real + "'");
|
||||||
|
return real;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
Loading…
Add table
Reference in a new issue