/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package org.apache.jena.rdf.model.impl; import java.io.*; import java.util.Locale ; import org.apache.jena.rdf.model.* ; import org.apache.jena.shared.* ; import org.apache.jena.util.FileUtils ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** Writes out an XML serialization of a model. */ public class NTripleWriter extends Object implements RDFWriter { RDFErrorHandler errorHandler = new RDFDefaultErrorHandler(); protected static Logger logger = LoggerFactory.getLogger( NTripleWriter.class ); public NTripleWriter() { } @Override public void write(Model model, OutputStream out, String base) { try { Writer w; try { w = new OutputStreamWriter(out, "ascii"); } catch (UnsupportedEncodingException e) { logger.warn( "ASCII is not supported: in NTripleWriter.write", e ); w = FileUtils.asUTF8(out); } write(model, w, base); w.flush(); } catch (Exception ioe) { errorHandler.error(ioe); } } @Override public void write(Model model, Writer writer, String base) { try { PrintWriter pw; if (writer instanceof PrintWriter) { pw = (PrintWriter) writer; } else { pw = new PrintWriter(writer); } StmtIterator iter = model.listStatements(); Statement stmt = null; while (iter.hasNext()) { stmt = iter.nextStatement(); writeResource(stmt.getSubject(), pw); pw.print(" "); writeResource(stmt.getPredicate(), pw); pw.print(" "); writeNode(stmt.getObject(), pw); pw.println(" ."); } pw.flush(); } catch (Exception e) { errorHandler.error(e); } } /** Set a property to control the writer's behaviour. * * <p>This writer currently recognises no properties. Invoking this * method always causes an <CODE>UnknownPropertyException</CODE> * to be raised.</p>? * @param propName The name of the property to be set * @param propValue The new value of the property * @return the previous value of the property */ @Override public Object setProperty(String propName, Object propValue) { throw new UnknownPropertyException( propName ); } public void setNsPrefix(String prefix, String ns) { } public String getPrefixFor( String uri ) { return null; } @Override public RDFErrorHandler setErrorHandler(RDFErrorHandler errHandler) { RDFErrorHandler old = this.errorHandler; this.errorHandler = errHandler; return old; } public static void write(Model model, PrintWriter writer) { StmtIterator iter = model.listStatements(); Statement stmt = null; while (iter.hasNext()) { stmt = iter.nextStatement(); writeResource(stmt.getSubject(), writer); writer.print(" "); writeResource(stmt.getPredicate(), writer); writer.print(" "); writeNode(stmt.getObject(), writer); writer.println(" ."); } } protected static void writeResource(Resource r, PrintWriter writer) { if (r.isAnon()) { writer.print(anonName(r.getId())); } else { writer.print("<"); writeURIString(r.getURI(), writer); writer.print(">"); } } static private boolean okURIChars[] = new boolean[128]; static { for (int i = 32; i < 127; i++) okURIChars[i] = true; okURIChars['<'] = false; okURIChars['>'] = false; okURIChars['\\'] = false; } private static void writeURIString(String s, PrintWriter writer) { for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c < okURIChars.length && okURIChars[c]) { writer.print(c); } else { String hexstr = Integer.toHexString(c).toUpperCase(Locale.ENGLISH); int pad = 4 - hexstr.length(); writer.print("\\u"); for (; pad > 0; pad--) writer.print("0"); writer.print(hexstr); } } } private static void writeString(String s, PrintWriter writer) { for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '\\' || c == '"') { writer.print('\\'); writer.print(c); } else if (c == '\n') { writer.print("\\n"); } else if (c == '\r') { writer.print("\\r"); } else if (c == '\t') { writer.print("\\t"); } else if (c >= 32 && c < 127) { writer.print(c); } else { String hexstr = Integer.toHexString(c).toUpperCase(); int pad = 4 - hexstr.length(); writer.print("\\u"); for (; pad > 0; pad--) writer.print("0"); writer.print(hexstr); } } } protected static void writeLiteral(Literal l, PrintWriter writer) { String s = l.getString(); /* if (l.getWellFormed()) writer.print("xml"); */ writer.print('"'); writeString(s, writer); writer.print('"'); String lang = l.getLanguage(); if (lang != null && !lang.equals("")) writer.print("@" + lang); String dt = l.getDatatypeURI(); if (dt != null && !dt.equals("")) writer.print("^^<" + dt + ">"); } protected static void writeNode(RDFNode n, PrintWriter writer) { if (n instanceof Literal) { writeLiteral((Literal) n, writer); } else { writeResource((Resource) n, writer); } } protected static String anonName(AnonId id) { String name = "_:A"; String sid = id.toString(); for (int i = 0; i < sid.length(); i++) { char c = sid.charAt(i); if (c == 'X') { name = name + "XX"; } else if (Character.isLetterOrDigit(c)) { name = name + c; } else { name = name + "X" + Integer.toHexString(c) + "X"; } } return name; } }