/* * (C) Copyright 2006-2016 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed 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. * * Contributors: * Nuxeo - initial API and implementation */ package org.nuxeo.ecm.platform.relations.jena; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.io.Charsets; import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; import org.nuxeo.common.utils.FileUtils; import org.nuxeo.ecm.platform.relations.api.Graph; import org.nuxeo.ecm.platform.relations.api.Node; import org.nuxeo.ecm.platform.relations.api.QNameResource; import org.nuxeo.ecm.platform.relations.api.QueryResult; import org.nuxeo.ecm.platform.relations.api.RelationManager; import org.nuxeo.ecm.platform.relations.api.Resource; import org.nuxeo.ecm.platform.relations.api.Statement; import org.nuxeo.ecm.platform.relations.api.impl.BlankImpl; import org.nuxeo.ecm.platform.relations.api.impl.LiteralImpl; import org.nuxeo.ecm.platform.relations.api.impl.QNameResourceImpl; import org.nuxeo.ecm.platform.relations.api.impl.ResourceImpl; import org.nuxeo.ecm.platform.relations.api.impl.StatementImpl; import org.nuxeo.ecm.platform.relations.descriptors.GraphDescriptor; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.test.NXRuntimeTestCase; import com.hp.hpl.jena.rdf.model.Model; public class TestJenaGraph extends NXRuntimeTestCase { private JenaGraph graph; private List<Statement> statements; private String namespace; private Resource doc1; private Resource doc2; private QNameResource isBasedOn; private QNameResource references; @Override @Before public void setUp() throws Exception { super.setUp(); deployBundle("org.nuxeo.runtime.management"); deployBundle("org.nuxeo.ecm.core.schema"); deployBundle("org.nuxeo.ecm.core.api"); deployBundle("org.nuxeo.ecm.relations"); deployBundle("org.nuxeo.ecm.relations.jena"); deployContrib("org.nuxeo.ecm.relations.jena.tests", "jena-test-bundle.xml"); RelationManager service = Framework.getService(RelationManager.class); Graph graph = service.getGraphByName("myrelations"); assertNotNull(graph); assertEquals(JenaGraph.class, graph.getClass()); this.graph = (JenaGraph) graph; statements = new ArrayList<>(); doc1 = new ResourceImpl("http://www.ecm.org/uid/DOC200600013_02.01"); doc2 = new ResourceImpl("http://www.ecm.org/uid/DOC200600015_01.00"); namespace = "http://purl.org/dc/terms/"; isBasedOn = new QNameResourceImpl(namespace, "IsBasedOn"); references = new QNameResourceImpl(namespace, "References"); statements.add(new StatementImpl(doc2, isBasedOn, doc1)); statements.add(new StatementImpl(doc1, references, new ResourceImpl("http://www.wikipedia.com/Enterprise_Content_Management"))); statements.add(new StatementImpl(doc2, references, new LiteralImpl("NXRuntime"))); Collections.sort(statements); } private static String getTestFile() { String filePath = "test.rdf"; return FileUtils.getResourcePathFromContext(filePath); } @Test public void testGetGraph() { Model jenaGraph = graph.openGraph().getGraph(); Map<String, String> map = jenaGraph.getNsPrefixMap(); assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#", map.get("rdf")); assertEquals("http://purl.org/dc/terms/", map.get("dcterms")); } @Test public void testSetOptions() { Map<String, String> options = new HashMap<>(); options.put("backend", "dummy"); try { graph.setOptions(options); fail("Should have raised IllegalArgumentException"); } catch (IllegalArgumentException e) { } options.put("backend", "memory"); graph.setOptions(options); options.put("databaseDoCompressUri", "dummy"); try { graph.setOptions(options); fail("Should have raised IllegalArgumentException"); } catch (IllegalArgumentException e) { } options.put("databaseDoCompressUri", "true"); graph.setOptions(options); options.put("databaseTransactionEnabled", "dummy"); try { graph.setOptions(options); fail("Should have raised IllegalArgumentException"); } catch (IllegalArgumentException e) { } options.put("databaseTransactionEnabled", "false"); graph.setOptions(options); } @Test public void testSetNamespaces() { Map<String, String> namespaces = new HashMap<>(); namespaces.put("dummy", "http://dummy"); boolean forceReload = false; Model jenaGraph = graph.openGraph(forceReload).getGraph(); Map<String, String> map = jenaGraph.getNsPrefixMap(); // old namespaces are kept assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#", map.get("rdf")); assertEquals("http://purl.org/dc/terms/", map.get("dcterms")); assertNull(map.get("dummy")); GraphDescriptor desc = new GraphDescriptor(); desc.namespaces = namespaces; graph.setDescription(desc); // not set yet on the graph, have to rebuild it jenaGraph = graph.openGraph(forceReload).getGraph(); map = jenaGraph.getNsPrefixMap(); assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#", map.get("rdf")); assertEquals("http://purl.org/dc/terms/", map.get("dcterms")); assertNull(map.get("dummy")); // rebuild graph forceReload = true; jenaGraph = graph.openGraph(forceReload).getGraph(); map = jenaGraph.getNsPrefixMap(); // old namespaces are still set on the named graph lots assertNull(map.get("rdf")); assertNull(map.get("dcterms")); assertEquals("http://dummy", map.get("dummy")); } @Test public void testAdd() { assertSame(0L, graph.size()); graph.add(statements); assertSame(3L, graph.size()); } @Test public void testRemove() { assertSame(0L, graph.size()); graph.add(statements); assertSame(3L, graph.size()); List<Statement> stmts = new ArrayList<>(); stmts.add(new StatementImpl(doc2, references, new LiteralImpl("NXRuntime"))); graph.remove(stmts); assertSame(2L, graph.size()); } @Test public void testGetStatements() { List<Statement> stmts = new ArrayList<>(); assertEquals(stmts, graph.getStatements()); graph.add(statements); stmts = graph.getStatements(); Collections.sort(stmts); assertEquals(statements, stmts); } @Test public void testGetStatementsPattern() { List<Statement> expected = new ArrayList<>(); assertEquals(expected, graph.getStatements()); graph.add(statements); List<Statement> stmts = graph.getStatements(new StatementImpl(null, null, null)); Collections.sort(stmts); expected = statements; assertEquals(expected, stmts); stmts = graph.getStatements(new StatementImpl(doc1, null, null)); Collections.sort(stmts); expected = new ArrayList<>(); expected.add(new StatementImpl(doc1, references, new ResourceImpl("http://www.wikipedia.com/Enterprise_Content_Management"))); assertEquals(expected, stmts); stmts = graph.getStatements(new StatementImpl(null, references, null)); Collections.sort(stmts); expected = new ArrayList<>(); expected.add(new StatementImpl(doc1, references, new ResourceImpl("http://www.wikipedia.com/Enterprise_Content_Management"))); expected.add(new StatementImpl(doc2, references, new LiteralImpl("NXRuntime"))); assertEquals(expected, stmts); stmts = graph.getStatements(new StatementImpl(doc2, null, doc1)); Collections.sort(stmts); expected = new ArrayList<>(); expected.add(new StatementImpl(doc2, isBasedOn, doc1)); assertEquals(expected, stmts); // test with unknown nodes expected = new ArrayList<>(); stmts = graph.getStatements(new StatementImpl(new ResourceImpl("http://subject"), new ResourceImpl("http://propertty"), new ResourceImpl("http://object"))); assertEquals(expected, stmts); stmts = graph.getStatements( new StatementImpl(new ResourceImpl("http://subject"), null, new LiteralImpl("literal"))); assertEquals(expected, stmts); stmts = graph.getStatements( new StatementImpl(new ResourceImpl("http://subject"), null, new BlankImpl("blank"))); assertEquals(expected, stmts); } @Test public void testGetSubjects() { graph.add(statements); List<Node> expected; List<Node> res; res = graph.getSubjects(references, new ResourceImpl("http://www.wikipedia.com/Enterprise_Content_Management")); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc1); Collections.sort(expected); assertEquals(expected, res); res = graph.getSubjects(references, null); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc1); expected.add(doc2); Collections.sort(expected); assertEquals(expected, res); res = graph.getSubjects(null, doc1); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc2); Collections.sort(expected); assertEquals(expected, res); res = graph.getSubjects(null, null); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc1); expected.add(doc2); Collections.sort(expected); assertEquals(expected, res); } @Test public void testGetPredicates() { graph.add(statements); List<Node> expected; List<Node> res; res = graph.getPredicates(doc2, doc1); Collections.sort(res); expected = new ArrayList<>(); expected.add(isBasedOn); Collections.sort(expected); assertEquals(expected, res); res = graph.getPredicates(doc2, null); Collections.sort(res); expected = new ArrayList<>(); expected.add(isBasedOn); expected.add(references); Collections.sort(expected); assertEquals(expected, res); res = graph.getPredicates(null, doc1); Collections.sort(res); expected = new ArrayList<>(); expected.add(isBasedOn); Collections.sort(expected); assertEquals(expected, res); res = graph.getPredicates(null, null); Collections.sort(res); expected = new ArrayList<>(); expected.add(isBasedOn); expected.add(references); Collections.sort(expected); assertEquals(expected, res); } @Test public void testGetObject() { graph.add(statements); List<Node> expected; List<Node> res; res = graph.getObjects(doc2, isBasedOn); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc1); Collections.sort(expected); assertEquals(expected, res); res = graph.getObjects(doc2, null); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc1); expected.add(new LiteralImpl("NXRuntime")); Collections.sort(expected); assertEquals(expected, res); res = graph.getObjects(null, references); Collections.sort(res); expected = new ArrayList<>(); expected.add(new ResourceImpl("http://www.wikipedia.com/Enterprise_Content_Management")); expected.add(new LiteralImpl("NXRuntime")); Collections.sort(expected); assertEquals(expected, res); res = graph.getObjects(null, null); Collections.sort(res); expected = new ArrayList<>(); expected.add(doc1); expected.add(new ResourceImpl("http://www.wikipedia.com/Enterprise_Content_Management")); expected.add(new LiteralImpl("NXRuntime")); Collections.sort(expected); assertEquals(expected, res); } @Test public void testHasStatement() { graph.add(statements); assertFalse(graph.hasStatement(null)); assertTrue(graph.hasStatement(new StatementImpl(doc2, isBasedOn, doc1))); assertFalse(graph.hasStatement(new StatementImpl(doc2, isBasedOn, doc2))); assertTrue(graph.hasStatement(new StatementImpl(doc2, isBasedOn, null))); assertFalse(graph.hasStatement(new StatementImpl(null, null, doc2))); } @Test public void testHasResource() { graph.add(statements); assertFalse(graph.hasResource(null)); assertTrue(graph.hasResource(doc1)); assertFalse(graph.hasResource(new ResourceImpl("http://foo"))); } @Test public void testSize() { assertSame(0L, graph.size()); List<Statement> stmts = new ArrayList<>(); stmts.add(new StatementImpl(doc1, isBasedOn, new LiteralImpl("foo"))); graph.add(stmts); assertSame(1L, graph.size()); graph.add(statements); assertSame(4L, graph.size()); } @Test public void testClear() { assertSame(0L, graph.size()); graph.add(statements); assertSame(3L, graph.size()); graph.clear(); assertSame(0L, graph.size()); } @Test public void testQuery() { graph.add(statements); String queryString = "SELECT ?subj ?pred ?obj " + "WHERE {" + " ?subj ?pred ?obj " + " }"; QueryResult res = graph.query(queryString, "sparql", null); assertSame(3, res.getCount()); List<String> variableNames = new ArrayList<>(); variableNames.add("subj"); variableNames.add("pred"); variableNames.add("obj"); assertEquals(variableNames, res.getVariableNames()); queryString = "PREFIX dcterms: <http://purl.org/dc/terms/> " + "SELECT ?subj ?obj " + "WHERE {" + " ?subj dcterms:References ?obj ." + " }"; res = graph.query(queryString, "sparql", null); assertSame(2, res.getCount()); variableNames.remove("pred"); assertEquals(variableNames, res.getVariableNames()); } @Test public void testRead() throws Exception { InputStream in = new FileInputStream(getTestFile()); assertSame(0L, graph.size()); graph.read(in, null, null); assertNotSame(0L, graph.size()); List<Statement> statements = graph.getStatements(); Collections.sort(statements); // assertSame(statements.size(), this.statements.size()); // for (int i = 0; i < statements.size(); i++) { // assertEquals(statements.get(i), this.statements.get(i)); // } assertEquals(statements, this.statements); } @Test public void testReadPath() { assertSame(0L, graph.size()); graph.read(getTestFile(), null, null); assertNotSame(0L, graph.size()); List<Statement> statements = graph.getStatements(); Collections.sort(statements); // assertSame(statements.size(), this.statements.size()); // for (int i = 0; i < statements.size(); i++) { // assertEquals(statements.get(i), this.statements.get(i)); // } assertEquals(statements, this.statements); } @Test public void testWrite() throws Exception { graph.add(statements); ByteArrayOutputStream out = new ByteArrayOutputStream(); graph.write(out, null, null); try (InputStream written = new ByteArrayInputStream(out.toByteArray()); InputStream expected = new FileInputStream(getTestFile())) { assertEquals(IOUtils.toString(expected, Charsets.UTF_8).replaceAll("\r?\n", ""), IOUtils.toString(written, Charsets.UTF_8).replaceAll("\r?\n", "")); } } @Test public void testWritePath() throws Exception { graph.add(statements); File file = Framework.createTempFile("test", ".rdf"); String path = file.getPath(); graph.write(path, null, null); try (InputStream written = new FileInputStream(new File(path)); InputStream expected = new FileInputStream(getTestFile())) { String expectedString = IOUtils.toString(expected, Charsets.UTF_8).replaceAll("\r?\n", ""); String writtenString = IOUtils.toString(written, Charsets.UTF_8).replaceAll("\r?\n", ""); assertEquals(expectedString, writtenString); } } // XXX AT: test serialization of the graph because the RelationServiceBean // will attempt to keep references to graphs it manages. @Test public void testSerialization() throws Exception { graph.add(statements); // serialize ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(graph); oos.close(); assertTrue(out.toByteArray().length > 0); // deserialize byte[] pickled = out.toByteArray(); InputStream in = new ByteArrayInputStream(pickled); ObjectInputStream ois = new ObjectInputStream(in); Object o = ois.readObject(); JenaGraph newGraph = (JenaGraph) o; // new graph has same properties than old one but statements are lost // because they were stored in a memory graph assertSame(0L, newGraph.size()); Model newModel = newGraph.openGraph().getGraph(); Map<String, String> map = newModel.getNsPrefixMap(); assertEquals("http://www.w3.org/1999/02/22-rdf-syntax-ns#", map.get("rdf")); assertEquals("http://purl.org/dc/terms/", map.get("dcterms")); } }