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.camel.processor; 019 020import static org.apache.camel.Exchange.CONTENT_TYPE; 021import static org.apache.camel.Exchange.HTTP_METHOD; 022import static org.apache.http.entity.ContentType.parse; 023import static org.apache.jena.rdf.model.ResourceFactory.createProperty; 024import static org.apache.jena.rdf.model.ResourceFactory.createResource; 025import static org.apache.jena.rdf.model.ResourceFactory.createStatement; 026import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel; 027import static org.apache.jena.riot.RDFDataMgr.read; 028import static org.apache.jena.riot.RDFDataMgr.write; 029import static org.apache.jena.riot.RDFFormat.JSONLD; 030import static org.apache.jena.riot.RDFLanguages.contentTypeToLang; 031import static org.fcrepo.camel.processor.ProcessorUtils.getSubjectUri; 032 033import java.io.ByteArrayOutputStream; 034import java.io.InputStream; 035import java.io.IOException; 036import java.util.concurrent.atomic.AtomicInteger; 037 038import org.apache.jena.rdf.model.Model; 039import org.apache.jena.rdf.model.Property; 040import org.apache.jena.rdf.model.Resource; 041import org.apache.camel.Exchange; 042import org.apache.camel.Message; 043import org.apache.camel.NoSuchHeaderException; 044import org.apache.camel.Processor; 045 046/** 047 * Converts a Fedora Message into a format suitable for a LDN receiver. 048 * See: http://www.w3.org/TR/ldn/ 049 * 050 * @author acoburn 051 */ 052public class LdnProcessor implements Processor { 053 054 private static final String PROV = "http://www.w3.org/ns/prov#"; 055 056 private static final Property wasAssociatedWith = createProperty(PROV + "wasAssociatedWith"); 057 private static final Property wasAttributedTo = createProperty(PROV + "wasAttributedTo"); 058 private static final Property wasGeneratedBy = createProperty(PROV + "wasGeneratedBy"); 059 private static final Property used = createProperty(PROV + "used"); 060 061 /** 062 * Process the Fedora message 063 * 064 * @param exchange the current camel message exchange 065 */ 066 public void process(final Exchange exchange) throws IOException, NoSuchHeaderException { 067 final Message in = exchange.getIn(); 068 final Model model = createDefaultModel(); 069 final Model newModel = createDefaultModel(); 070 final Resource resource = createResource(getSubjectUri(exchange)); 071 final Resource event = createResource(""); 072 final AtomicInteger counter = new AtomicInteger(); 073 final ByteArrayOutputStream serializedGraph = new ByteArrayOutputStream(); 074 075 read(model, in.getBody(InputStream.class), 076 contentTypeToLang(parse(in.getHeader(CONTENT_TYPE, String.class)).getMimeType())); 077 078 newModel.add(createStatement(event, used, resource)); 079 model.listObjectsOfProperty(resource, wasGeneratedBy).forEachRemaining(obj -> { 080 if (obj.isResource()) { 081 obj.asResource().listProperties().forEachRemaining(stmt -> { 082 newModel.add(createStatement(event, stmt.getPredicate(), stmt.getObject())); 083 }); 084 } 085 }); 086 model.listObjectsOfProperty(resource, wasAttributedTo).forEachRemaining(obj -> { 087 final Resource agent = createResource("#agent" + Integer.toString(counter.getAndIncrement())); 088 if (obj.isResource()) { 089 obj.asResource().listProperties().forEachRemaining(stmt -> { 090 newModel.add(createStatement(agent, stmt.getPredicate(), stmt.getObject())); 091 }); 092 } 093 newModel.add(createStatement(event, wasAssociatedWith, agent)); 094 }); 095 096 write(serializedGraph, newModel, JSONLD); 097 in.setBody(serializedGraph.toString("UTF-8")); 098 in.setHeader(HTTP_METHOD, "POST"); 099 in.setHeader(CONTENT_TYPE, "application/ld+json"); 100 } 101}