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.camel.processor; 017 018import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel; 019import static org.fcrepo.camel.processor.ProcessorUtils.langFromMimeType; 020import static java.net.URLEncoder.encode; 021 022import java.io.ByteArrayOutputStream; 023import java.io.InputStream; 024import java.io.IOException; 025 026import com.hp.hpl.jena.rdf.model.Model; 027import org.apache.camel.Exchange; 028import org.apache.camel.Message; 029import org.apache.camel.Processor; 030import org.fcrepo.camel.FcrepoHeaders; 031 032/** 033 * Represents a processor for creating the sparql-update message to 034 * be passed to an external triplestore. 035 * 036 * @author Aaron Coburn 037 * @since Nov 8, 2014 038 */ 039public class SparqlUpdateProcessor implements Processor { 040 /** 041 * Define how the message is processed. 042 * 043 * @param exchange the current camel message exchange 044 */ 045 public void process(final Exchange exchange) throws IOException { 046 047 final Message in = exchange.getIn(); 048 049 final ByteArrayOutputStream serializedGraph = new ByteArrayOutputStream(); 050 final String subject = ProcessorUtils.getSubjectUri(in); 051 final String namedGraph = in.getHeader(FcrepoHeaders.FCREPO_NAMED_GRAPH, String.class); 052 final Model model = createDefaultModel().read(in.getBody(InputStream.class), subject, 053 langFromMimeType(in.getHeader(Exchange.CONTENT_TYPE, String.class))); 054 055 model.write(serializedGraph, "N-TRIPLE"); 056 057 /* 058 * Before inserting updated triples, the Sparql update command 059 * below deletes all triples with the defined subject uri 060 * (coming from the FCREPO_IDENTIFIER and FCREPO_BASE_URL headers). 061 * It also deletes triples that have a subject corresponding to 062 * that Fcrepo URI plus the "/fcr:export?format=jcr/xml" string 063 * appended to it. This makes it possible to more completely 064 * remove any triples for a given resource that were added 065 * earlier. If fcrepo ever stops producing triples that are 066 * appended with /fcr:export?format..., then that extra line 067 * can be removed. It would also be possible to recursively delete 068 * triples (by removing any triple whose subject is also an object 069 * of the starting (or context) URI, but that approach tends to 070 * delete too many triples from the triplestore. This command does 071 * not delete blank nodes. 072 */ 073 final StringBuilder query = new StringBuilder(); 074 query.append(ProcessorUtils.deleteWhere(subject, namedGraph)); 075 query.append(";\n"); 076 query.append(ProcessorUtils.deleteWhere(subject + "/fcr:export?format=jcr/xml", namedGraph)); 077 query.append(";\n"); 078 query.append(ProcessorUtils.insertData(serializedGraph.toString("UTF-8"), namedGraph)); 079 080 in.setBody("update=" + encode(query.toString(), "UTF-8")); 081 in.setHeader(Exchange.HTTP_METHOD, "POST"); 082 in.setHeader(Exchange.CONTENT_TYPE, "application/x-www-form-urlencoded; charset=utf-8"); 083 } 084}