/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.testing_framework;
import org.apache.jena.graph.Node;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;
import org.apache.jena.shared.PrefixMapping;
import org.apache.jena.util.CollectionFactory;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import org.junit.Assert;
import org.xenei.junit.contract.IProducer;
/**
* provides useful functionality for testing models, eg building small models
* from strings, testing equality, etc.
*
* Currently this class extends GraphHelper and thus TestCase.
*/
public class ModelHelper extends GraphHelper {
private static Model builderModel;
static {
builderModel = ModelFactory.createDefaultModel();
builderModel.setNsPrefixes(PrefixMapping.Extended);
}
protected static final Model empty = ModelFactory.createDefaultModel();
protected static Model extendedModel(IProducer<Model> producer) {
Model result = producer.newInstance();
result.setNsPrefixes(PrefixMapping.Extended);
return result;
}
protected static String nice(RDFNode n) {
return nice(n.asNode());
}
public static Statement statement(String fact) {
StringTokenizer st = new StringTokenizer(fact);
Resource sub = resource(st.nextToken());
Property pred = property(st.nextToken());
RDFNode obj = rdfNode(st.nextToken());
return builderModel.createStatement(sub, pred, obj);
}
public static Statement statement(Resource s, Property p, RDFNode o) {
return builderModel.createStatement(s, p, o);
}
public static RDFNode rdfNode(Model m, String s) {
return m.asRDFNode(NodeCreateUtils.create(s));
}
public static RDFNode rdfNode(String s) {
return rdfNode(builderModel, s);
}
public static <T extends RDFNode> T rdfNode(String s, Class<T> c) {
return rdfNode(s).as(c);
}
public static Resource resource() {
return ResourceFactory.createResource();
}
public static Resource resource(String s) {
return (Resource) rdfNode(s);
}
// public static Resource resource(Model m, String s) {
// return (Resource) rdfNode(m, s);
// }
public static Property property(String s) {
return rdfNode(s).as(Property.class);
}
public static Property property(Model m, String s) {
return rdfNode(m, s).as(Property.class);
}
public static Literal literal(String s, String lang) {
return builderModel.createLiteral(s, lang);
}
public static Literal literal(String s) {
return rdfNode(s).as(Literal.class);
}
// /**
// * Create an array of Statements parsed from a semi-separated string.
// *
// * @param lockModel
// * a model to serve as a statement factory
// * @param facts
// * a sequence of semicolon-separated "S P O" facts
// * @return a Statement[] of the (S P O) statements from the string
// */
// public static Statement[] statements(Model m, String facts) {
// ArrayList<Statement> sl = new ArrayList<Statement>();
// StringTokenizer st = new StringTokenizer(facts, ";");
// while (st.hasMoreTokens())
// sl.add(statement(m, st.nextToken()));
// return sl.toArray(new Statement[sl.size()]);
// }
/**
* Create an array of Statements parsed from a semi-separated string.
*
* @param facts
* a sequence of semicolon-separated "S P O" facts
* @return a Statement[] of the (S P O) statements from the string
*/
public static Statement[] statements(String facts) {
ArrayList<Statement> sl = new ArrayList<Statement>();
StringTokenizer st = new StringTokenizer(facts, ";");
while (st.hasMoreTokens())
sl.add(statement(st.nextToken()));
return sl.toArray(new Statement[sl.size()]);
}
/**
* Create an array of Resources from a whitespace-separated string
*
* @param items
* a whitespace-separated sequence to feed to resource
* @return a Resource[] of the parsed resources
*/
public static Resource[] resources(String items) {
ArrayList<Resource> rl = new ArrayList<Resource>();
StringTokenizer st = new StringTokenizer(items);
while (st.hasMoreTokens())
rl.add(resource(st.nextToken()));
return rl.toArray(new Resource[rl.size()]);
}
/**
* Answer the set of resources given by the space-separated
* <code>items</code> string. Each resource specification is interpreted as
* per <code>resource</code>.
*/
public static Set<Resource> resourceSet(String items) {
Set<Resource> result = new HashSet<Resource>();
StringTokenizer st = new StringTokenizer(items);
while (st.hasMoreTokens())
result.add(resource(st.nextToken()));
return result;
}
/**
* add to a model all the statements expressed by a string.
*
* Does not do any transaction manipulation.
*
* @param m
* the model to be updated
* @param facts
* a sequence of semicolon-separated "S P O" facts
* @return the updated model
*/
public static Model modelAdd(Model m, String facts) {
StringTokenizer semis = new StringTokenizer(facts, ";");
while (semis.hasMoreTokens()) {
StringTokenizer st = new StringTokenizer(semis.nextToken());
Resource sub = resource(st.nextToken());
Property pred = property(st.nextToken());
RDFNode obj = rdfNode(st.nextToken());
m.add(sub, pred, obj);
}
return m;
}
/**
* create a memory based model with extended prefixes and initialises it
* with statements parsed from a string.
*
* does all insertions in a transaction.
*
* @param facts
* @return Model
*/
public static Model memModel(String facts) {
Model model = ModelFactory.createMemModelMaker().createFreshModel();
model.setNsPrefixes(PrefixMapping.Extended);
txnBegin(model);
modelAdd(model, facts);
txnCommit(model);
return model;
}
/**
* Creates a model with extended prefixes and initialises it with statements
* parsed from a string.
*
* does all insertions in a transaction.
*
* @param facts
* a string in semicolon-separated "S P O" format
* @return a model containing those facts
*/
public static Model modelWithStatements(
IProducer<? extends Model> producer, String facts) {
Model m = createModel(producer);
txnBegin(m);
modelAdd(m, facts);
txnCommit(m);
return m;
}
/**
* Creates a model with extended prefixes and initialises it with statements
* parsed from the statement iterator.
*
* Does all insertions in a transaction.
*/
public static Model modelWithStatements(
IProducer<? extends Model> producer, final StmtIterator it) {
Model m = createModel(producer);
txnBegin(m);
while (it.hasNext()) {
m.add(it.nextStatement());
}
txnCommit(m);
return m;
}
/**
* make a model and give it Extended prefixes
*/
public static Model createModel(IProducer<? extends Model> producer) {
Model result = producer.newInstance();
result.setNsPrefixes(PrefixMapping.Extended);
return result;
}
/**
* test that two models are isomorphic and fail if they are not.
*
* @param title
* a String appearing at the beginning of the failure message
* @param wanted
* the model value that is expected
* @param got
* the model value to check
*/
public static void assertIsoModels(String title, Model wanted, Model got) {
if (wanted.isIsomorphicWith(got) == false) {
Map<Node, Object> map = CollectionFactory.createHashedMap();
fail(title + ": expected " + nice(wanted.getGraph(), map)
+ "\n but had " + nice(got.getGraph(), map));
}
}
public static void assertContainsAll(final Model model, final Model model2) {
for (final StmtIterator s = model2.listStatements(); s.hasNext();) {
Assert.assertTrue(model.contains(s.nextStatement()));
}
}
public static void assertSameStatements(final Model model,
final Model model2) {
assertContainsAll(model, model2);
assertContainsAll(model2, model);
}
public static Property prop(final String uri) {
return ResourceFactory.createProperty("eh:/" + uri);
}
public static Resource res(final String uri) {
return ResourceFactory.createResource("eh:/" + uri);
}
/**
* Fail if the two models are not isomorphic. See
* assertIsoModels(String,Model,Model).
*/
public static void assertIsoModels(Model wanted, Model got) {
assertIsoModels("models must be isomorphic", wanted, got);
}
public static final boolean tvBoolean = true;
public static final byte tvByte = 1;
public static final short tvShort = 2;
public static final int tvInt = -1;
public static final long tvLong = -2;
public static final char tvChar = '!';
public static final float tvFloat = (float) 123.456;
public static final double tvDouble = -123.456;
public static final String tvString = "test 12 string";
public static final double dDelta = 0.000000005;
public static final float fDelta = 0.000005f;
public static final Object tvLitObj = new LitTestObj(1234);
public static final LitTestObj tvObject = new LitTestObj(12345);
public static class LitTestObj {
protected long content;
public LitTestObj(final long l) {
content = l;
}
public LitTestObj(final String s) {
content = Long.parseLong(s.substring(1, s.length() - 1));
}
@Override
public boolean equals(final Object o) {
return (o instanceof LitTestObj)
&& (content == ((LitTestObj) o).content);
}
@Override
public int hashCode() {
return (int) (content ^ (content >> 32));
}
@Override
public String toString() {
return "[" + Long.toString(content) + "]";
}
public long getContent() {
return content;
}
}
/**
* Begin a transaction on the model if transactions are supported.
*
* @param m
*/
public static Model txnBegin(Model m) {
if (m.supportsTransactions()) {
return m.begin();
}
return m;
}
/**
* Commit the transaction on the model if transactions are supported.
*
* @param m
*/
public static Model txnCommit(Model m) {
if (m.supportsTransactions()) {
return m.commit();
}
return m;
}
/**
* Rollback (abort) the transaction on the model if transactions are
* supported.
*
* @param m
*/
public static Model txnRollback(Model m) {
if (m.supportsTransactions()) {
return m.abort();
}
return m;
}
}