commit 92acd9e1c4cb5b1a7a3807c01284c8507bc7f9bd
parent 4f25607ea77ca8eb8953b99705c85de97ad9d984
Author: Dan Callaghan <djc@djc.id.au>
Date: Tue, 6 Oct 2009 20:15:36 +1000
allow for user-defined adapatations, caching of selector parsing results
Diffstat:
11 files changed, 220 insertions(+), 74 deletions(-)
diff --git a/src/main/antlr3/au/com/miskinhill/rdftemplate/selector/Selector.g b/src/main/antlr3/au/com/miskinhill/rdftemplate/selector/Selector.g
@@ -5,22 +5,18 @@ package au.com.miskinhill.rdftemplate.selector;
}
@parser::members {
- public static Selector<?> parse(String expression) {
- CharStream stream = new ANTLRStringStream(expression);
- SelectorLexer lexer = new SelectorLexer(stream);
- CommonTokenStream tokens = new CommonTokenStream(lexer);
- SelectorParser parser = new SelectorParser(tokens);
- try {
- return parser.unionSelector();
- } catch (RecognitionException e) {
- throw new InvalidSelectorSyntaxException(e);
- }
- }
@Override
public void reportError(RecognitionException e) {
throw new InvalidSelectorSyntaxException(e);
}
+
+ private AdaptationResolver adaptationResolver;
+
+ public void setAdaptationResolver(AdaptationResolver adaptationResolver) {
+ this.adaptationResolver = adaptationResolver;
+ }
+
}
@lexer::header {
@@ -53,20 +49,35 @@ unionSelector returns [Selector<?> result]
;
selector returns [Selector<?> result]
+@init {
+ Class<? extends Adaptation<?>> adaptationClass;
+ Adaptation<?> adaptation = null;
+}
: ' '*
( ts=traversingSelector { result = ts; }
| { result = new NoopSelector(); }
)
( '#'
- ( URI_ADAPTATION { result = new SelectorWithAdaptation(result, new UriAdaptation()); }
- | URI_SLICE_ADAPTATION
- '('
- startIndex=INTEGER { result = new SelectorWithAdaptation(result,
- new UriSliceAdaptation(Integer.parseInt($startIndex.text))); }
+ adaptationName=XMLTOKEN { adaptationClass = adaptationResolver.getByName($adaptationName.text); }
+ ( '('
+ startIndex=INTEGER {
+ try {
+ adaptation = adaptationClass.getConstructor(Integer.class)
+ .newInstance(Integer.parseInt($startIndex.text));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
')'
- | COMPARABLE_LV_ADAPTATION { result = new SelectorWithAdaptation(result, new ComparableLiteralValueAdaptation()); }
- | LV_ADAPTATION { result = new SelectorWithAdaptation(result, new LiteralValueAdaptation()); }
+ | {
+ try {
+ adaptation = adaptationClass.newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
)
+ { $result = new SelectorWithAdaptation(result, adaptation); }
|
)
' '*
@@ -139,10 +150,6 @@ predicate returns [Predicate result]
URI_PREFIX_PREDICATE : 'uri-prefix' ;
TYPE_PREDICATE : 'type' ;
FIRST_PREDICATE : 'first' ;
-LV_ADAPTATION : 'lv' ;
-COMPARABLE_LV_ADAPTATION : 'comparable-lv' ;
-URI_SLICE_ADAPTATION : 'uri-slice' ;
-URI_ADAPTATION : 'uri' ;
XMLTOKEN : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')* ;
INTEGER : ('0'..'9')+ ;
diff --git a/src/main/java/au/com/miskinhill/rdftemplate/TemplateInterpolator.java b/src/main/java/au/com/miskinhill/rdftemplate/TemplateInterpolator.java
@@ -34,7 +34,7 @@ import com.hp.hpl.jena.rdf.model.RDFNode;
import org.apache.commons.lang.StringUtils;
import au.com.miskinhill.rdftemplate.selector.Selector;
-import au.com.miskinhill.rdftemplate.selector.SelectorParser;
+import au.com.miskinhill.rdftemplate.selector.SelectorFactory;
public class TemplateInterpolator {
@@ -55,17 +55,20 @@ public class TemplateInterpolator {
inputFactory.setProperty("javax.xml.stream.isCoalescing", true);
}
- private TemplateInterpolator() {
+ private final SelectorFactory selectorFactory;
+
+ public TemplateInterpolator(SelectorFactory selectorFactory) {
+ this.selectorFactory = selectorFactory;
}
@SuppressWarnings("unchecked")
- public static String interpolate(Reader reader, RDFNode node) throws XMLStreamException {
+ public String interpolate(Reader reader, RDFNode node) throws XMLStreamException {
StringWriter writer = new StringWriter();
interpolate(inputFactory.createXMLEventReader(reader), node, outputFactory.createXMLEventWriter(writer));
return writer.toString();
}
- public static void interpolate(Iterator<XMLEvent> reader, RDFNode node, XMLEventWriter writer)
+ public void interpolate(Iterator<XMLEvent> reader, RDFNode node, XMLEventWriter writer)
throws XMLStreamException {
while (reader.hasNext()) {
XMLEvent event = reader.next();
@@ -76,7 +79,7 @@ public class TemplateInterpolator {
Attribute testAttribute = start.getAttributeByName(new QName("test"));
if (testAttribute == null)
throw new TemplateSyntaxException("rdf:if must have a test attribute");
- Selector<?> selector = SelectorParser.parse(testAttribute.getValue());
+ Selector<?> selector = selectorFactory.get(testAttribute.getValue());
if (selector.result(node).isEmpty()) {
consumeTree(start, reader);
break;
@@ -92,7 +95,7 @@ public class TemplateInterpolator {
Attribute contentAttribute = start.getAttributeByName(CONTENT_ACTION_QNAME);
Attribute forAttribute = start.getAttributeByName(FOR_ACTION_QNAME);
if (ifAttribute != null) {
- Selector<?> selector = SelectorParser.parse(ifAttribute.getValue());
+ Selector<?> selector = selectorFactory.get(ifAttribute.getValue());
if (selector.result(node).isEmpty()) {
consumeTree(start, reader);
break;
@@ -104,12 +107,12 @@ public class TemplateInterpolator {
} else if (contentAttribute != null) {
consumeTree(start, reader);
start = interpolateAttributes(start, node);
- Selector<?> selector = SelectorParser.parse(contentAttribute.getValue());
+ Selector<?> selector = selectorFactory.get(contentAttribute.getValue());
writeTreeForContent(writer, start, selector.singleResult(node));
} else if (forAttribute != null) {
start = cloneStartWithAttributes(start, cloneAttributesWithout(start, FOR_ACTION_QNAME));
List<XMLEvent> tree = consumeTree(start, reader);
- Selector<RDFNode> selector = SelectorParser.parse(forAttribute.getValue()).withResultType(RDFNode.class);
+ Selector<RDFNode> selector = selectorFactory.get(forAttribute.getValue()).withResultType(RDFNode.class);
for (RDFNode subNode : selector.result(node)) {
interpolate(tree.iterator(), subNode, writer);
}
@@ -136,7 +139,7 @@ public class TemplateInterpolator {
}
}
- private static List<XMLEvent> consumeTree(StartElement start, Iterator<XMLEvent> reader) throws XMLStreamException {
+ private List<XMLEvent> consumeTree(StartElement start, Iterator<XMLEvent> reader) throws XMLStreamException {
List<XMLEvent> events = new ArrayList<XMLEvent>();
events.add(start);
Deque<QName> elementStack = new LinkedList<QName>();
@@ -162,7 +165,7 @@ public class TemplateInterpolator {
}
@SuppressWarnings("unchecked")
- private static StartElement interpolateAttributes(StartElement start, RDFNode node) {
+ private StartElement interpolateAttributes(StartElement start, RDFNode node) {
Set<Attribute> replacementAttributes = new LinkedHashSet<Attribute>();
for (Iterator<Attribute> it = start.getAttributes(); it.hasNext(); ) {
Attribute attribute = it.next();
@@ -186,7 +189,7 @@ public class TemplateInterpolator {
}
private static final Pattern SUBSTITUTION_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");
- public static String interpolateString(String template, RDFNode node) {
+ public String interpolateString(String template, RDFNode node) {
if (!SUBSTITUTION_PATTERN.matcher(template).find()) {
return template; // fast path
}
@@ -194,7 +197,7 @@ public class TemplateInterpolator {
Matcher matcher = SUBSTITUTION_PATTERN.matcher(template);
while (matcher.find()) {
String expression = matcher.group(1);
- Object replacement = SelectorParser.parse(expression).singleResult(node);
+ Object replacement = selectorFactory.get(expression).singleResult(node);
String replacementValue;
if (replacement instanceof RDFNode) {
@@ -217,7 +220,7 @@ public class TemplateInterpolator {
return substituted.toString();
}
- private static void writeTreeForContent(XMLEventWriter writer, StartElement start, Object replacement)
+ private void writeTreeForContent(XMLEventWriter writer, StartElement start, Object replacement)
throws XMLStreamException {
if (replacement instanceof RDFNode) {
RDFNode replacementNode = (RDFNode) replacement;
@@ -254,7 +257,7 @@ public class TemplateInterpolator {
}
@SuppressWarnings("unchecked")
- private static Set<Attribute> cloneAttributesWithout(StartElement start, QName omit) {
+ private Set<Attribute> cloneAttributesWithout(StartElement start, QName omit) {
// clone attributes, but without rdf:content
Set<Attribute> attributes = new LinkedHashSet<Attribute>();
for (Iterator<Attribute> it = start.getAttributes(); it.hasNext(); ) {
@@ -265,7 +268,7 @@ public class TemplateInterpolator {
return attributes;
}
- private static void writeXMLLiteral(NamespaceContext nsContext, String literal, XMLEventWriter writer)
+ private void writeXMLLiteral(NamespaceContext nsContext, String literal, XMLEventWriter writer)
throws XMLStreamException {
XMLEventReader reader = inputFactory.createXMLEventReader(new StringReader(literal));
while (reader.hasNext()) {
diff --git a/src/main/java/au/com/miskinhill/rdftemplate/selector/AdaptationResolver.java b/src/main/java/au/com/miskinhill/rdftemplate/selector/AdaptationResolver.java
@@ -0,0 +1,7 @@
+package au.com.miskinhill.rdftemplate.selector;
+
+public interface AdaptationResolver {
+
+ <T> Class<? extends Adaptation<?>> getByName(String name);
+
+}
diff --git a/src/main/java/au/com/miskinhill/rdftemplate/selector/AntlrSelectorFactory.java b/src/main/java/au/com/miskinhill/rdftemplate/selector/AntlrSelectorFactory.java
@@ -0,0 +1,34 @@
+package au.com.miskinhill.rdftemplate.selector;
+
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.antlr.runtime.RecognitionException;
+
+public class AntlrSelectorFactory implements SelectorFactory {
+
+ private final AdaptationResolver adaptationResolver;
+
+ public AntlrSelectorFactory() {
+ this.adaptationResolver = new DefaultAdaptationResolver();
+ }
+
+ public AntlrSelectorFactory(AdaptationResolver adaptationResolver) {
+ this.adaptationResolver = adaptationResolver;
+ }
+
+ @Override
+ public Selector<?> get(String expression) {
+ CharStream stream = new ANTLRStringStream(expression);
+ SelectorLexer lexer = new SelectorLexer(stream);
+ CommonTokenStream tokens = new CommonTokenStream(lexer);
+ SelectorParser parser = new SelectorParser(tokens);
+ parser.setAdaptationResolver(adaptationResolver);
+ try {
+ return parser.unionSelector();
+ } catch (RecognitionException e) {
+ throw new InvalidSelectorSyntaxException(e);
+ }
+ }
+
+}
diff --git a/src/main/java/au/com/miskinhill/rdftemplate/selector/DefaultAdaptationResolver.java b/src/main/java/au/com/miskinhill/rdftemplate/selector/DefaultAdaptationResolver.java
@@ -0,0 +1,21 @@
+package au.com.miskinhill.rdftemplate.selector;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DefaultAdaptationResolver implements AdaptationResolver {
+
+ private static final Map<String, Class<? extends Adaptation<?>>> ADAPTATIONS = new HashMap<String, Class<? extends Adaptation<?>>>();
+ static {
+ ADAPTATIONS.put("uri", UriAdaptation.class);
+ ADAPTATIONS.put("uri-slice", UriSliceAdaptation.class);
+ ADAPTATIONS.put("lv", LiteralValueAdaptation.class);
+ ADAPTATIONS.put("comparable-lv", ComparableLiteralValueAdaptation.class);
+ }
+
+ @Override
+ public Class<? extends Adaptation<?>> getByName(String name) {
+ return ADAPTATIONS.get(name);
+ }
+
+}
diff --git a/src/main/java/au/com/miskinhill/rdftemplate/selector/EternallyCachingSelectorFactory.java b/src/main/java/au/com/miskinhill/rdftemplate/selector/EternallyCachingSelectorFactory.java
@@ -0,0 +1,35 @@
+package au.com.miskinhill.rdftemplate.selector;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * {@link SelectorFactory} implementation which indirects to a real
+ * implementation and caches its return values eternally. Do not use in
+ * situations where the set of input expressions can be unbounded (e.g.
+ * user-provided) as this will lead to unbounded cache growth.
+ * <p>
+ * A better implementation would use a LRU cache or similar, but I cbf.
+ */
+public class EternallyCachingSelectorFactory implements SelectorFactory {
+
+ private final SelectorFactory real;
+ private final Map<String, Selector<?>> cache = new HashMap<String, Selector<?>>();
+
+ public EternallyCachingSelectorFactory(SelectorFactory real) {
+ this.real = real;
+ }
+
+ @Override
+ public Selector<?> get(String expression) {
+ Selector<?> cached = cache.get(expression);
+ if (cached == null) {
+ Selector<?> fresh = real.get(expression);
+ cache.put(expression, fresh);
+ return fresh;
+ } else {
+ return cached;
+ }
+ }
+
+}
diff --git a/src/main/java/au/com/miskinhill/rdftemplate/selector/SelectorFactory.java b/src/main/java/au/com/miskinhill/rdftemplate/selector/SelectorFactory.java
@@ -0,0 +1,7 @@
+package au.com.miskinhill.rdftemplate.selector;
+
+public interface SelectorFactory {
+
+ Selector<?> get(String expression);
+
+}
diff --git a/src/test/java/au/com/miskinhill/rdftemplate/TemplateInterpolatorUnitTest.java b/src/test/java/au/com/miskinhill/rdftemplate/TemplateInterpolatorUnitTest.java
@@ -22,6 +22,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import au.com.miskinhill.rdftemplate.datatype.DateDataType;
+import au.com.miskinhill.rdftemplate.selector.AntlrSelectorFactory;
public class TemplateInterpolatorUnitTest {
@@ -31,6 +32,7 @@ public class TemplateInterpolatorUnitTest {
}
private Model model;
+ private TemplateInterpolator templateInterpolator;
@Before
public void setUp() {
@@ -38,12 +40,13 @@ public class TemplateInterpolatorUnitTest {
InputStream stream = this.getClass().getResourceAsStream(
"/au/com/miskinhill/rdftemplate/test-data.xml");
model.read(stream, "");
+ templateInterpolator = new TemplateInterpolator(new AntlrSelectorFactory());
}
@Test
public void shouldReplaceSubtreesWithContent() throws Exception {
Resource journal = model.getResource("http://miskinhill.com.au/journals/test/");
- String result = TemplateInterpolator.interpolate(
+ String result = templateInterpolator.interpolate(
new InputStreamReader(this.getClass().getResourceAsStream("replace-subtree.xml")), journal);
assertThat(result, containsString("<div xml:lang=\"en\" lang=\"en\">Test Journal of Good Stuff</div>"));
assertThat(result, not(containsString("<p>This should all go <em>away</em>!</p>")));
@@ -52,7 +55,7 @@ public class TemplateInterpolatorUnitTest {
@Test
public void shouldHandleXMLLiterals() throws Exception {
Resource journal = model.getResource("http://miskinhill.com.au/journals/test/");
- String result = TemplateInterpolator.interpolate(
+ String result = templateInterpolator.interpolate(
new InputStreamReader(this.getClass().getResourceAsStream("replace-xml.xml")), journal);
assertThat(result, containsString(
"<div xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\"><p><em>Test Journal</em> is a journal.</p></div>"));
@@ -61,14 +64,14 @@ public class TemplateInterpolatorUnitTest {
@Test
public void shouldHandleIfs() throws Exception {
Resource author = model.getResource("http://miskinhill.com.au/authors/test-author");
- String result = TemplateInterpolator.interpolate(
+ String result = templateInterpolator.interpolate(
new InputStreamReader(this.getClass().getResourceAsStream("conditional.xml")), author);
assertThat(result, containsString("attribute test"));
assertThat(result, containsString("element test"));
assertThat(result, not(containsString("rdf:if")));
Resource authorWithoutNotes = model.getResource("http://miskinhill.com.au/authors/another-author");
- result = TemplateInterpolator.interpolate(
+ result = templateInterpolator.interpolate(
new InputStreamReader(this.getClass().getResourceAsStream("conditional.xml")), authorWithoutNotes);
assertThat(result, not(containsString("attribute test")));
assertThat(result, not(containsString("element test")));
@@ -77,7 +80,7 @@ public class TemplateInterpolatorUnitTest {
@Test
public void shouldWork() throws Exception {
Resource journal = model.getResource("http://miskinhill.com.au/journals/test/");
- String result = TemplateInterpolator.interpolate(
+ String result = templateInterpolator.interpolate(
new InputStreamReader(this.getClass().getResourceAsStream("test-template.xml")), journal);
String expected = exhaust(this.getClass().getResource("test-template.out.xml").toURI());
assertEquals(expected.trim(), result.trim());
diff --git a/src/test/java/au/com/miskinhill/rdftemplate/selector/EternallyCachingSelectorFactoryUnitTest.java b/src/test/java/au/com/miskinhill/rdftemplate/selector/EternallyCachingSelectorFactoryUnitTest.java
@@ -0,0 +1,18 @@
+package au.com.miskinhill.rdftemplate.selector;
+
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class EternallyCachingSelectorFactoryUnitTest {
+
+ @Test
+ public void shouldCacheSelectors() {
+ EternallyCachingSelectorFactory factory = new EternallyCachingSelectorFactory(new AntlrSelectorFactory());
+ Selector<?> first = factory.get("dc:creator/foaf:name");
+ Selector<?> second = factory.get("dc:creator/foaf:name");
+ assertThat((Selector) first, sameInstance((Selector) second));
+ }
+
+}
diff --git a/src/test/java/au/com/miskinhill/rdftemplate/selector/SelectorEvaluationUnitTest.java b/src/test/java/au/com/miskinhill/rdftemplate/selector/SelectorEvaluationUnitTest.java
@@ -22,6 +22,7 @@ public class SelectorEvaluationUnitTest {
private Model m;
private Resource journal, issue, article, citedArticle, author, anotherAuthor, book, review, anotherReview, obituary, en, ru;
+ private SelectorFactory selectorFactory;
@BeforeClass
public static void ensureDatatypesRegistered() {
@@ -45,24 +46,25 @@ public class SelectorEvaluationUnitTest {
obituary = m.createResource("http://miskinhill.com.au/journals/test/1:1/in-memoriam-john-doe");
en = m.createResource("http://www.lingvoj.org/lang/en");
ru = m.createResource("http://www.lingvoj.org/lang/ru");
+ selectorFactory = new AntlrSelectorFactory();
}
@Test
public void shouldEvaluateTraversal() {
- RDFNode result = SelectorParser.parse("dc:creator").withResultType(RDFNode.class).singleResult(article);
+ RDFNode result = selectorFactory.get("dc:creator").withResultType(RDFNode.class).singleResult(article);
assertThat(result, equalTo((RDFNode) author));
}
@Test
public void shouldEvaluateMultipleTraversals() throws Exception {
- RDFNode result = SelectorParser.parse("dc:creator/foaf:name")
+ RDFNode result = selectorFactory.get("dc:creator/foaf:name")
.withResultType(RDFNode.class).singleResult(article);
assertThat(((Literal) result).getString(), equalTo("Test Author"));
}
@Test
public void shouldEvaluateInverseTraversal() throws Exception {
- List<RDFNode> results = SelectorParser.parse("!mhs:isIssueOf/!dc:isPartOf")
+ List<RDFNode> results = selectorFactory.get("!mhs:isIssueOf/!dc:isPartOf")
.withResultType(RDFNode.class).result(journal);
assertThat(results.size(), equalTo(4));
assertThat(results, hasItems((RDFNode) article, (RDFNode) review, (RDFNode) anotherReview, (RDFNode) obituary));
@@ -70,7 +72,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateSortOrder() throws Exception {
- List<RDFNode> results = SelectorParser.parse("dc:language(lingvoj:iso1#comparable-lv)")
+ List<RDFNode> results = selectorFactory.get("dc:language(lingvoj:iso1#comparable-lv)")
.withResultType(RDFNode.class).result(journal);
assertThat(results.size(), equalTo(2));
assertThat(results.get(0), equalTo((RDFNode) en));
@@ -79,7 +81,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateReverseSortOrder() throws Exception {
- List<RDFNode> results = SelectorParser.parse("dc:language(~lingvoj:iso1#comparable-lv)")
+ List<RDFNode> results = selectorFactory.get("dc:language(~lingvoj:iso1#comparable-lv)")
.withResultType(RDFNode.class).result(journal);
assertThat(results.size(), equalTo(2));
assertThat(results.get(0), equalTo((RDFNode) ru));
@@ -88,7 +90,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateComplexSortOrder() throws Exception {
- List<RDFNode> results = SelectorParser.parse("!mhs:reviews(dc:isPartOf/mhs:publicationDate#comparable-lv)")
+ List<RDFNode> results = selectorFactory.get("!mhs:reviews(dc:isPartOf/mhs:publicationDate#comparable-lv)")
.withResultType(RDFNode.class).result(book);
assertThat(results.size(), equalTo(2));
assertThat(results.get(0), equalTo((RDFNode) review));
@@ -97,31 +99,31 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateUriAdaptation() throws Exception {
- String result = SelectorParser.parse("mhs:coverThumbnail#uri")
+ String result = selectorFactory.get("mhs:coverThumbnail#uri")
.withResultType(String.class).singleResult(issue);
assertThat(result, equalTo("http://miskinhill.com.au/journals/test/1:1/cover.thumb.jpg"));
}
@Test
public void shouldEvaluateBareUriAdaptation() throws Exception {
- String result = SelectorParser.parse("#uri").withResultType(String.class).singleResult(journal);
+ String result = selectorFactory.get("#uri").withResultType(String.class).singleResult(journal);
assertThat(result, equalTo("http://miskinhill.com.au/journals/test/"));
}
@Test
public void shouldEvaluateUriSliceAdaptation() throws Exception {
- String result = SelectorParser.parse("dc:identifier[uri-prefix='urn:issn:']#uri-slice(9)")
+ String result = selectorFactory.get("dc:identifier[uri-prefix='urn:issn:']#uri-slice(9)")
.withResultType(String.class).singleResult(journal);
assertThat(result, equalTo("12345678"));
}
@Test
public void shouldEvaluateSubscript() throws Exception {
- String result = SelectorParser.parse(
+ String result = selectorFactory.get(
"!mhs:isIssueOf(~mhs:publicationDate#comparable-lv)[0]/mhs:coverThumbnail#uri")
.withResultType(String.class).singleResult(journal);
assertThat(result, equalTo("http://miskinhill.com.au/journals/test/2:1/cover.thumb.jpg"));
- result = SelectorParser.parse(
+ result = selectorFactory.get(
"!mhs:isIssueOf(mhs:publicationDate#comparable-lv)[0]/mhs:coverThumbnail#uri")
.withResultType(String.class).singleResult(journal);
assertThat(result, equalTo("http://miskinhill.com.au/journals/test/1:1/cover.thumb.jpg"));
@@ -129,7 +131,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateLVAdaptation() throws Exception {
- List<Object> results = SelectorParser.parse("dc:language/lingvoj:iso1#lv")
+ List<Object> results = selectorFactory.get("dc:language/lingvoj:iso1#lv")
.withResultType(Object.class).result(journal);
assertThat(results.size(), equalTo(2));
assertThat(results, hasItems((Object) "en", (Object) "ru"));
@@ -137,7 +139,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateTypePredicate() throws Exception {
- List<RDFNode> results = SelectorParser.parse("!dc:creator[type=mhs:Review]")
+ List<RDFNode> results = selectorFactory.get("!dc:creator[type=mhs:Review]")
.withResultType(RDFNode.class).result(author);
assertThat(results.size(), equalTo(1));
assertThat(results, hasItems((RDFNode) review));
@@ -145,7 +147,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateAndCombinationOfPredicates() throws Exception {
- List<RDFNode> results = SelectorParser.parse("!dc:creator[type=mhs:Article and uri-prefix='http://miskinhill.com.au/journals/']")
+ List<RDFNode> results = selectorFactory.get("!dc:creator[type=mhs:Article and uri-prefix='http://miskinhill.com.au/journals/']")
.withResultType(RDFNode.class).result(author);
assertThat(results.size(), equalTo(1));
assertThat(results, hasItems((RDFNode) article));
@@ -153,7 +155,7 @@ public class SelectorEvaluationUnitTest {
@Test
public void shouldEvaluateUnion() throws Exception {
- List<RDFNode> results = SelectorParser.parse("!dc:creator | !mhs:translator")
+ List<RDFNode> results = selectorFactory.get("!dc:creator | !mhs:translator")
.withResultType(RDFNode.class).result(anotherAuthor);
assertThat(results.size(), equalTo(3));
assertThat(results, hasItems((RDFNode) article, (RDFNode) citedArticle, (RDFNode) anotherReview));
diff --git a/src/test/java/au/com/miskinhill/rdftemplate/selector/SelectorParserUnitTest.java b/src/test/java/au/com/miskinhill/rdftemplate/selector/SelectorParserUnitTest.java
@@ -1,5 +1,7 @@
package au.com.miskinhill.rdftemplate.selector;
+import org.junit.Before;
+
import static au.com.miskinhill.rdftemplate.selector.AdaptationMatcher.*;
import static au.com.miskinhill.rdftemplate.selector.PredicateMatcher.*;
import static au.com.miskinhill.rdftemplate.selector.SelectorMatcher.*;
@@ -11,15 +13,22 @@ import org.junit.Test;
public class SelectorParserUnitTest {
+ private SelectorFactory factory;
+
+ @Before
+ public void setUp() {
+ factory = new AntlrSelectorFactory();
+ }
+
@Test
public void shouldRecogniseSingleTraversal() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("dc:creator").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("dc:creator").withResultType(RDFNode.class);
assertThat(selector, selector(traversal("dc", "creator")));
}
@Test
public void shouldRecogniseMultipleTraversals() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("dc:creator/foaf:name").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("dc:creator/foaf:name").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("dc", "creator"),
traversal("foaf", "name")));
@@ -27,7 +36,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseInverseTraversal() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!dc:isPartOf/!dc:isPartOf").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!dc:isPartOf/!dc:isPartOf").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("dc", "isPartOf").inverse(),
traversal("dc", "isPartOf").inverse()));
@@ -35,7 +44,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseSortOrder() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!mhs:isIssueOf(mhs:publicationDate#comparable-lv)").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!mhs:isIssueOf(mhs:publicationDate#comparable-lv)").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("mhs", "isIssueOf").inverse()
.withSortOrder(selector(traversal("mhs", "publicationDate"))
@@ -44,7 +53,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseReverseSortOrder() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!mhs:isIssueOf(~mhs:publicationDate#comparable-lv)").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!mhs:isIssueOf(~mhs:publicationDate#comparable-lv)").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("mhs", "isIssueOf").inverse()
.withSortOrder(selector(traversal("mhs", "publicationDate"))
@@ -54,7 +63,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseComplexSortOrder() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!mhs:reviews(dc:isPartOf/mhs:publicationDate#comparable-lv)").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!mhs:reviews(dc:isPartOf/mhs:publicationDate#comparable-lv)").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("mhs", "reviews")
.withSortOrder(selector(traversal("dc", "isPartOf"), traversal("mhs", "publicationDate"))
@@ -63,7 +72,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseUriAdaptation() throws Exception {
- Selector<?> selector = SelectorParser.parse("mhs:coverThumbnail#uri");
+ Selector<?> selector = factory.get("mhs:coverThumbnail#uri");
assertThat(selector, selector(
traversal("mhs", "coverThumbnail"))
.withAdaptation(uriAdaptation()));
@@ -71,13 +80,13 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseBareUriAdaptation() throws Exception {
- Selector<?> selector = SelectorParser.parse("#uri");
+ Selector<?> selector = factory.get("#uri");
assertThat(selector, selector().withAdaptation(uriAdaptation()));
}
@Test
public void shouldRecogniseUriSliceAdaptation() throws Exception {
- Selector<?> selector = SelectorParser.parse("dc:identifier[uri-prefix='urn:issn:']#uri-slice(9)");
+ Selector<?> selector = factory.get("dc:identifier[uri-prefix='urn:issn:']#uri-slice(9)");
assertThat(selector, selector(
traversal("dc", "identifier")
.withPredicate(uriPrefixPredicate("urn:issn:")))
@@ -86,7 +95,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseUriPrefixPredicate() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse(
+ Selector<RDFNode> selector = factory.get(
"!mhs:isIssueOf[uri-prefix='http://miskinhill.com.au/journals/'](~mhs:publicationDate#comparable-lv)")
.withResultType(RDFNode.class);
assertThat(selector, selector(
@@ -100,7 +109,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseSubscript() throws Exception {
- Selector<String> selector = SelectorParser.parse(
+ Selector<String> selector = factory.get(
"!mhs:isIssueOf(~mhs:publicationDate#comparable-lv)[0]/mhs:coverThumbnail#uri")
.withResultType(String.class);
assertThat(selector, selector(
@@ -116,7 +125,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseLVAdaptation() throws Exception {
- Selector<Object> selector = SelectorParser.parse("dc:language/lingvoj:iso1#lv").withResultType(Object.class);
+ Selector<Object> selector = factory.get("dc:language/lingvoj:iso1#lv").withResultType(Object.class);
assertThat(selector, selector(
traversal("dc", "language"),
traversal("lingvoj", "iso1"))
@@ -125,14 +134,14 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseTypePredicate() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!dc:creator[type=mhs:Review]").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!dc:creator[type=mhs:Review]").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("dc", "creator").inverse().withPredicate(typePredicate("mhs", "Review"))));
}
@Test
public void shouldRecogniseAndCombinationOfPredicates() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!dc:creator[type=mhs:Review and uri-prefix='http://miskinhill.com.au/journals/']").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!dc:creator[type=mhs:Review and uri-prefix='http://miskinhill.com.au/journals/']").withResultType(RDFNode.class);
assertThat(selector, selector(
traversal("dc", "creator").inverse()
.withPredicate(booleanAndPredicate(
@@ -142,7 +151,7 @@ public class SelectorParserUnitTest {
@Test
public void shouldRecogniseUnion() throws Exception {
- Selector<RDFNode> selector = SelectorParser.parse("!dc:creator | !mhs:translator").withResultType(RDFNode.class);
+ Selector<RDFNode> selector = factory.get("!dc:creator | !mhs:translator").withResultType(RDFNode.class);
assertThat((UnionSelector<RDFNode>) selector, unionSelector(
selector(traversal("dc", "creator").inverse()),
selector(traversal("mhs", "translator").inverse())));
@@ -150,12 +159,12 @@ public class SelectorParserUnitTest {
@Test(expected = InvalidSelectorSyntaxException.class)
public void shouldThrowForInvalidSyntax() throws Exception {
- SelectorParser.parse("dc:creator]["); // this is a parser error
+ factory.get("dc:creator]["); // this is a parser error
}
@Test(expected = InvalidSelectorSyntaxException.class)
public void shouldThrowForUnrecognisedCharacter() throws Exception {
- SelectorParser.parse("dc:cre&ator"); // ... and this is a lexer error
+ factory.get("dc:cre&ator"); // ... and this is a lexer error
}
}