001 /* 002 * (c) Copyright 2009 University of Bristol 003 * All rights reserved. 004 * [See end of file] 005 */ 006 007 package net.rootdev.javardfa.output; 008 009 import java.io.OutputStream; 010 import java.io.OutputStreamWriter; 011 import java.io.PrintWriter; 012 import java.io.UnsupportedEncodingException; 013 import java.io.Writer; 014 import java.util.regex.Pattern; 015 import net.rootdev.javardfa.StatementSink; 016 017 018 /** 019 * A pretty ropey NTriple serialiser. 020 * Advantages: streams, no dependencies. 021 * 022 * @author pldms 023 */ 024 public class NTripleSink implements StatementSink { 025 protected final PrintWriter out; 026 protected final String[] comments; 027 028 public NTripleSink(OutputStream os, String... comments) throws UnsupportedEncodingException { 029 this(new OutputStreamWriter(os, "US-ASCII"), comments); // N-Triples is 7-bit ascii 030 } 031 032 public NTripleSink(Writer writer, String... comments) { 033 this.out = new PrintWriter(writer); 034 this.comments = comments; 035 } 036 037 public void start() { 038 for (String line: comments) { 039 out.print("# "); 040 out.println(line); 041 } 042 } 043 044 public void end() { 045 out.flush(); 046 } 047 048 public void addObject(String subject, String predicate, String object) { 049 out.print(toNode(subject)); 050 out.print(toNode(predicate)); 051 out.print(toNode(object)); 052 out.println("."); 053 } 054 055 public void addLiteral(String subject, String predicate, String lex, String lang, String datatype) { 056 out.print(toNode(subject)); 057 out.print(toNode(predicate)); 058 out.print(toLiteral(lex, lang, datatype)); 059 out.println("."); 060 } 061 062 public void addPrefix(String prefix, String uri) {} 063 064 protected final String toNode(String node) { 065 if (node.startsWith("_:") || node.startsWith("?")) 066 return node + " "; 067 return "<" + node + "> "; 068 } 069 070 protected final String toLiteral(String lex, String lang, String datatype) { 071 if (lang != null && lang.length() != 0) 072 return quote(lex) + "@" + lang + " "; 073 if (datatype != null) 074 return quote(lex) + "^^<" + datatype + "> "; 075 return quote(lex) + " "; 076 } 077 078 private Pattern quotePattern = Pattern.compile("\""); 079 protected final String quote(String lex) { 080 return "\"" + encode(lex) + "\""; 081 } 082 083 protected final String encode(String s) { 084 StringBuilder b = new StringBuilder(); 085 for (int i = 0; i < s.length(); i++) { 086 int c = s.codePointAt(i); 087 if (c <= 8) b.append(enc(c)); 088 else if (c == '\t') b.append("\\t"); 089 else if (c == '\n') b.append("\\n"); 090 else if (c == '\r') b.append("\\r"); 091 else if (c == '"') b.append("\\\""); 092 else if (c == '\\') b.append("\\\\"); 093 else if (c <= 127) b.appendCodePoint(c); 094 else if (c <= 0xFFFF) b.append(enc(c)); 095 else b.append(longenc(c)); 096 } 097 return b.toString(); 098 } 099 100 protected String enc(int codepoint) { 101 return String.format("\\u%04x", codepoint); 102 } 103 104 protected String longenc(int codepoint) { 105 return String.format("\\U%08x", codepoint); 106 } 107 108 public void setBase(String base) {} 109 } 110 111 /* 112 * (c) Copyright 2009 University of Bristol 113 * All rights reserved. 114 * 115 * Redistribution and use in source and binary forms, with or without 116 * modification, are permitted provided that the following conditions 117 * are met: 118 * 1. Redistributions of source code must retain the above copyright 119 * notice, this list of conditions and the following disclaimer. 120 * 2. Redistributions in binary form must reproduce the above copyright 121 * notice, this list of conditions and the following disclaimer in the 122 * documentation and/or other materials provided with the distribution. 123 * 3. The name of the author may not be used to endorse or promote products 124 * derived from this software without specific prior written permission. 125 * 126 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 127 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 128 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 129 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 130 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 131 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 132 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 133 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 134 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 135 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 136 */