/******************************************************************************* * Copyright 2014 University of Southern California * * 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. * * This code was developed by the Information Integration Group as part * of the Karma project at the Information Sciences Institute of the * University of Southern California. For more information, publications, * and related projects, please see: http://www.isi.edu/integration ******************************************************************************/ package edu.isi.karma.kr2rml.writer; import java.io.OutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.text.translate.UnicodeUnescaper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import edu.isi.karma.kr2rml.PredicateObjectMap; import edu.isi.karma.kr2rml.URIFormatter; import edu.isi.karma.kr2rml.mapping.R2RMLMappingIdentifier; public class N3KR2RMLRDFWriter extends KR2RMLRDFWriter { private static final Logger LOG = LoggerFactory.getLogger(N3KR2RMLRDFWriter.class); protected URIFormatter uriFormatter; protected PrintWriter outWriter; protected Map<String,String> generatedTriples; String baseURI; public N3KR2RMLRDFWriter(URIFormatter uriFormatter, OutputStream outputStream) { this.outWriter = new PrintWriter(outputStream); this.uriFormatter = uriFormatter; generatedTriples = new ConcurrentHashMap<>(); baseURI = null; } public N3KR2RMLRDFWriter(URIFormatter uriFormatter, PrintWriter writer) { this.outWriter =writer; this.uriFormatter = uriFormatter; generatedTriples = new ConcurrentHashMap<>(); } private void outputTriple(String triple) { generatedTriples.put(triple, ""); } @Override public void outputTripleWithURIObject(String subjUri, String predicateUri, String objectUri) { outputTriple(constructTripleWithURIObject(subjUri, predicateUri, objectUri)); } private String constructTripleWithURIObject(String subjUri, String predicateUri, String objectUri) { if (subjUri.indexOf("<") != -1 && subjUri.indexOf(">") != -1) { String tmp = subjUri.substring(1, subjUri.length() - 1); subjUri = "<" + normalizeURI(tmp) + ">"; } if (objectUri.indexOf("<") != -1 && objectUri.indexOf(">") != -1) { String tmp = objectUri.substring(1, objectUri.length() - 1); objectUri = "<" + normalizeURI(tmp) + ">"; } return subjUri + " " + uriFormatter.getExpandedAndNormalizedUri(predicateUri) + " " + objectUri + " ."; } @Override public void outputTripleWithLiteralObject(String subjUri, String predicateUri, String value, String literalType, String language) { outputTriple(constructTripleWithLiteralObject(subjUri, predicateUri, value, literalType, language)); } private String constructTripleWithLiteralObject(String subjUri, String predicateUri, String value, String literalType, String language) { value = escapeValue(value); if (subjUri.indexOf("<") != -1 && subjUri.indexOf(">") != -1) { String tmp = subjUri.substring(1, subjUri.length() - 1); subjUri = "<" + normalizeURI(tmp) + ">"; } //https://www.w3.org/TeamSubmission/turtle/ - Literals may be given either a language suffix or a datatype URI but not both if(language != null && !language.equals("")) { return subjUri + " " + uriFormatter.getExpandedAndNormalizedUri(predicateUri) + " \"" + value + "\"" + "@" + language + " ."; } else if (literalType != null && !literalType.equals("")) { // Add the RDF literal type to the literal if present return subjUri + " " + uriFormatter.getExpandedAndNormalizedUri(predicateUri) + " \"" + value + "\"" + "^^<" + literalType + "> ."; } return subjUri + " " + uriFormatter.getExpandedAndNormalizedUri(predicateUri) + " \"" + value + "\" ."; } private String escapeValue(String value) { // Use Apache Commons to escape the value String result = StringEscapeUtils.escapeJava(value); //The above also encodes unicode characters to \u0048\u0065\u006C\u006C etc sequences. To remove that, we do return new UnicodeUnescaper().translate(result); } @Override public void outputQuadWithLiteralObject(String subjUri, String predicateUri, String value, String literalType, String language, String graph) { outputTriple(constructQuadWithLiteralObject(subjUri, predicateUri, value, literalType, language, graph)); } private String constructQuadWithLiteralObject(String subjUri, String predicateUri, String value, String literalType, String language, String graph) { String triple = constructTripleWithLiteralObject(subjUri, predicateUri, value, literalType, language); if (triple.length() > 2) return triple.substring(0, triple.length()-1) + "<" + graph + "> ." ; else return ""; } @Override public void outputTripleWithURIObject(PredicateObjectMap predicateObjectMap, String subjUri, String predicateUri, String objectUri) { outputTripleWithURIObject(subjUri, predicateUri, objectUri); } @Override public void outputTripleWithLiteralObject(PredicateObjectMap predicateObjectMap, String subjUri, String predicateUri, String value, String literalType, String language) { outputTripleWithLiteralObject(subjUri, predicateUri, value, literalType, language); } @Override public void outputQuadWithLiteralObject(PredicateObjectMap predicateObjectMap, String subjUri, String predicateUri, String value, String literalType, String language, String graph) { outputQuadWithLiteralObject(subjUri, predicateUri, value, literalType, language, graph); } @Override public void finishRow() { for(String value : generatedTriples.keySet()) { outWriter.println(value); } outWriter.println(""); generatedTriples = new ConcurrentHashMap<>(); } @Override public void flush() { LOG.debug("Flushing writer"); for(String value : generatedTriples.keySet()) { outWriter.println(value); } outWriter.flush(); LOG.debug("Flushed writer"); } @Override public void close() { outWriter.close(); } private String normalizeURI(String URI) { try { URI = URI.replace(" ", ""); URI uri = new URI(URI); if (!uri.isAbsolute() && baseURI != null) return baseURI + URI; }catch(URISyntaxException e) { if (baseURI != null) return baseURI + URI; else return URI; } return URI; } public void setBaseURI(String baseURI) { this.baseURI = baseURI; } @Override public void setR2RMLMappingIdentifier( R2RMLMappingIdentifier mappingIdentifer) { } }