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