001: /*
002: * (c) Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Hewlett-Packard Development Company, LP
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: * 1. Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * 3. The name of the author may not be used to endorse or promote products
014: * derived from this software without specific prior written permission.
015:
016: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
017: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
018: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
019: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
020: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
021: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
022: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
023: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
024: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
025: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
026: *
027: * $Id: NTripleWriter.java,v 1.21 2008/01/02 12:05:06 andy_seaborne Exp $
028: */
029:
030: package com.hp.hpl.jena.rdf.model.impl;
031:
032: import com.hp.hpl.jena.rdf.model.*;
033: import com.hp.hpl.jena.util.FileUtils;
034: import com.hp.hpl.jena.shared.*;
035:
036: import java.io.*;
037:
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040:
041: /** Writes out an XML serialization of a model.
042: *
043: * @author bwm
044: * @version Release='$Name: $' Revision='$Revision: 1.21 $' Date='$Date: 2008/01/02 12:05:06 $'
045: */
046: public class NTripleWriter extends Object implements RDFWriter {
047:
048: RDFErrorHandler errorHandler = new RDFDefaultErrorHandler();
049:
050: protected static Log logger = LogFactory
051: .getLog(NTripleWriter.class);
052:
053: public NTripleWriter() {
054: }
055:
056: public void write(Model model, OutputStream out, String base) {
057: try {
058: Writer w;
059: try {
060: w = new OutputStreamWriter(out, "ascii");
061: } catch (UnsupportedEncodingException e) {
062: logger
063: .warn(
064: "ASCII is not supported: in NTripleWriter.write",
065: e);
066: w = FileUtils.asUTF8(out);
067: }
068: write(model, w, base);
069: w.flush();
070:
071: } catch (Exception ioe) {
072: errorHandler.error(ioe);
073: }
074: }
075:
076: public void write(Model baseModel, Writer writer, String base) {
077: try {
078: Model model = ModelFactory.withHiddenStatements(baseModel);
079: PrintWriter pw;
080: if (writer instanceof PrintWriter) {
081: pw = (PrintWriter) writer;
082: } else {
083: pw = new PrintWriter(writer);
084: }
085:
086: StmtIterator iter = model.listStatements();
087: Statement stmt = null;
088:
089: while (iter.hasNext()) {
090: stmt = iter.nextStatement();
091: writeResource(stmt.getSubject(), pw);
092: pw.print(" ");
093: writeResource(stmt.getPredicate(), pw);
094: pw.print(" ");
095: writeNode(stmt.getObject(), pw);
096: pw.println(" .");
097: }
098: pw.flush();
099: } catch (Exception e) {
100: errorHandler.error(e);
101: }
102: }
103:
104: /** Set a property to control the writer's behaviour.
105: *
106: * <p>This writer currently recognises no properties. Invoking this
107: * method always causes an <CODE>UnknownPropertyException</CODE>
108: * to be raised.</p>?
109: * @param propName The name of the property to be set
110: * @param propValue The new value of the property
111: * @return the previous value of the property
112: */
113: public Object setProperty(String propName, Object propValue) {
114: throw new UnknownPropertyException(propName);
115: }
116:
117: public void setNsPrefix(String prefix, String ns) {
118: }
119:
120: public String getPrefixFor(String uri) {
121: return null;
122: }
123:
124: public RDFErrorHandler setErrorHandler(RDFErrorHandler errHandler) {
125: RDFErrorHandler old = this .errorHandler;
126: this .errorHandler = errHandler;
127: return old;
128: }
129:
130: public static void write(Model model, PrintWriter writer)
131: throws java.io.IOException {
132: StmtIterator iter = model.listStatements();
133: Statement stmt = null;
134:
135: while (iter.hasNext()) {
136: stmt = iter.nextStatement();
137: writeResource(stmt.getSubject(), writer);
138: writer.print(" ");
139: writeResource(stmt.getPredicate(), writer);
140: writer.print(" ");
141: writeNode(stmt.getObject(), writer);
142: writer.println(" .");
143: }
144: }
145:
146: protected static void writeResource(Resource r, PrintWriter writer) {
147: if (r.isAnon()) {
148: writer.print(anonName(r.getId()));
149: } else {
150: writer.print("<");
151: writeURIString(r.getURI(), writer);
152: writer.print(">");
153: }
154: }
155:
156: static private boolean okURIChars[] = new boolean[128];
157: static {
158: for (int i = 32; i < 127; i++)
159: okURIChars[i] = true;
160: okURIChars['<'] = false;
161: okURIChars['>'] = false;
162: okURIChars['\\'] = false;
163:
164: }
165:
166: private static void writeURIString(String s, PrintWriter writer) {
167:
168: for (int i = 0; i < s.length(); i++) {
169: char c = s.charAt(i);
170: if (c < okURIChars.length && okURIChars[c]) {
171: writer.print(c);
172: } else {
173: String hexstr = Integer.toHexString(c).toUpperCase();
174: int pad = 4 - hexstr.length();
175: writer.print("\\u");
176: for (; pad > 0; pad--)
177: writer.print("0");
178: writer.print(hexstr);
179: }
180: }
181: }
182:
183: private static void writeString(String s, PrintWriter writer) {
184:
185: for (int i = 0; i < s.length(); i++) {
186: char c = s.charAt(i);
187: if (c == '\\' || c == '"') {
188: writer.print('\\');
189: writer.print(c);
190: } else if (c == '\n') {
191: writer.print("\\n");
192: } else if (c == '\r') {
193: writer.print("\\r");
194: } else if (c == '\t') {
195: writer.print("\\t");
196: } else if (c >= 32 && c < 127) {
197: writer.print(c);
198: } else {
199: String hexstr = Integer.toHexString(c).toUpperCase();
200: int pad = 4 - hexstr.length();
201: writer.print("\\u");
202: for (; pad > 0; pad--)
203: writer.print("0");
204: writer.print(hexstr);
205: }
206: }
207: }
208:
209: protected static void writeLiteral(Literal l, PrintWriter writer) {
210: String s = l.getString();
211: /*
212: if (l.getWellFormed())
213: writer.print("xml");
214: */
215: writer.print('"');
216: writeString(s, writer);
217: writer.print('"');
218: String lang = l.getLanguage();
219: if (lang != null && !lang.equals(""))
220: writer.print("@" + lang);
221: String dt = l.getDatatypeURI();
222: if (dt != null && !dt.equals(""))
223: writer.print("^^<" + dt + ">");
224: }
225:
226: protected static void writeNode(RDFNode n, PrintWriter writer) {
227: if (n instanceof Literal) {
228: writeLiteral((Literal) n, writer);
229: } else {
230: writeResource((Resource) n, writer);
231: }
232: }
233:
234: protected static String anonName(AnonId id) {
235: String name = "_:A";
236: String sid = id.toString();
237: for (int i = 0; i < sid.length(); i++) {
238: char c = sid.charAt(i);
239: if (c == 'X') {
240: name = name + "XX";
241: } else if (Character.isLetterOrDigit(c)) {
242: name = name + c;
243: } else {
244: name = name + "X" + Integer.toHexString((int) c) + "X";
245: }
246: }
247: return name;
248: }
249: }
|