package com.mysema.rdfbean.model.io;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import javax.annotation.Nullable;
import com.mysema.commons.l10n.support.LocaleUtil;
import com.mysema.rdfbean.model.BID;
import com.mysema.rdfbean.model.LIT;
import com.mysema.rdfbean.model.NODE;
import com.mysema.rdfbean.model.RDF;
import com.mysema.rdfbean.model.RepositoryException;
import com.mysema.rdfbean.model.STMT;
import com.mysema.rdfbean.model.UID;
/**
* @author tiwe
*
*/
public class TurtleWriter implements RDFWriter {
protected final Appendable appendable;
private final boolean blankNodeAsURI;
private final Map<String, String> prefixes;
@Nullable
protected STMT last;
public TurtleWriter(Appendable writer, Map<String, String> prefixes) {
this(writer, prefixes, false);
}
public TurtleWriter(Appendable writer, Map<String, String> prefixes, boolean blankNodeAsURI) {
this.appendable = writer;
this.prefixes = prefixes;
this.blankNodeAsURI = blankNodeAsURI;
}
protected void append(BID bid) throws IOException {
if (blankNodeAsURI) {
appendable.append("<_:").append(bid.getValue()).append(">");
} else {
appendable.append("_:").append(bid.getValue());
}
}
protected void append(LIT lit) throws IOException {
String val = lit.getValue();
if (val.indexOf('\n') > 0 || val.indexOf('\r') > 0 || val.indexOf('\t') > 0) {
appendable.append("\"\"\"");
appendable.append(TurtleUtil.encodeLongString(val));
appendable.append("\"\"\"");
} else {
appendable.append("\"");
appendable.append(TurtleUtil.encodeString(val));
appendable.append("\"");
}
if (lit.getLang() != null) {
appendable.append("@").append(LocaleUtil.toLang(lit.getLang()));
} else if (!lit.getDatatype().equals(RDF.text)) {
appendable.append("^^");
append(lit.getDatatype());
}
}
private void append(NODE node) throws IOException {
if (node.isURI()) {
append(node.asURI());
} else if (node.isLiteral()) {
append(node.asLiteral());
} else {
append(node.asBNode());
}
}
protected void append(UID uid) throws IOException {
if (uid.ln().length() == 0 || !TurtleUtil.isName(uid.ln())) {
appendFull(uid);
} else {
appendPrefixed(uid);
}
}
protected void appendPredicate(UID uid) throws IOException {
if (uid.equals(RDF.type)) {
appendable.append("a");
} else {
append(uid);
}
}
protected void appendFull(UID uid) throws IOException {
appendable.append("<").append(uid.getValue()).append(">");
}
protected void appendPrefixed(UID uid) throws IOException {
String prefix = prefixes.get(uid.ns());
if (prefix != null) {
appendable.append(prefix).append(":").append(uid.ln());
} else {
appendable.append("<").append(NTriplesUtil.escapeString(uid.getId())).append(">");
}
}
@Override
public void begin() {
try {
for (Map.Entry<String, String> entry : prefixes.entrySet()) {
appendable.append("@prefix ");
appendable.append(entry.getValue());
appendable.append(": <");
appendable.append(TurtleUtil.encodeString(entry.getKey()));
appendable.append("> .\n");
}
appendable.append("\n");
} catch (IOException e) {
throw new RepositoryException(e);
}
}
@Override
public void end() {
if (last != null) {
try {
appendable.append(" .\n");
if (appendable instanceof Writer) {
((Writer) appendable).flush();
}
} catch (IOException e) {
throw new RepositoryException(e);
}
}
}
@Override
public void handle(STMT stmt) {
try {
if (last == null || !last.getSubject().equals(stmt.getSubject())) {
if (last != null) {
appendable.append(" .\n");
}
append(stmt.getSubject());
appendable.append(" ");
appendPredicate(stmt.getPredicate());
appendable.append(" ");
} else if (!last.getPredicate().equals(stmt.getPredicate())) {
appendable.append(" ; ");
appendPredicate(stmt.getPredicate());
appendable.append(" ");
} else {
appendable.append(" , ");
}
append(stmt.getObject());
last = stmt;
} catch (IOException e) {
throw new RepositoryException(e);
}
}
}