001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.integration.rdf; 019 020import org.apache.jena.datatypes.xsd.XSDDatatype; 021import org.apache.jena.graph.Graph; 022import org.apache.jena.graph.Node; 023import org.apache.jena.graph.Triple; 024import org.apache.jena.query.Dataset; 025import org.apache.jena.rdf.model.Model; 026import org.apache.jena.rdf.model.ModelFactory; 027import org.apache.jena.sparql.core.DatasetGraph; 028import org.apache.jena.sparql.graph.GraphFactory; 029import org.apache.jena.util.iterator.ExtendedIterator; 030import org.apache.commons.io.IOUtils; 031import org.apache.http.HttpResponse; 032import org.apache.http.client.methods.HttpGet; 033import org.apache.http.client.methods.HttpPut; 034import org.apache.http.entity.BasicHttpEntity; 035import org.apache.jena.riot.RDFDataMgr; 036import org.apache.jena.riot.RDFLanguages; 037import org.fcrepo.integration.http.api.AbstractResourceIT; 038 039import javax.ws.rs.core.Response; 040import java.io.ByteArrayOutputStream; 041import java.io.IOException; 042import java.util.HashMap; 043import java.util.Map; 044 045import static java.nio.charset.StandardCharsets.UTF_8; 046import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE; 047import static javax.ws.rs.core.Response.Status.CREATED; 048import static org.apache.jena.graph.NodeFactory.createBlankNode; 049import static org.apache.jena.graph.NodeFactory.createLiteral; 050import static org.junit.Assert.assertEquals; 051import static org.junit.Assert.assertFalse; 052import static org.junit.Assert.assertTrue; 053 054/** 055 * @author cabeer 056 * @author ajs6f 057 */ 058public abstract class AbstractIntegrationRdfIT extends AbstractResourceIT { 059 060 protected HttpResponse createLDPRSAndCheckResponse(final String pid, final String body) { 061 try { 062 final HttpPut httpPut = new HttpPut(serverAddress + pid); 063 httpPut.addHeader("Slug", pid); 064 httpPut.addHeader(CONTENT_TYPE, "text/turtle"); 065 final BasicHttpEntity e = new BasicHttpEntity(); 066 e.setContent(IOUtils.toInputStream(body, UTF_8)); 067 httpPut.setEntity(e); 068 final HttpResponse response = client.execute(httpPut); 069 checkResponse(response, CREATED); 070 071 final String location = response.getFirstHeader("Location").getValue(); 072 073 final HttpGet httpGet = new HttpGet(location); 074 httpGet.addHeader("Prefer", "return=representation; " + 075 "include=\"http://www.w3.org/ns/ldp#PreferMinimalContainer\"; " + 076 "omit=\"http://fedora.info/definitions/v4/repository#ServerManaged\""); 077 final Dataset dataset = getDataset(httpGet); 078 079 final DatasetGraph graphStore = dataset.asDatasetGraph(); 080 assertFalse(graphStore.isEmpty()); 081 082 final Graph tidiedGraph = getTidiedGraph(graphStore); 083 final Model expected = ModelFactory.createDefaultModel().read( 084 IOUtils.toInputStream(body, UTF_8), location, "TTL"); 085 086 final boolean isomorphicWith = tidiedGraph.isIsomorphicWith(getTidiedGraph(expected.getGraph())); 087 088 final String description; 089 090 if (!isomorphicWith) { 091 final ByteArrayOutputStream o = new ByteArrayOutputStream(); 092 093 final Model tidiedModel = ModelFactory.createModelForGraph(tidiedGraph); 094 tidiedModel.setNsPrefixes(expected.getNsPrefixMap()); 095 o.write("Expected: ".getBytes()); 096 RDFDataMgr.write(o, expected, RDFLanguages.TTL); 097 o.write("to be isomorphic with: ".getBytes()); 098 RDFDataMgr.write(o, tidiedModel, RDFLanguages.TTL); 099 description = IOUtils.toString(o.toByteArray(), "UTF-8"); 100 } else { 101 description = ""; 102 } 103 104 105 assertTrue(description, isomorphicWith); 106 107 return response; 108 } catch (final IOException e) { 109 assertTrue("Got IOException " + e, false); 110 return null; 111 } 112 } 113 114 private static Graph getTidiedGraph(final DatasetGraph graph) { 115 return getTidiedGraph(graph.getDefaultGraph()); 116 } 117 118 private static Graph getTidiedGraph(final Graph graph) { 119 final Graph betterGraph = GraphFactory.createDefaultGraph(); 120 final ExtendedIterator<Triple> triples = graph.find(Node.ANY, Node.ANY, Node.ANY); 121 final Map<Node, Node> bnodeMap = new HashMap<>(); 122 123 while (triples.hasNext()) { 124 final Triple next = triples.next(); 125 126 Triple replacement = next; 127 128 if (replacement.getSubject().toString().contains(".well-known")) { 129 if (!bnodeMap.containsKey(replacement.getSubject())) { 130 bnodeMap.put(replacement.getSubject(), createBlankNode()); 131 } 132 133 replacement = new Triple(bnodeMap.get(replacement.getSubject()), 134 replacement.getPredicate(), 135 replacement.getObject()); 136 } 137 138 if (replacement.getObject().toString().contains(".well-known")) { 139 140 if (!bnodeMap.containsKey(replacement.getObject())) { 141 bnodeMap.put(replacement.getObject(), createBlankNode()); 142 } 143 144 replacement = new Triple(replacement.getSubject(), 145 replacement.getPredicate(), 146 bnodeMap.get(replacement.getObject())); 147 } 148 149 if (replacement.getObject().isLiteral() 150 && replacement.getObject().getLiteral().getDatatype() != null 151 && replacement.getObject().getLiteral().getDatatype().equals(XSDDatatype.XSDstring)) { 152 replacement = new Triple(replacement.getSubject(), 153 replacement.getPredicate(), 154 createLiteral(replacement.getObject().getLiteral().getLexicalForm())); 155 } 156 157 betterGraph.add(replacement); 158 } 159 return betterGraph; 160 } 161 162 protected void checkResponse(final HttpResponse response, final Response.StatusType expected) { 163 final int actual = response.getStatusLine().getStatusCode(); 164 assertEquals("Didn't get a CREATED response!", expected.getStatusCode(), actual); 165 } 166 167 protected String getContentFromClasspath(final String path) throws IOException { 168 return IOUtils.toString(this.getClass().getResourceAsStream(path), UTF_8); 169 } 170 171 172}