/******************************************************************************* * Copyright 2012 Pearson Education * * 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. ******************************************************************************/ package org.semantictools.jsonld.io.impl; import java.io.PrintWriter; import java.util.List; import java.util.regex.Pattern; import org.semantictools.jsonld.LdClass; import org.semantictools.jsonld.LdContext; import org.semantictools.jsonld.LdDatatype; import org.semantictools.jsonld.LdProperty; import org.semantictools.jsonld.LdQualifiedRestriction; import org.semantictools.jsonld.LdRestriction; import org.semantictools.jsonld.LdTerm; import org.semantictools.jsonld.io.LdContextWriter; public class LdContextWriterImpl implements LdContextWriter { @Override public void write(LdContext context, PrintWriter out) { Delegate delegate = new Delegate(out); delegate.write(context); } static class Delegate { private int indentSize=2; private int indent; private PrintWriter writer; public Delegate(PrintWriter writer) { this.writer = writer; } private Delegate pushIndent() { indent++; return this; } private Delegate popIndent() { indent--; return this; } private Delegate indent() { for (int i=0; i<indent*indentSize; i++) { writer.print(' '); } return this; } private Delegate print(String text) { writer.print(text); return this; } private Delegate println(String text) { writer.println(text); return this; } private Delegate println() { writer.println(); return this; } public void write(LdContext context) { beginObject(); println().indent(); beginField("@context"); beginObject(); printTerms(context); endObject(); endObject(); } private void printTerms(LdContext context) { String comma = ""; List<LdTerm> termList = context.listTerms(); for (LdTerm term : termList) { printTerm(comma, term); comma = ","; } } private void printTerm(String comma, LdTerm term) { String id = term.getRawIRI(); String type = term.getRawTypeIRI(); LdProperty property = term.getProperty(); LdClass rdfClass = term.getRdfClass(); LdDatatype datatype = term.getDatatype(); if (type==null && property != null) { type = term.getTypeIRI(); } println(comma); comma = ""; indent().quote(term.getShortName()).print(" : "); if ( (type != null) || (property != null) || (rdfClass != null) || (datatype != null) ) { beginObject(); comma = writeField(comma, "@id", id); comma = writeField(comma, "@type", type); comma = writeClass(comma, rdfClass); comma = writeDatatype(comma, datatype); comma = writeProperty(comma, property); endObject(); } else { quote(id); } } private String writeDatatype(String comma, LdDatatype datatype) { if (datatype == null) return comma; LdDatatype base = datatype.getBase(); String baseURI = (base==null) ? null : base.getURI(); println(comma); comma = ""; beginField("datatype"); beginObject(); comma = writeField(comma, "base", baseURI); comma = writeField(comma, "fractionDigits", datatype.getFractionDigits()); comma = writeField(comma, "length", datatype.getLength()); comma = writeField(comma, "maxExclusive", datatype.getMaxExclusive()); comma = writeField(comma, "minExclusive", datatype.getMinExclusive()); comma = writeField(comma, "maxInclusive", datatype.getMaxInclusive()); comma = writeField(comma, "minInclusive", datatype.getMinInclusive()); comma = writeField(comma, "maxLength", datatype.getMaxLength()); comma = writeField(comma, "minLength", datatype.getMinLength()); comma = writeField(comma, "pattern", datatype.getPattern()); endObject(); return ","; } private String writeField(String comma, String fieldName, Pattern pattern) { if (pattern == null) return comma; return writeField(comma, fieldName, pattern.pattern()); } private String writeField(String comma, String fieldName, String value) { if (value == null) return comma; writer.println(comma); writeField(fieldName, value); return ","; } private String writeField(String comma, String fieldName, Number number) { if (number != null) { println(comma); beginField(fieldName); writer.append(number.toString()); comma = ","; } return comma; } private void beginField(String fieldName) { indent().quote(fieldName).print(" : "); } private String writeProperty(String comma, LdProperty property) { if (property == null) return comma; println(comma); beginField("property"); beginObject(); beginField("domain"); beginArray(); printDomain(property); endArray(); endObject(); return ","; } private void printDomain(LdProperty property) { String comma = ""; List<String> array = property.getDomain(); for (String value : array) { println(comma); indent().quoteValue(value); comma = ","; } } private void endArray() { println(); popIndent(); indent().print("]"); } private void beginArray() { print("["); pushIndent(); } private String writeClass(String comma, LdClass rdfClass) { if (rdfClass == null) return comma; println(comma); comma = ""; beginField("class"); beginObject(); comma = writeSuperTypes(comma, rdfClass); comma = writeRestrictions(comma, rdfClass); endObject(comma); return ","; } private void endObject(String comma) { if (comma.length()==0) { popIndent().println("}"); } else { endObject(); } } private String writeRestrictions(String comma, LdClass rdfClass) { List<LdRestriction> list = rdfClass.listRestrictions(); if (list == null || list.isEmpty()) return comma; println(comma); beginField("restriction"); beginArray(); comma = ""; for (LdRestriction r : list) { comma = printRestriction(comma, r); } endArray(); return ","; } private String printRestriction(String comma, LdRestriction r) { println(comma).indent(); comma = ""; beginObject(); comma = writeField(comma, "onProperty", r.getPropertyURI()); comma = writeField(comma, "maxCardinality", r.getMaxCardinality()); comma = writeField(comma, "minCardinality", r.getMinCardinality()); comma = writeField(comma, "allValuesFrom", r.getAllValuesFrom()); comma = writeQualifiedRestrictions(comma, r); endObject(); return ","; } private String writeQualifiedRestrictions(String comma, LdRestriction r) { List<LdQualifiedRestriction> qlist = r.listQualifiedRestrictions(); if (qlist == null || qlist.isEmpty()) return comma; println(comma); beginField("qualifiedRestriction"); beginArray(); comma = ""; for (LdQualifiedRestriction qr : qlist) { comma = writeQualifiedRestriction(comma, qr); } endArray(); return ","; } private String writeQualifiedRestriction(String comma, LdQualifiedRestriction qr) { println(comma).indent(); comma = ""; beginObject(); comma = writeField(comma, "onClass", qr.getRangeURI()); comma = writeField(comma, "maxCardinality", qr.getMaxCardinality()); comma = writeField(comma, "minCardinality", qr.getMinCardinality()); endObject(); return ","; } private String writeSuperTypes(String comma, LdClass rdfClass) { List<LdClass> superList = rdfClass.listSupertypes(); if (superList==null || superList.isEmpty()) return comma; println(comma); beginField("supertype"); beginArray(); comma = ""; for (LdClass superType : superList) { comma = printValue(comma, superType.getURI()); } endArray(); return ","; } private String printValue(String comma, String value) { println(comma); indent().quote(value); return ","; } private void writeField(String fieldName, String value) { indent().quote(fieldName).print(" : ").quoteValue(value); } private Delegate quoteValue(String value) { if (value == null) { writer.print("null"); return this; } value = value.replace("\\", "\\\\"); writer.print('"'); writer.print(value); writer.print('"'); return this; } private Delegate quote(String value) { if (value == null) { writer.print("null"); return this; } writer.print('"'); writer.print(value); writer.print('"'); return this; } private Delegate endObject() { return popIndent().println().indent().print("}"); } private Delegate beginObject() { return print("{").pushIndent(); } } }