Merge pull request #65 from j2blake/feature/VIVO-1408_java-rdf-namespaces
VIVO-1408 ConfigurationBeanLoader: java rdf namespaces
This commit is contained in:
commit
07686ebdf0
11 changed files with 829 additions and 218 deletions
|
@ -8,6 +8,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -34,16 +35,42 @@ public class ConfigurationBeanLoader {
|
||||||
return JAVA_URI_PREFIX + clazz.getName();
|
return JAVA_URI_PREFIX + clazz.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String toCanonicalJavaUri(String uri) {
|
||||||
|
return uri.replace("#", ".");
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isJavaUri(String uri) {
|
public static boolean isJavaUri(String uri) {
|
||||||
return uri.startsWith(JAVA_URI_PREFIX);
|
return uri.startsWith(JAVA_URI_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String fromJavaUri(String uri) {
|
public static Set<String> toPossibleJavaUris(Class<?> clazz) {
|
||||||
if (!isJavaUri(uri)) {
|
Set<String> set = new TreeSet<>();
|
||||||
throw new IllegalArgumentException("Not a java class URI: '" + uri
|
String[] uriPieces = toJavaUri(clazz).split("\\.");
|
||||||
+ "'");
|
for (int hashIndex = 0; hashIndex < uriPieces.length; hashIndex++) {
|
||||||
|
set.add(joinWithPeriodsAndAHash(uriPieces, hashIndex));
|
||||||
}
|
}
|
||||||
return uri.substring(JAVA_URI_PREFIX.length());
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String joinWithPeriodsAndAHash(String[] pieces,
|
||||||
|
int hashIndex) {
|
||||||
|
StringBuilder buffer = new StringBuilder(pieces[0]);
|
||||||
|
for (int i = 1; i < pieces.length; i++) {
|
||||||
|
buffer.append(i == hashIndex ? '#' : '.').append(pieces[i]);
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String classnameFromJavaUri(String uri) {
|
||||||
|
if (!isJavaUri(uri)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Not a java class URI: '" + uri + "'");
|
||||||
|
}
|
||||||
|
return toCanonicalJavaUri(uri).substring(JAVA_URI_PREFIX.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMatchingJavaUri(String uri1, String uri2) {
|
||||||
|
return toCanonicalJavaUri(uri1).equals(toCanonicalJavaUri(uri2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -85,9 +112,11 @@ public class ConfigurationBeanLoader {
|
||||||
this(new LockableModel(model), req);
|
this(new LockableModel(model), req);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationBeanLoader(LockableModel locking, HttpServletRequest req) {
|
public ConfigurationBeanLoader(LockableModel locking,
|
||||||
this(locking, (req == null) ? null : req.getSession()
|
HttpServletRequest req) {
|
||||||
.getServletContext(), req);
|
this(locking,
|
||||||
|
(req == null) ? null : req.getSession().getServletContext(),
|
||||||
|
req);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigurationBeanLoader(LockableModel locking, ServletContext ctx,
|
private ConfigurationBeanLoader(LockableModel locking, ServletContext ctx,
|
||||||
|
@ -111,18 +140,18 @@ public class ConfigurationBeanLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ConfigurationRdf<T> parsedRdf = ConfigurationRdfParser.parse(
|
ConfigurationRdf<T> parsedRdf = ConfigurationRdfParser
|
||||||
locking, uri, resultClass);
|
.parse(locking, uri, resultClass);
|
||||||
WrappedInstance<T> wrapper = InstanceWrapper.wrap(parsedRdf
|
WrappedInstance<T> wrapper = InstanceWrapper
|
||||||
.getConcreteClass());
|
.wrap(parsedRdf.getConcreteClass());
|
||||||
wrapper.satisfyInterfaces(ctx, req);
|
wrapper.satisfyInterfaces(ctx, req);
|
||||||
wrapper.checkCardinality(parsedRdf.getPropertyStatements());
|
wrapper.checkCardinality(parsedRdf.getPropertyStatements());
|
||||||
wrapper.setProperties(this, parsedRdf.getPropertyStatements());
|
wrapper.setProperties(this, parsedRdf.getPropertyStatements());
|
||||||
wrapper.validate();
|
wrapper.validate();
|
||||||
return wrapper.getInstance();
|
return wrapper.getInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ConfigurationBeanLoaderException("Failed to load '" + uri
|
throw new ConfigurationBeanLoaderException(
|
||||||
+ "'", e);
|
"Failed to load '" + uri + "'", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,14 +162,16 @@ public class ConfigurationBeanLoader {
|
||||||
throws ConfigurationBeanLoaderException {
|
throws ConfigurationBeanLoaderException {
|
||||||
Set<String> uris = new HashSet<>();
|
Set<String> uris = new HashSet<>();
|
||||||
try (LockedModel m = locking.read()) {
|
try (LockedModel m = locking.read()) {
|
||||||
|
for (String typeUri : toPossibleJavaUris(resultClass)) {
|
||||||
List<Resource> resources = m.listResourcesWithProperty(RDF.type,
|
List<Resource> resources = m.listResourcesWithProperty(RDF.type,
|
||||||
createResource(toJavaUri(resultClass))).toList();
|
createResource(typeUri)).toList();
|
||||||
for (Resource r : resources) {
|
for (Resource r : resources) {
|
||||||
if (r.isURIResource()) {
|
if (r.isURIResource()) {
|
||||||
uris.add(r.getURI());
|
uris.add(r.getURI());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Set<T> instances = new HashSet<>();
|
Set<T> instances = new HashSet<>();
|
||||||
for (String uri : uris) {
|
for (String uri : uris) {
|
||||||
|
|
|
@ -2,16 +2,18 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.utils.configuration;
|
package edu.cornell.mannlib.vitro.webapp.utils.configuration;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.classnameFromJavaUri;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.isJavaUri;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.isMatchingJavaUri;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toJavaUri;
|
||||||
import static org.apache.jena.rdf.model.ResourceFactory.createResource;
|
import static org.apache.jena.rdf.model.ResourceFactory.createResource;
|
||||||
import static org.apache.jena.rdf.model.ResourceFactory.createStatement;
|
import static org.apache.jena.rdf.model.ResourceFactory.createStatement;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.fromJavaUri;
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.isJavaUri;
|
|
||||||
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toJavaUri;
|
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.jena.rdf.model.Property;
|
import org.apache.jena.rdf.model.Property;
|
||||||
|
@ -64,23 +66,30 @@ public class ConfigurationRdfParser {
|
||||||
private static void confirmEligibilityForResultClass(LockableModel locking,
|
private static void confirmEligibilityForResultClass(LockableModel locking,
|
||||||
String uri, Class<?> resultClass)
|
String uri, Class<?> resultClass)
|
||||||
throws InvalidConfigurationRdfException {
|
throws InvalidConfigurationRdfException {
|
||||||
Statement s = createStatement(createResource(uri), RDF.type,
|
String resultClassUri = toJavaUri(resultClass);
|
||||||
createResource(toJavaUri(resultClass)));
|
|
||||||
try (LockedModel m = locking.read()) {
|
try (LockedModel m = locking.read()) {
|
||||||
if (!m.contains(s)) {
|
Set<RDFNode> types = //
|
||||||
throw noTypeStatementForResultClass(s);
|
m.listObjectsOfProperty(createResource(uri), RDF.type)
|
||||||
|
.toSet();
|
||||||
|
for (RDFNode typeNode : types) {
|
||||||
|
if (typeNode.isURIResource()) {
|
||||||
|
String typeUri = typeNode.asResource().getURI();
|
||||||
|
if (isMatchingJavaUri(resultClassUri, typeUri)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw noTypeStatementForResultClass(uri, resultClassUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Set<PropertyStatement> loadProperties(LockableModel locking,
|
private static Set<PropertyStatement> loadProperties(LockableModel locking,
|
||||||
String uri) throws InvalidConfigurationRdfException {
|
String uri) throws InvalidConfigurationRdfException {
|
||||||
Set<PropertyStatement> set = new HashSet<>();
|
Set<PropertyStatement> set = new HashSet<>();
|
||||||
|
|
||||||
try (LockedModel m = locking.read()) {
|
try (LockedModel m = locking.read()) {
|
||||||
List<Statement> rawStatements = m.listStatements(
|
List<Statement> rawStatements = m.listStatements(m.getResource(uri),
|
||||||
m.getResource(uri), (Property) null, (RDFNode) null)
|
(Property) null, (RDFNode) null).toList();
|
||||||
.toList();
|
|
||||||
if (rawStatements.isEmpty()) {
|
if (rawStatements.isEmpty()) {
|
||||||
throw noRdfStatements(uri);
|
throw noRdfStatements(uri);
|
||||||
}
|
}
|
||||||
|
@ -108,8 +117,9 @@ public class ConfigurationRdfParser {
|
||||||
Set<Class<? extends T>> concreteClasses = new HashSet<>();
|
Set<Class<? extends T>> concreteClasses = new HashSet<>();
|
||||||
|
|
||||||
try (LockedModel m = locking.read()) {
|
try (LockedModel m = locking.read()) {
|
||||||
for (RDFNode node : m.listObjectsOfProperty(createResource(uri),
|
for (RDFNode node : m
|
||||||
RDF.type).toSet()) {
|
.listObjectsOfProperty(createResource(uri), RDF.type)
|
||||||
|
.toSet()) {
|
||||||
if (!node.isURIResource()) {
|
if (!node.isURIResource()) {
|
||||||
throw typeMustBeUriResource(node);
|
throw typeMustBeUriResource(node);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +150,7 @@ public class ConfigurationRdfParser {
|
||||||
if (!isJavaUri(typeUri)) {
|
if (!isJavaUri(typeUri)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Class<?> clazz = Class.forName(fromJavaUri(typeUri));
|
Class<?> clazz = Class.forName(classnameFromJavaUri(typeUri));
|
||||||
if (clazz.isInterface()) {
|
if (clazz.isInterface()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +167,7 @@ public class ConfigurationRdfParser {
|
||||||
private static <T> Class<? extends T> processTypeUri(String typeUri,
|
private static <T> Class<? extends T> processTypeUri(String typeUri,
|
||||||
Class<T> resultClass) throws InvalidConfigurationRdfException {
|
Class<T> resultClass) throws InvalidConfigurationRdfException {
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = Class.forName(fromJavaUri(typeUri));
|
Class<?> clazz = Class.forName(classnameFromJavaUri(typeUri));
|
||||||
if (!resultClass.isAssignableFrom(clazz)) {
|
if (!resultClass.isAssignableFrom(clazz)) {
|
||||||
throw notAssignable(resultClass, clazz);
|
throw notAssignable(resultClass, clazz);
|
||||||
}
|
}
|
||||||
|
@ -180,22 +190,23 @@ public class ConfigurationRdfParser {
|
||||||
"The model contains no statements about '" + uri + "'");
|
"The model contains no statements about '" + uri + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException noConcreteClasses(String uri) {
|
private static InvalidConfigurationRdfException noConcreteClasses(
|
||||||
|
String uri) {
|
||||||
return new InvalidConfigurationRdfException(
|
return new InvalidConfigurationRdfException(
|
||||||
"No concrete class is declared for '" + uri + "'");
|
"No concrete class is declared for '" + uri + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException tooManyConcreteClasses(
|
private static InvalidConfigurationRdfException tooManyConcreteClasses(
|
||||||
String uri, Set<?> concreteClasses) {
|
String uri, Set<?> concreteClasses) {
|
||||||
return new InvalidConfigurationRdfException("'" + uri
|
return new InvalidConfigurationRdfException(
|
||||||
+ "' is declared with more than one " + "concrete class: "
|
"'" + uri + "' is declared with more than one "
|
||||||
+ concreteClasses);
|
+ "concrete class: " + concreteClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException notAssignable(
|
private static InvalidConfigurationRdfException notAssignable(
|
||||||
Class<?> resultClass, Class<?> clazz) {
|
Class<?> resultClass, Class<?> clazz) {
|
||||||
return new InvalidConfigurationRdfException(clazz
|
return new InvalidConfigurationRdfException(
|
||||||
+ " cannot be assigned to " + resultClass);
|
clazz + " cannot be assigned to " + resultClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException noZeroArgumentConstructor(
|
private static InvalidConfigurationRdfException noZeroArgumentConstructor(
|
||||||
|
@ -212,8 +223,8 @@ public class ConfigurationRdfParser {
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException failedToLoadClass(
|
private static InvalidConfigurationRdfException failedToLoadClass(
|
||||||
String typeUri, Throwable e) {
|
String typeUri, Throwable e) {
|
||||||
return new InvalidConfigurationRdfException("Can't load this type: '"
|
return new InvalidConfigurationRdfException(
|
||||||
+ typeUri + "'", e);
|
"Can't load this type: '" + typeUri + "'", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException typeMustBeUriResource(
|
private static InvalidConfigurationRdfException typeMustBeUriResource(
|
||||||
|
@ -223,14 +234,17 @@ public class ConfigurationRdfParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException noTypeStatementForResultClass(
|
private static InvalidConfigurationRdfException noTypeStatementForResultClass(
|
||||||
Statement s) {
|
String uri, String resultClassUri) {
|
||||||
return new InvalidConfigurationRdfException(
|
return new InvalidConfigurationRdfException(
|
||||||
"A type statement is required: '" + s);
|
"A type statement is required: '"
|
||||||
|
+ createStatement(createResource(uri), RDF.type,
|
||||||
|
createResource(resultClassUri)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InvalidConfigurationRdfException noRdfStatements(String uri) {
|
private static InvalidConfigurationRdfException noRdfStatements(
|
||||||
return new InvalidConfigurationRdfException("'" + uri
|
String uri) {
|
||||||
+ "' does not appear as the subject of any "
|
return new InvalidConfigurationRdfException(
|
||||||
|
"'" + uri + "' does not appear as the subject of any "
|
||||||
+ "statements in the model.");
|
+ "statements in the model.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +253,8 @@ public class ConfigurationRdfParser {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InvalidConfigurationRdfException(String message, Throwable cause) {
|
public InvalidConfigurationRdfException(String message,
|
||||||
|
Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,36 @@ The principal methods are:
|
||||||
+ Search the graph for all individuals of type `resultClass`. For each such individual, call `loadInstance`.
|
+ Search the graph for all individuals of type `resultClass`. For each such individual, call `loadInstance`.
|
||||||
Return a set containing the created instances. If no individuals are found, return an empty `Set`.
|
Return a set containing the created instances. If no individuals are found, return an empty `Set`.
|
||||||
|
|
||||||
|
### Specifying Java class URIs
|
||||||
|
|
||||||
|
Java classes are specified as types in the configurations. The type URIs consist of `java:` and the fully-qualified class path and name. For example,
|
||||||
|
|
||||||
|
```
|
||||||
|
:application
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl> .
|
||||||
|
```
|
||||||
|
|
||||||
|
It would be nice to use prefixes to make URIs more readable. This doesn't
|
||||||
|
work with the scheme above, since none of the characters in the URI are valid
|
||||||
|
as delimiters of a prefix.
|
||||||
|
|
||||||
|
For this reason, the loader will also recognize a type URI if one of the periods is replaced by a hash (`#`). So, this is equivalent to the previous example (note the `#` after `webapp`):
|
||||||
|
|
||||||
|
```
|
||||||
|
:application
|
||||||
|
a <java:edu.cornell.mannlib.vitro.webapp#application.ApplicationImpl> .
|
||||||
|
```
|
||||||
|
|
||||||
|
which implies that this is equivalent also:
|
||||||
|
|
||||||
|
```
|
||||||
|
@prefix javaWebapp: <java:edu.cornell.mannlib.vitro.webapp#>
|
||||||
|
:application a javaWebapp:application.ApplicationImpl .
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
### Restrictions on instantiated classes.
|
### Restrictions on instantiated classes.
|
||||||
Each class to be instantiated must have a niladic constructor.
|
Each class to be instantiated must have a public niladic constructor.
|
||||||
|
|
||||||
### Property methods
|
### Property methods
|
||||||
When the loader encounters a data property or an object property in a description,
|
When the loader encounters a data property or an object property in a description,
|
||||||
|
@ -116,7 +144,8 @@ For example:
|
||||||
|
|
||||||
In more detail:
|
In more detail:
|
||||||
|
|
||||||
+ A class must contain exactly one method that serves each property URI in the description.
|
+ Each property URI in the description may be served by only one method in the class.
|
||||||
|
+ If a property URI in the description is not served by any method in the class, the loader will ignore that property.
|
||||||
+ The description need not include properies for all of the property methods in the class.
|
+ The description need not include properies for all of the property methods in the class.
|
||||||
+ Each property method must be public, must have exactly one parameter, and must return null.
|
+ Each property method must be public, must have exactly one parameter, and must return null.
|
||||||
+ The name of the property method is immaterial, except that there must not be another method
|
+ The name of the property method is immaterial, except that there must not be another method
|
||||||
|
@ -159,7 +188,7 @@ Again, in detail:
|
||||||
|
|
||||||
+ Each validation method must be public, must accept no parameters, and must return null.
|
+ Each validation method must be public, must accept no parameters, and must return null.
|
||||||
+ The name of the validation method is immaterial, except that there must not be another
|
+ The name of the validation method is immaterial, except that there must not be another
|
||||||
+ method with the same name in the lass.
|
+ method with the same name in the class.
|
||||||
+ Validation methods in superclasses will be called, but may not be overridden in a subclass.
|
+ Validation methods in superclasses will be called, but may not be overridden in a subclass.
|
||||||
|
|
||||||
### Life cycle
|
### Life cycle
|
||||||
|
|
|
@ -70,7 +70,8 @@ public class WrappedInstance<T> {
|
||||||
*/
|
*/
|
||||||
public void checkCardinality(Set<PropertyStatement> propertyStatements)
|
public void checkCardinality(Set<PropertyStatement> propertyStatements)
|
||||||
throws CardinalityException {
|
throws CardinalityException {
|
||||||
Map<String, Integer> statementCounts = countPropertyStatementsByPredicateUri(propertyStatements);
|
Map<String, Integer> statementCounts = countPropertyStatementsByPredicateUri(
|
||||||
|
propertyStatements);
|
||||||
for (PropertyMethod pm : propertyMethods.values()) {
|
for (PropertyMethod pm : propertyMethods.values()) {
|
||||||
Integer c = statementCounts.get(pm.getPropertyUri());
|
Integer c = statementCounts.get(pm.getPropertyUri());
|
||||||
int count = (c == null) ? 0 : c;
|
int count = (c == null) ? 0 : c;
|
||||||
|
@ -109,12 +110,11 @@ public class WrappedInstance<T> {
|
||||||
*/
|
*/
|
||||||
public void setProperties(ConfigurationBeanLoader loader,
|
public void setProperties(ConfigurationBeanLoader loader,
|
||||||
Collection<PropertyStatement> propertyStatements)
|
Collection<PropertyStatement> propertyStatements)
|
||||||
throws PropertyTypeException, NoSuchPropertyMethodException,
|
throws PropertyTypeException, ConfigurationBeanLoaderException {
|
||||||
ConfigurationBeanLoaderException {
|
|
||||||
for (PropertyStatement ps : propertyStatements) {
|
for (PropertyStatement ps : propertyStatements) {
|
||||||
PropertyMethod pm = propertyMethods.get(ps.getPredicateUri());
|
PropertyMethod pm = propertyMethods.get(ps.getPredicateUri());
|
||||||
if (pm == null) {
|
if (pm == null) {
|
||||||
throw new NoSuchPropertyMethodException(ps);
|
continue; // No method for this property? Ignore it.
|
||||||
}
|
}
|
||||||
pm.confirmCompatible(ps);
|
pm.confirmCompatible(ps);
|
||||||
|
|
||||||
|
@ -141,7 +141,8 @@ public class WrappedInstance<T> {
|
||||||
} catch (IllegalAccessException | IllegalArgumentException
|
} catch (IllegalAccessException | IllegalArgumentException
|
||||||
| InvocationTargetException e) {
|
| InvocationTargetException e) {
|
||||||
throw new ValidationFailedException(
|
throw new ValidationFailedException(
|
||||||
"Error executing validation method '" + method + "'", e);
|
"Error executing validation method '" + method + "'",
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,12 +166,6 @@ public class WrappedInstance<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class NoSuchPropertyMethodException extends Exception {
|
|
||||||
public NoSuchPropertyMethodException(PropertyStatement ps) {
|
|
||||||
super("No property method for '" + ps.getPredicateUri() + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CardinalityException extends Exception {
|
public static class CardinalityException extends Exception {
|
||||||
public CardinalityException(String message) {
|
public CardinalityException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
|
@ -2,19 +2,43 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels;
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
import freemarker.ext.beans.MethodAppearanceFineTuner;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
import freemarker.ext.beans.BeansWrapper;
|
import freemarker.ext.beans.BeansWrapper;
|
||||||
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.TemplateModel;
|
import freemarker.template.TemplateModel;
|
||||||
import freemarker.template.TemplateModelException;
|
import freemarker.template.TemplateModelException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a mechanism for Freemarker templates (main or included, parent or
|
||||||
|
* child) to add to the lists of scripts and style sheets for the current page.
|
||||||
|
*
|
||||||
|
* Each page uses 3 instances of Tags, exposed as ${scripts}, ${headScripts} and
|
||||||
|
* ${stylesheets}. A template may add a complete <script/$gt; element (for
|
||||||
|
* scripts or headScripts) or a <link> tag (for stylesheets), and these
|
||||||
|
* elements will appear at the proper location in the rendered HTML for the
|
||||||
|
* page.
|
||||||
|
*
|
||||||
|
* VIVO-1405: This process is augmented by the TagVersionInfo inner class, which
|
||||||
|
* attempts to add a "version=" query string to the URL in the supplied element.
|
||||||
|
* The version number is derived from the last-modified date of the specified
|
||||||
|
* script or stylesheet on the server. The effect is that a user's browser cache
|
||||||
|
* is effectively invalidated each time a new version of the script or
|
||||||
|
* stylesheet is deployed.
|
||||||
|
*/
|
||||||
public class Tags extends BaseTemplateModel {
|
public class Tags extends BaseTemplateModel {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(Tags.class);
|
private static final Log log = LogFactory.getLog(Tags.class);
|
||||||
|
|
||||||
protected final LinkedHashSet<String> tags;
|
protected final LinkedHashSet<String> tags;
|
||||||
|
@ -36,35 +60,44 @@ public class Tags extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Script and stylesheet lists are wrapped with a specialized BeansWrapper
|
/**
|
||||||
* that exposes certain write methods, instead of the configuration's object wrapper,
|
* Script and stylesheet lists are wrapped with a specialized BeansWrapper
|
||||||
* which doesn't. The templates can then add stylesheets and scripts to the lists
|
* that exposes certain write methods, instead of the configuration's object
|
||||||
* by calling their add() methods.
|
* wrapper, which doesn't. The templates can then add stylesheets and
|
||||||
|
* scripts to the lists by calling their add() methods.
|
||||||
|
*
|
||||||
|
* @param Tags
|
||||||
|
* tags
|
||||||
|
* @return TemplateModel
|
||||||
*/
|
*/
|
||||||
static public class TagsWrapper extends BeansWrapper {
|
static public class TagsWrapper extends BeansWrapper {
|
||||||
|
|
||||||
public TagsWrapper() {
|
public TagsWrapper() {
|
||||||
|
super(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
|
||||||
|
|
||||||
// Start by exposing all safe methods.
|
// Start by exposing all safe methods.
|
||||||
setExposureLevel(EXPOSE_SAFE);
|
setExposureLevel(EXPOSE_SAFE);
|
||||||
setMethodAppearanceFineTuner(new MethodAppearanceFineTuner() {
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public void process(MethodAppearanceDecisionInput methodAppearanceDecisionInput, MethodAppearanceDecision methodAppearanceDecision) {
|
protected void finetuneMethodAppearance(Class cls, Method method,
|
||||||
|
MethodAppearanceDecision decision) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String methodName = methodAppearanceDecisionInput.getMethod().getName();
|
String methodName = method.getName();
|
||||||
if ( ! ( methodName.equals("add") || methodName.equals("list")) ) {
|
if (!(methodName.equals("add") || methodName.equals("list"))) {
|
||||||
methodAppearanceDecision.setExposeMethodAs(null);
|
decision.setExposeMethodAs(null);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e, e);
|
log.error(e, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Template methods */
|
/* Template methods */
|
||||||
|
|
||||||
|
@SuppressWarnings("hiding")
|
||||||
public void add(String... tags) {
|
public void add(String... tags) {
|
||||||
for (String tag : tags) {
|
for (String tag : tags) {
|
||||||
add(tag);
|
add(tag);
|
||||||
|
@ -72,12 +105,167 @@ public class Tags extends BaseTemplateModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(String tag) {
|
public void add(String tag) {
|
||||||
|
TagVersionInfo info = new TagVersionInfo(tag);
|
||||||
|
if (info.hasVersion()) {
|
||||||
|
tags.add(TagVersionInfo.addVersionNumber(tag, info));
|
||||||
|
} else {
|
||||||
tags.add(tag);
|
tags.add(tag);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String list() {
|
public String list() {
|
||||||
return StringUtils.join(tags, "\n");
|
return StringUtils.join(tags, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the value of "href" or "src".
|
||||||
|
*
|
||||||
|
* If there is such a value, and it doesn't have a query string already, and
|
||||||
|
* it represents a local URL, and we can locate the file that is served by
|
||||||
|
* the URL and get the last modified date, then we have found a "version
|
||||||
|
* number" that we can add to the attribute value.
|
||||||
|
*
|
||||||
|
* Reference for parsing attributes:
|
||||||
|
* https://www.w3.org/TR/html/syntax.html#elements-attributes
|
||||||
|
*/
|
||||||
|
protected static class TagVersionInfo {
|
||||||
|
private static final Pattern PATTERN_DOUBLE_QUOTES = Pattern
|
||||||
|
.compile("(href|src)\\s*=\\s*\"([^\"]+)\"[\\s|>]");
|
||||||
|
private static final int GROUP_INDEX_DOUBLE_QUOTES = 2;
|
||||||
|
|
||||||
|
private static final Pattern PATTERN_SINGLE_QUOTES = Pattern
|
||||||
|
.compile("(href|src)\\s*=\\s*'([^']+)'[\\s|>]");
|
||||||
|
private static final int GROUP_INDEX_SINGLE_QUOTES = 2;
|
||||||
|
|
||||||
|
private static final Pattern PATTERN_NO_QUOTES = Pattern
|
||||||
|
.compile("(href|src)\\s*=\\s*([^\"'<=>\\s]+)[\\s|>]");
|
||||||
|
private static final int GROUP_INDEX_NO_QUOTES = 2;
|
||||||
|
|
||||||
|
public static String addVersionNumber(String rawTag,
|
||||||
|
TagVersionInfo info) {
|
||||||
|
String versionString = (info.match.style == MatchResult.Style.NO_QUOTES)
|
||||||
|
? "?version&eq;"
|
||||||
|
: "?version=";
|
||||||
|
return rawTag.substring(0, info.match.start) + info.match.group
|
||||||
|
+ versionString + smushTimeStamp(info)
|
||||||
|
+ rawTag.substring(info.match.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String smushTimeStamp(TagVersionInfo info) {
|
||||||
|
int smushed = (((char) (info.timestamp >> 48))
|
||||||
|
^ ((char) (info.timestamp >> 32))
|
||||||
|
^ ((char) (info.timestamp >> 16))
|
||||||
|
^ ((char) info.timestamp));
|
||||||
|
return String.format("%04x", smushed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MatchResult match;
|
||||||
|
private long timestamp = 0L;
|
||||||
|
|
||||||
|
public TagVersionInfo(String rawTag) {
|
||||||
|
try {
|
||||||
|
match = findUrlValue(rawTag);
|
||||||
|
|
||||||
|
if (match != null && !hasQueryString(match.group)) {
|
||||||
|
String stripped = stripContextPath(match.group);
|
||||||
|
|
||||||
|
if (stripped != null) {
|
||||||
|
String realPath = locateRealPath(stripped);
|
||||||
|
|
||||||
|
if (realPath != null) {
|
||||||
|
timestamp = getLastModified(realPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.debug("Failed to add version info to tag: " + rawTag, e);
|
||||||
|
timestamp = 0L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasVersion() {
|
||||||
|
return timestamp != 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MatchResult findUrlValue(String rawTag) {
|
||||||
|
Matcher mDouble = PATTERN_DOUBLE_QUOTES.matcher(rawTag);
|
||||||
|
if (mDouble.find()) {
|
||||||
|
return new MatchResult(mDouble, GROUP_INDEX_DOUBLE_QUOTES,
|
||||||
|
MatchResult.Style.DOUBLE_QUOTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher mSingle = PATTERN_SINGLE_QUOTES.matcher(rawTag);
|
||||||
|
if (mSingle.find()) {
|
||||||
|
return new MatchResult(mSingle, GROUP_INDEX_SINGLE_QUOTES,
|
||||||
|
MatchResult.Style.SINGLE_QUOTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matcher mNo = PATTERN_NO_QUOTES.matcher(rawTag);
|
||||||
|
if (mNo.find()) {
|
||||||
|
return new MatchResult(mNo, GROUP_INDEX_NO_QUOTES,
|
||||||
|
MatchResult.Style.NO_QUOTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug(rawTag + " no match");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasQueryString(String group) {
|
||||||
|
if (group.indexOf('?') > -1) {
|
||||||
|
log.debug(group + " has query string already");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String stripContextPath(String group) {
|
||||||
|
String contextPath = UrlBuilder.getBaseUrl();
|
||||||
|
if (contextPath.isEmpty() || group.startsWith(contextPath)) {
|
||||||
|
return group.substring(contextPath.length());
|
||||||
|
} else {
|
||||||
|
log.debug(group + " doesn't match context path");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String locateRealPath(String stripped) {
|
||||||
|
ServletContext ctx = ApplicationUtils.instance()
|
||||||
|
.getServletContext();
|
||||||
|
String realPath = ctx.getRealPath(stripped);
|
||||||
|
if (realPath == null) {
|
||||||
|
log.debug(stripped + " has no real path");
|
||||||
|
}
|
||||||
|
return realPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long getLastModified(String realPath) {
|
||||||
|
return new File(realPath).lastModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class MatchResult {
|
||||||
|
public enum Style {
|
||||||
|
SINGLE_QUOTES, DOUBLE_QUOTES, NO_QUOTES
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String group;
|
||||||
|
public final int start;
|
||||||
|
public final int end;
|
||||||
|
public final Style style;
|
||||||
|
|
||||||
|
public MatchResult(Matcher matcher, int group, Style style) {
|
||||||
|
this.group = matcher.group(group);
|
||||||
|
this.start = matcher.start(group);
|
||||||
|
this.end = matcher.end(group);
|
||||||
|
this.style = style;
|
||||||
|
log.debug(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MatchResult[start=" + start + ", end=" + end
|
||||||
|
+ ", group=" + group + ", style=" + style + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.utils.configuration;
|
package edu.cornell.mannlib.vitro.webapp.utils.configuration;
|
||||||
|
|
||||||
import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDfloat;
|
|
||||||
import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDstring;
|
|
||||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty;
|
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.dataProperty;
|
||||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.objectProperty;
|
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.objectProperty;
|
||||||
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.typeStatement;
|
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.typeStatement;
|
||||||
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toJavaUri;
|
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toJavaUri;
|
||||||
|
import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDfloat;
|
||||||
|
import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDstring;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -19,18 +19,16 @@ import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.apache.jena.rdf.model.Model;
|
import org.apache.jena.rdf.model.Model;
|
||||||
import org.apache.jena.rdf.model.Statement;
|
import org.apache.jena.rdf.model.Statement;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
||||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess;
|
import edu.cornell.mannlib.vitro.webapp.modelaccess.RequestModelAccess;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationRdfParser.InvalidConfigurationRdfException;
|
import edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationRdfParser.InvalidConfigurationRdfException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.InstanceWrapper.InstanceWrapperException;
|
import edu.cornell.mannlib.vitro.webapp.utils.configuration.InstanceWrapper.InstanceWrapperException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyTypeException;
|
import edu.cornell.mannlib.vitro.webapp.utils.configuration.PropertyType.PropertyTypeException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.NoSuchPropertyMethodException;
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.ResourceUnavailableException;
|
import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.ResourceUnavailableException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -309,24 +307,6 @@ public class ConfigurationBeanLoaderTest extends
|
||||||
|
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
|
|
||||||
@Test
|
|
||||||
public void tripleHasUnrecognizedProperty_throwsException()
|
|
||||||
throws ConfigurationBeanLoaderException {
|
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
|
||||||
toJavaUri(SimpleSuccess.class)));
|
|
||||||
model.add(dataProperty(GENERIC_INSTANCE_URI,
|
|
||||||
"http://bogus.property/name", "No place to put it."));
|
|
||||||
|
|
||||||
expectSimpleFailure(
|
|
||||||
SimpleSuccess.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
|
||||||
"Failed to load"),
|
|
||||||
throwable(NoSuchPropertyMethodException.class,
|
|
||||||
"No property method"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void valueTypeDoesNotMatchArgumentOfPropertyMethod_throwsException()
|
public void valueTypeDoesNotMatchArgumentOfPropertyMethod_throwsException()
|
||||||
throws ConfigurationBeanLoaderException {
|
throws ConfigurationBeanLoaderException {
|
||||||
|
@ -395,6 +375,22 @@ public class ConfigurationBeanLoaderTest extends
|
||||||
assertNotNull(instance);
|
assertNotNull(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignores unexpected properties
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void simpleSuccessIgnoringExtraProperties() throws ConfigurationBeanLoaderException {
|
||||||
|
model.add(typeStatement(SIMPLE_SUCCESS_INSTANCE_URI,
|
||||||
|
toJavaUri(SimpleSuccess.class)));
|
||||||
|
model.add(dataProperty(SIMPLE_SUCCESS_INSTANCE_URI,
|
||||||
|
"http://surprise.property/name", "No matching method."));
|
||||||
|
|
||||||
|
SimpleSuccess instance = loader.loadInstance(
|
||||||
|
SIMPLE_SUCCESS_INSTANCE_URI, SimpleSuccess.class);
|
||||||
|
|
||||||
|
assertNotNull(instance);
|
||||||
|
}
|
||||||
|
|
||||||
public static class SimpleSuccess {
|
public static class SimpleSuccess {
|
||||||
// Nothing of interest.
|
// Nothing of interest.
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.utils.configuration;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.testing.ModelUtilitiesTestHelper.typeStatement;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.utils.configuration.ConfigurationBeanLoader.toPossibleJavaUris;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assure that we can use "namespaces" for Java URIs. The namespace must end
|
||||||
|
* with a '#'.
|
||||||
|
*/
|
||||||
|
public class ConfigurationBeanLoader_NamespacesTest
|
||||||
|
extends ConfigurationBeanLoaderTestBase {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// toPossibleJavaUris()
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void possibleForJavaLangString() {
|
||||||
|
Set<String> expected = new HashSet<>();
|
||||||
|
expected.add("java:java.lang.String");
|
||||||
|
expected.add("java:java#lang.String");
|
||||||
|
expected.add("java:java.lang#String");
|
||||||
|
assertEquals(expected, toPossibleJavaUris(String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// loadAll()
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadAllForJavaUtilRandom()
|
||||||
|
throws ConfigurationBeanLoaderException {
|
||||||
|
model.add(typeStatement("http://noPound", "java:java.util.Random"));
|
||||||
|
model.add(typeStatement("http://firstPound", "java:java#util.Random"));
|
||||||
|
model.add(typeStatement("http://secondPound", "java:java.util#Random"));
|
||||||
|
model.add(typeStatement("http://notARandom", "java:java.util.Set"));
|
||||||
|
Set<Random> instances = loader.loadAll(Random.class);
|
||||||
|
assertEquals(3, instances.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadAlForCustomInnerClass()
|
||||||
|
throws ConfigurationBeanLoaderException {
|
||||||
|
Set<String> typeUris = toPossibleJavaUris(ExampleClassForLoadAll.class);
|
||||||
|
for (String typeUri : typeUris) {
|
||||||
|
model.add(typeStatement("http://testUri" + model.size(), typeUri));
|
||||||
|
}
|
||||||
|
Set<ExampleClassForLoadAll> instances = loader
|
||||||
|
.loadAll(ExampleClassForLoadAll.class);
|
||||||
|
assertEquals(typeUris.size(), instances.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ExampleClassForLoadAll {
|
||||||
|
// Nothing of interest
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// loadInstance()
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadInstanceVariationsForJavaUtilRandom()
|
||||||
|
throws ConfigurationBeanLoaderException {
|
||||||
|
model.add(typeStatement("http://noPound", "java:java.util.Random"));
|
||||||
|
model.add(typeStatement("http://firstPound", "java:java#util.Random"));
|
||||||
|
model.add(typeStatement("http://secondPound", "java:java.util#Random"));
|
||||||
|
model.add(typeStatement("http://notARandom", "java:java.util.Set"));
|
||||||
|
|
||||||
|
assertNotNull(loader.loadInstance("http://noPound", Random.class));
|
||||||
|
assertNotNull(loader.loadInstance("http://firstPound", Random.class));
|
||||||
|
assertNotNull(loader.loadInstance("http://secondPound", Random.class));
|
||||||
|
|
||||||
|
try {
|
||||||
|
loader.loadInstance("http://notARandom", Random.class);
|
||||||
|
fail("Should not be a Random");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Expected it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loadInstanceVariationsForCustomInnerClass()
|
||||||
|
throws ConfigurationBeanLoaderException {
|
||||||
|
Set<String> typeUris = toPossibleJavaUris(
|
||||||
|
ExampleClassForLoadInstance.class);
|
||||||
|
for (String typeUri : typeUris) {
|
||||||
|
model.add(typeStatement("http://testUri" + model.size(), typeUri));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < model.size(); i++) {
|
||||||
|
String instanceUri = "http://testUri" + i;
|
||||||
|
assertNotNull("No instance for " + instanceUri, loader.loadInstance(
|
||||||
|
instanceUri, ExampleClassForLoadInstance.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ExampleClassForLoadInstance {
|
||||||
|
// Nothing of interest
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,8 +15,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.configuration.WrappedInstance.Vali
|
||||||
/**
|
/**
|
||||||
* Test the @Validation annotation.
|
* Test the @Validation annotation.
|
||||||
*/
|
*/
|
||||||
public class ConfigurationBeanLoader_ValidationTest extends
|
public class ConfigurationBeanLoader_ValidationTest
|
||||||
ConfigurationBeanLoaderTestBase {
|
extends ConfigurationBeanLoaderTestBase {
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -25,8 +25,7 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
||||||
toJavaUri(ValidationMethodWithParameter.class)));
|
toJavaUri(ValidationMethodWithParameter.class)));
|
||||||
|
|
||||||
expectSimpleFailure(
|
expectSimpleFailure(ValidationMethodWithParameter.class,
|
||||||
ValidationMethodWithParameter.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
throwable(ConfigurationBeanLoaderException.class,
|
||||||
"Failed to load"),
|
"Failed to load"),
|
||||||
throwable(InstanceWrapperException.class,
|
throwable(InstanceWrapperException.class,
|
||||||
|
@ -49,11 +48,11 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
||||||
toJavaUri(ValidationMethodShouldReturnVoid.class)));
|
toJavaUri(ValidationMethodShouldReturnVoid.class)));
|
||||||
|
|
||||||
expectSimpleFailure(
|
expectSimpleFailure(ValidationMethodShouldReturnVoid.class,
|
||||||
ValidationMethodShouldReturnVoid.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
throwable(ConfigurationBeanLoaderException.class,
|
||||||
"Failed to load"),
|
"Failed to load"),
|
||||||
throwable(InstanceWrapperException.class, "should return void"));
|
throwable(InstanceWrapperException.class,
|
||||||
|
"should return void"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ValidationMethodShouldReturnVoid {
|
public static class ValidationMethodShouldReturnVoid {
|
||||||
|
@ -71,8 +70,7 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
||||||
toJavaUri(ValidationMethodIsPrivate.class)));
|
toJavaUri(ValidationMethodIsPrivate.class)));
|
||||||
|
|
||||||
expectSimpleFailure(
|
expectSimpleFailure(ValidationMethodIsPrivate.class,
|
||||||
ValidationMethodIsPrivate.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
throwable(ConfigurationBeanLoaderException.class,
|
||||||
"Failed to load"),
|
"Failed to load"),
|
||||||
throwable(ValidationFailedException.class,
|
throwable(ValidationFailedException.class,
|
||||||
|
@ -94,8 +92,7 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
||||||
toJavaUri(ValidationThrowsException.class)));
|
toJavaUri(ValidationThrowsException.class)));
|
||||||
|
|
||||||
expectSimpleFailure(
|
expectSimpleFailure(ValidationThrowsException.class,
|
||||||
ValidationThrowsException.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
throwable(ConfigurationBeanLoaderException.class,
|
||||||
"Failed to load"),
|
"Failed to load"),
|
||||||
throwable(ValidationFailedException.class,
|
throwable(ValidationFailedException.class,
|
||||||
|
@ -144,8 +141,7 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
||||||
toJavaUri(ValidationOverValidationSubclass.class)));
|
toJavaUri(ValidationOverValidationSubclass.class)));
|
||||||
|
|
||||||
expectSimpleFailure(
|
expectSimpleFailure(ValidationOverValidationSubclass.class,
|
||||||
ValidationOverValidationSubclass.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
throwable(ConfigurationBeanLoaderException.class,
|
||||||
"Failed to load"),
|
"Failed to load"),
|
||||||
throwable(InstanceWrapperException.class,
|
throwable(InstanceWrapperException.class,
|
||||||
|
@ -158,8 +154,7 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
model.add(typeStatement(GENERIC_INSTANCE_URI,
|
||||||
toJavaUri(PlainOverValidationSubclass.class)));
|
toJavaUri(PlainOverValidationSubclass.class)));
|
||||||
|
|
||||||
expectSimpleFailure(
|
expectSimpleFailure(PlainOverValidationSubclass.class,
|
||||||
PlainOverValidationSubclass.class,
|
|
||||||
throwable(ConfigurationBeanLoaderException.class,
|
throwable(ConfigurationBeanLoaderException.class,
|
||||||
"Failed to load"),
|
"Failed to load"),
|
||||||
throwable(InstanceWrapperException.class,
|
throwable(InstanceWrapperException.class,
|
||||||
|
@ -182,8 +177,8 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
// Just want to see that the superclass validation is run.
|
// Just want to see that the superclass validation is run.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AdditionalValidationSubclass extends
|
public static class AdditionalValidationSubclass
|
||||||
ValidationSuperclass {
|
extends ValidationSuperclass {
|
||||||
public boolean validatorSubHasRun = false;
|
public boolean validatorSubHasRun = false;
|
||||||
|
|
||||||
@Validation
|
@Validation
|
||||||
|
@ -195,8 +190,8 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ValidationOverValidationSubclass extends
|
public static class ValidationOverValidationSubclass
|
||||||
EmptyValidationSubclass {
|
extends EmptyValidationSubclass {
|
||||||
@Override
|
@Override
|
||||||
@Validation
|
@Validation
|
||||||
public void validatorSuper() {
|
public void validatorSuper() {
|
||||||
|
@ -204,8 +199,8 @@ public class ConfigurationBeanLoader_ValidationTest extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PlainOverValidationSubclass extends
|
public static class PlainOverValidationSubclass
|
||||||
ValidationSuperclass {
|
extends ValidationSuperclass {
|
||||||
@Override
|
@Override
|
||||||
public void validatorSuper() {
|
public void validatorSuper() {
|
||||||
// Should fail
|
// Should fail
|
||||||
|
|
|
@ -0,0 +1,248 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.web.templatemodels;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags.TagVersionInfo;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags.TagVersionInfo.MatchResult;
|
||||||
|
import stubs.edu.cornell.mannlib.vitro.webapp.modules.ApplicationStub;
|
||||||
|
import stubs.javax.servlet.ServletContextStub;
|
||||||
|
|
||||||
|
public class TagsTest extends AbstractTestClass {
|
||||||
|
private ServletContextStub ctx;
|
||||||
|
private File resource;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws IOException {
|
||||||
|
resource = File.createTempFile("resource", "");
|
||||||
|
|
||||||
|
ctx = new ServletContextStub();
|
||||||
|
ctx.setRealPath("/base/sub/file.js", resource.getPath());
|
||||||
|
ctx.setRealPath("/base/sub/file.css", resource.getPath());
|
||||||
|
|
||||||
|
ApplicationStub.setup(ctx, null);
|
||||||
|
|
||||||
|
setContextPath("/context");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Parsing tests
|
||||||
|
//
|
||||||
|
// Reference for parsing attributes:
|
||||||
|
// https://www.w3.org/TR/html/syntax.html#elements-attributes
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noAttribute_failure() {
|
||||||
|
assertNoMatch("<div height='value'></div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singleQuote_noTerminator_failure() {
|
||||||
|
assertNoMatch("<link rel='stylesheet' href='problem></link>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singleQuotes_embeddedSingleQuote_failure() {
|
||||||
|
assertNoMatch("<script src='value'problem'></script");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singleQuotes_embeddedDoubleQuote_success() {
|
||||||
|
assertMatch("<script src='value\"noproblem'></script",
|
||||||
|
"value\"noproblem");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doubleQuote_noTerminator_failure() {
|
||||||
|
assertNoMatch("<link rel=\"stylesheet\" href=\"problem ></link>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doubleQuotes_embeddedDoubleQuote_failure() {
|
||||||
|
assertNoMatch("<link href=\"value\"problem\"></link>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doubleQuotes_embeddedSingleQuote_success() {
|
||||||
|
assertMatch("<link href=\"value'noproblem\"></link>",
|
||||||
|
"value'noproblem");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquotedBadTerminator_failure() {
|
||||||
|
assertNoMatch("<script src=problem");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquoted_embeddedEquals_failure() {
|
||||||
|
assertNoMatch("<script src=value=problem>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquoted_embeddedSingleQuote_failure() {
|
||||||
|
assertNoMatch("<script src=value'problem>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquoted_embeddedDoubleQuote_failure() {
|
||||||
|
assertNoMatch("<script src=value\"problem>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquoted_embeddedBackTick_failure() {
|
||||||
|
assertNoMatch("<script src=value`problem>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquoted_embeddedLessThan_failure() {
|
||||||
|
assertNoMatch("<script src=value<problem>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void spacesBeforeEquals_success() {
|
||||||
|
assertMatch("<link href =value rel='stylesheet'>", "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void spacesAfterEquals_success() {
|
||||||
|
assertMatch("<script src= 'value'></script>", "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noSpacesAroundEquals_success() {
|
||||||
|
assertMatch("<script src=\"value\" ></script>", "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Substitution tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noMatch_noChange() {
|
||||||
|
assertVersionNotAdded(
|
||||||
|
"<script junk='/context/base/sub/file.js' ></script>",
|
||||||
|
"no match");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alreadyHasQueryString_noChange() {
|
||||||
|
assertVersionNotAdded(
|
||||||
|
"<script src='/context/base/sub/file.js?why' ></script>",
|
||||||
|
"has query");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doesntStartWithContextPath_noChange() {
|
||||||
|
assertVersionNotAdded(
|
||||||
|
"<script src='/notContext/base/sub/file.js' ></script>",
|
||||||
|
"context path");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noRealPath_noChange() {
|
||||||
|
assertVersionNotAdded(
|
||||||
|
"<script src='/context/base/sub/nofile.js' ></script>",
|
||||||
|
"real path");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void exception_noChange() {
|
||||||
|
fail("exception_noChange not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void doubleQuotes_substitution() {
|
||||||
|
assertVersionAdded( //
|
||||||
|
"<link href=\"/context/base/sub/file.css\" rel=stylesheet></link>", //
|
||||||
|
"<link href=\"/context/base/sub/file.css?version=9999\" rel=stylesheet></link>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singleQuotes_substitution() {
|
||||||
|
assertVersionAdded( //
|
||||||
|
"<script src='/context/base/sub/file.js' ></script>", //
|
||||||
|
"<script src='/context/base/sub/file.js?version=9999' ></script>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unquoted_substitution() {
|
||||||
|
assertVersionAdded( //
|
||||||
|
"<script type=text/javascript src=/context/base/sub/file.js ></script>", //
|
||||||
|
"<script type=text/javascript src=/context/base/sub/file.js?version&eq;9999 ></script>");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void setContextPath(String contextPath) {
|
||||||
|
try {
|
||||||
|
Field f = UrlBuilder.class.getDeclaredField("contextPath");
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(null, contextPath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertMatch(String tag, String expected) {
|
||||||
|
TagVersionInfo info = new TagVersionInfo(tag);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Field f = TagVersionInfo.class.getDeclaredField("match");
|
||||||
|
f.setAccessible(true);
|
||||||
|
MatchResult match = (MatchResult) f.get(info);
|
||||||
|
|
||||||
|
assertEquals(expected, match.group);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNoMatch(String tag) {
|
||||||
|
TagVersionInfo info = new TagVersionInfo(tag);
|
||||||
|
assertFalse(info.hasVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertVersionAdded(String rawTag, String expected) {
|
||||||
|
String actual = createTag(rawTag);
|
||||||
|
String canonicalActual = actual.replaceAll("=[0-9a-f]{4}", "=9999")
|
||||||
|
.replaceAll("&eq;[0-9a-f]{4}", "&eq;9999");
|
||||||
|
assertEquals(expected, canonicalActual);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertVersionNotAdded(String rawTag, String debugMessage) {
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
captureLogOutput(Tags.class, writer, true);
|
||||||
|
setLoggerLevel(Tags.class, Level.DEBUG);
|
||||||
|
|
||||||
|
String actual = createTag(rawTag);
|
||||||
|
assertEquals(rawTag, actual);
|
||||||
|
assertThat(writer.toString(), containsString(debugMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createTag(String rawTag) {
|
||||||
|
Tags t = new Tags();
|
||||||
|
t.add(rawTag);
|
||||||
|
return t.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
@prefix : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#> .
|
@prefix : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#> .
|
||||||
|
@prefix vitroWebapp: <java:edu.cornell.mannlib.vitro.webapp#> .
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
#
|
#
|
||||||
|
@ -19,8 +20,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:application
|
:application
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl> ,
|
a vitroWebapp:application.ApplicationImpl ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.Application> ;
|
vitroWebapp:modules.Application ;
|
||||||
:hasSearchEngine :instrumentedSearchEngineWrapper ;
|
:hasSearchEngine :instrumentedSearchEngineWrapper ;
|
||||||
:hasSearchIndexer :basicSearchIndexer ;
|
:hasSearchIndexer :basicSearchIndexer ;
|
||||||
:hasImageProcessor :iioImageProcessor ;
|
:hasImageProcessor :iioImageProcessor ;
|
||||||
|
@ -35,8 +36,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:iioImageProcessor
|
:iioImageProcessor
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.imageprocessor.imageio.IIOImageProcessor> ,
|
a vitroWebapp:imageprocessor.imageio.IIOImageProcessor ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.imageProcessor.ImageProcessor> .
|
vitroWebapp:modules.imageProcessor.ImageProcessor .
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
#
|
#
|
||||||
|
@ -46,8 +47,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:ptiFileStorage
|
:ptiFileStorage
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.filestorage.impl.FileStorageImplWrapper> ,
|
a vitroWebapp:filestorage.impl.FileStorageImplWrapper ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.fileStorage.FileStorage> .
|
vitroWebapp:modules.fileStorage.FileStorage .
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
#
|
#
|
||||||
|
@ -58,13 +59,13 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:instrumentedSearchEngineWrapper
|
:instrumentedSearchEngineWrapper
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchengine.InstrumentedSearchEngineWrapper> ,
|
a vitroWebapp:searchengine.InstrumentedSearchEngineWrapper ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine> ;
|
vitroWebapp:modules.searchEngine.SearchEngine ;
|
||||||
:wraps :solrSearchEngine .
|
:wraps :solrSearchEngine .
|
||||||
|
|
||||||
:solrSearchEngine
|
:solrSearchEngine
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchengine.solr.SolrSearchEngine> ,
|
a vitroWebapp:searchengine.solr.SolrSearchEngine ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine> .
|
vitroWebapp:modules.searchEngine.SearchEngine .
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
#
|
#
|
||||||
|
@ -74,8 +75,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:basicSearchIndexer
|
:basicSearchIndexer
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.SearchIndexerImpl> ,
|
a vitroWebapp:searchindex.SearchIndexerImpl ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexer> ;
|
vitroWebapp:modules.searchIndexer.SearchIndexer ;
|
||||||
:threadPoolSize "10" .
|
:threadPoolSize "10" .
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
|
@ -89,26 +90,26 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:sdbContentTripleSource
|
:sdbContentTripleSource
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.triplesource.impl.sdb.ContentTripleSourceSDB> ,
|
a vitroWebapp:triplesource.impl.sdb.ContentTripleSourceSDB ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource> .
|
vitroWebapp:modules.tripleSource.ContentTripleSource .
|
||||||
|
|
||||||
#:tdbContentTripleSource
|
#:tdbContentTripleSource
|
||||||
# a <java:edu.cornell.mannlib.vitro.webapp.triplesource.impl.tdb.ContentTripleSourceTDB> ,
|
# a vitroWebapp:triplesource.impl.tdb.ContentTripleSourceTDB ,
|
||||||
# <java:edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource> ;
|
# vitroWebapp:modules.tripleSource.ContentTripleSource ;
|
||||||
# # May be an absolute path, or relative to the Vitro home directory.
|
# # May be an absolute path, or relative to the Vitro home directory.
|
||||||
# :hasTdbDirectory "tdbContentModels" .
|
# :hasTdbDirectory "tdbContentModels" .
|
||||||
|
|
||||||
#:sparqlContentTripleSource
|
#:sparqlContentTripleSource
|
||||||
# a <java:edu.cornell.mannlib.vitro.webapp.triplesource.impl.virtuoso.ContentTripleSourceSPARQL> ,
|
# a vitroWebapp:triplesource.impl.virtuoso.ContentTripleSourceSPARQL ,
|
||||||
# <java:edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource> ;
|
# vitroWebapp:modules.tripleSource.ContentTripleSource ;
|
||||||
# # The URI of the SPARQL endpoint for your triple-store.
|
# # The URI of the SPARQL endpoint for your triple-store.
|
||||||
# :hasEndpointURI "PUT_YOUR_SPARQL_ENDPOINT_URI_HERE" ;
|
# :hasEndpointURI "PUT_YOUR_SPARQL_ENDPOINT_URI_HERE" ;
|
||||||
# # The URI to use for SPARQL UPDATE calls against your triple-store.
|
# # The URI to use for SPARQL UPDATE calls against your triple-store.
|
||||||
# :hasUpdateEndpointURI "PUT_THE UPDATE_URI_HERE" .
|
# :hasUpdateEndpointURI "PUT_THE UPDATE_URI_HERE" .
|
||||||
|
|
||||||
#:virtuosoContentTripleSource
|
#:virtuosoContentTripleSource
|
||||||
# a <java:edu.cornell.mannlib.vitro.webapp.triplesource.impl.virtuoso.ContentTripleSourceVirtuoso> ,
|
# a vitroWebapp:triplesource.impl.virtuoso.ContentTripleSourceVirtuoso ,
|
||||||
# <java:edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource> ;
|
# vitroWebapp:modules.tripleSource.ContentTripleSource ;
|
||||||
# # The URI of Virtuoso's SPARQL endpoint.
|
# # The URI of Virtuoso's SPARQL endpoint.
|
||||||
# :hasEndpointURI "PUT_YOUR_VIRTUOSO_URI_HERE" ;
|
# :hasEndpointURI "PUT_YOUR_VIRTUOSO_URI_HERE" ;
|
||||||
# # The URI to use for SPARQL UPDATE calls against Virtuoso.
|
# # The URI to use for SPARQL UPDATE calls against Virtuoso.
|
||||||
|
@ -123,8 +124,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:tdbConfigurationTripleSource
|
:tdbConfigurationTripleSource
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.triplesource.impl.tdb.ConfigurationTripleSourceTDB> ,
|
a vitroWebapp:triplesource.impl.tdb.ConfigurationTripleSourceTDB ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource> .
|
vitroWebapp:modules.tripleSource.ConfigurationTripleSource .
|
||||||
|
|
||||||
# ----------------------------
|
# ----------------------------
|
||||||
#
|
#
|
||||||
|
@ -134,5 +135,5 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
:jfactTBoxReasonerModule
|
:jfactTBoxReasonerModule
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.tboxreasoner.impl.jfact.JFactTBoxReasonerModule> ,
|
a vitroWebapp:tboxreasoner.impl.jfact.JFactTBoxReasonerModule ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.modules.tboxreasoner.TBoxReasonerModule> .
|
vitroWebapp:modules.tboxreasoner.TBoxReasonerModule .
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
@prefix : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#> .
|
@prefix : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationSetup#> .
|
||||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||||
|
@prefix searchIndex: <java:edu.cornell.mannlib.vitro.webapp.searchindex#> .
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# configure the SearchIndexer
|
# configure the SearchIndexer
|
||||||
|
@ -8,8 +10,8 @@
|
||||||
|
|
||||||
# Individuals with these types will be excluded from the search index
|
# Individuals with these types will be excluded from the search index
|
||||||
:searchExcluder_typeExcluder
|
:searchExcluder_typeExcluder
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.ExcludeBasedOnType> ,
|
a searchIndex:exclusions.ExcludeBasedOnType ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.SearchIndexExcluder> ;
|
searchIndex:exclusions.SearchIndexExcluder ;
|
||||||
:excludes
|
:excludes
|
||||||
"http://www.w3.org/2002/07/owl#AnnotationProperty" ,
|
"http://www.w3.org/2002/07/owl#AnnotationProperty" ,
|
||||||
"http://www.w3.org/2002/07/owl#DatatypeProperty" ,
|
"http://www.w3.org/2002/07/owl#DatatypeProperty" ,
|
||||||
|
@ -17,8 +19,8 @@
|
||||||
|
|
||||||
# Individuals with types from these namespaces will be excluded from the search index.
|
# Individuals with types from these namespaces will be excluded from the search index.
|
||||||
:searchExcluder_namespaceExcluder
|
:searchExcluder_namespaceExcluder
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.ExcludeBasedOnNamespace> ,
|
a searchIndex:exclusions.ExcludeBasedOnNamespace ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.SearchIndexExcluder> ;
|
searchIndex:exclusions.SearchIndexExcluder ;
|
||||||
:excludes
|
:excludes
|
||||||
"http://vitro.mannlib.cornell.edu/ns/vitro/0.7#" ,
|
"http://vitro.mannlib.cornell.edu/ns/vitro/0.7#" ,
|
||||||
"http://vitro.mannlib.cornell.edu/ns/vitro/public#" ,
|
"http://vitro.mannlib.cornell.edu/ns/vitro/public#" ,
|
||||||
|
@ -27,38 +29,38 @@
|
||||||
|
|
||||||
# Individuals with URIs in these namespaces will be excluded from the search index.
|
# Individuals with URIs in these namespaces will be excluded from the search index.
|
||||||
:searchExcluder_typeNamespaceExcluder
|
:searchExcluder_typeNamespaceExcluder
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.ExcludeBasedOnTypeNamespace> ,
|
a searchIndex:exclusions.ExcludeBasedOnTypeNamespace ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.SearchIndexExcluder> ;
|
searchIndex:exclusions.SearchIndexExcluder ;
|
||||||
:excludes
|
:excludes
|
||||||
"http://vitro.mannlib.cornell.edu/ns/vitro/role#public" .
|
"http://vitro.mannlib.cornell.edu/ns/vitro/role#public" .
|
||||||
|
|
||||||
:searchExcluder_syncingTypeExcluder
|
:searchExcluder_syncingTypeExcluder
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.SyncingExcludeBasedOnType> ,
|
a searchIndex:exclusions.SyncingExcludeBasedOnType ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.exclusions.SearchIndexExcluder> .
|
searchIndex:exclusions.SearchIndexExcluder .
|
||||||
|
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
:uriFinder_forDataProperties
|
:uriFinder_forDataProperties
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.IndexingUriFinder> ,
|
a searchIndex:indexing.IndexingUriFinder ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.AdditionalURIsForDataProperties> .
|
searchIndex:indexing.AdditionalURIsForDataProperties .
|
||||||
|
|
||||||
:uriFinder_forObjectProperties
|
:uriFinder_forObjectProperties
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.IndexingUriFinder> ,
|
a searchIndex:indexing.IndexingUriFinder ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.AdditionalURIsForObjectProperties> .
|
searchIndex:indexing.AdditionalURIsForObjectProperties .
|
||||||
|
|
||||||
:uriFinder_forTypeStatements
|
:uriFinder_forTypeStatements
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.IndexingUriFinder> ,
|
a searchIndex:indexing.IndexingUriFinder ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.AdditionalURIsForTypeStatements> .
|
searchIndex:indexing.AdditionalURIsForTypeStatements .
|
||||||
|
|
||||||
:uriFinder_forClassGroupChange
|
:uriFinder_forClassGroupChange
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.IndexingUriFinder> ,
|
a searchIndex:indexing.IndexingUriFinder ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.indexing.URIsForClassGroupChange> .
|
searchIndex:indexing.URIsForClassGroupChange .
|
||||||
|
|
||||||
# ------------------------------------
|
# ------------------------------------
|
||||||
|
|
||||||
:documentModifier_AllNames
|
:documentModifier_AllNames
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.SelectQueryDocumentModifier> ,
|
a searchIndex:documentBuilding.SelectQueryDocumentModifier ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.DocumentModifier> ;
|
searchIndex:documentBuilding.DocumentModifier ;
|
||||||
rdfs:label "All labels are added to name fields." ;
|
rdfs:label "All labels are added to name fields." ;
|
||||||
:hasTargetField "nameRaw" ;
|
:hasTargetField "nameRaw" ;
|
||||||
:hasSelectQuery """
|
:hasSelectQuery """
|
||||||
|
@ -70,8 +72,8 @@
|
||||||
""" .
|
""" .
|
||||||
|
|
||||||
:documentModifier_NameFieldBooster
|
:documentModifier_NameFieldBooster
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.FieldBooster> ,
|
a searchIndex:documentBuilding.FieldBooster ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.DocumentModifier> ;
|
searchIndex:documentBuilding.DocumentModifier ;
|
||||||
:hasTargetField "nameRaw" ;
|
:hasTargetField "nameRaw" ;
|
||||||
:hasTargetField "nameLowercase" ;
|
:hasTargetField "nameLowercase" ;
|
||||||
:hasTargetField "nameUnstemmed" ;
|
:hasTargetField "nameUnstemmed" ;
|
||||||
|
@ -79,5 +81,5 @@
|
||||||
:hasBoost "1.2"^^xsd:float .
|
:hasBoost "1.2"^^xsd:float .
|
||||||
|
|
||||||
:documentModifier_thumbnailImageUrl
|
:documentModifier_thumbnailImageUrl
|
||||||
a <java:edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.ThumbnailImageURL> ,
|
a searchIndex:documentBuilding.ThumbnailImageURL ,
|
||||||
<java:edu.cornell.mannlib.vitro.webapp.searchindex.documentBuilding.DocumentModifier> .
|
searchIndex:documentBuilding.DocumentModifier .
|
||||||
|
|
Loading…
Add table
Reference in a new issue