org.apache.jena.atlas.json.io.JsonWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-arq Show documentation
Show all versions of jena-arq Show documentation
ARQ is a SPARQL 1.1 query engine for Apache Jena
/*
* 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.atlas.json.io;
import java.util.Set ;
import org.apache.jena.atlas.io.IndentedWriter ;
import org.apache.jena.atlas.json.* ;
public class JsonWriter implements JsonVisitor
{
private final IndentedWriter out ;
public JsonWriter() { this(IndentedWriter.stdout) ; }
public JsonWriter(IndentedWriter ps) { out = ps ; }
public void startOutput() { }
public void finishOutput() { out.flush() ; }
private static String ArrayStart = "[ " ;
private static String ArrayFinish = "]" ;
private static String ArraySep = "," ;
private static String ObjectStart = "{" ;
private static String ObjectFinish = "}" ;
private static String ObjectSep = " ," ;
private static String ObjectPairSep = " : " ;
private static String SPC = " " ;
// Number of key/value pairs in an object before it is always written long form.
// It may still written long form if any of the values are consider complicated.
private static int maxCompactObject = 1 ;
// Number of array elements before an array is always written long form.
// It may still written long form if any of the elements are consider complicated.
private static int maxCompactArray = 1 ;
@Override
public void visit(JsonObject jsonObject)
{
boolean first = true ;
Set x = jsonObject.keySet() ;
out.print(ObjectStart) ;
if ( x.size() == 0 ) {
out.print(SPC) ;
out.print(ObjectFinish) ;
return ;
}
out.incIndent() ;
if ( isJsonObjectCompact(jsonObject) )
writeObjectCompact(jsonObject, x) ;
else
writeObjectLong(jsonObject, x) ;
out.decIndent() ;
out.print(ObjectFinish) ;
}
private static boolean isJsonObjectCompact(JsonObject jsonObject) {
Set x = jsonObject.keySet() ;
if ( x.size() == 0 ) return true ;
if ( x.size() > maxCompactObject ) return false ;
for ( String k : x ) {
if ( ! isCompactValue(jsonObject.get(k)) )
return false ;
}
return true ;
}
private void writeObjectCompact(JsonObject jsonObject, Set x) {
boolean first = true ;
for ( String k : x ) {
if ( ! first )
out.print(ObjectSep) ;
first = false ;
JSWriter.outputQuotedString(out, k) ;
out.print(ObjectPairSep) ;
out.incIndent() ;
jsonObject.get(k).visit(this) ;
out.decIndent() ;
}
out.print(SPC) ;
}
private void writeObjectLong(JsonObject jsonObject, Set x) {
// Just after the opening {
boolean first = true ;
out.println() ;
if ( out.inFlatMode() )
out.print(SPC);
for ( String k : x ) {
if ( ! first ) {
out.print(ObjectSep) ;
out.println() ;
}
first = false ;
JSWriter.outputQuotedString(out, k) ;
out.print(ObjectPairSep) ;
out.incIndent() ;
jsonObject.get(k).visit(this) ;
out.decIndent() ;
}
out.println();
}
private static boolean isCompactValue(JsonValue v) {
if ( v.isPrimitive()) return true ;
if ( v.isArray() ) {
JsonArray a = v.getAsArray() ;
if ( a.size() == 0 ) return true ;
if ( a.size() > 1 ) return false ;
return a.get(0).isPrimitive() ;
}
if ( v.isObject() ) {
JsonObject obj = v.getAsObject() ;
Set x = obj.keySet() ;
if ( x.size() == 0 )
return true ;
if ( x.size() > 1 )
return false ;
String k = obj.keys().iterator().next();
return obj.get(k).isPrimitive() ;
}
return false ;
}
@Override
public void visit(JsonArray jsonArray)
{
if ( jsonArray.size() == 0 ) {
out.print(ArrayStart) ;
out.incIndent() ;
out.print(ArrayFinish) ;
out.decIndent() ;
return ;
}
if ( isJsonArrayCompact(jsonArray) )
writeArrayCompact(jsonArray) ;
else
writeArrayLong(jsonArray) ;
}
private boolean isJsonArrayCompact(JsonArray jsonArray) {
if ( jsonArray.size() > maxCompactArray ) return false ;
for ( JsonValue aJsonArray : jsonArray )
{
if ( !aJsonArray.isPrimitive() )
{
return false;
}
}
return true ;
}
private void writeArrayCompact(JsonArray jsonArray) {
out.print(ArrayStart) ;
out.incIndent() ;
boolean first = true ;
for ( JsonValue elt : jsonArray )
{
if ( ! first ) {
out.print(ArraySep) ;
out.print(SPC) ;
}
first = false ;
elt.visit(this) ;
}
out.print(SPC) ;
out.decIndent() ;
out.print(ArrayFinish) ;
}
private void writeArrayLong(JsonArray jsonArray) {
//out.println() ;
out.print(ArrayStart) ;
out.incIndent() ;
out.ensureStartOfLine() ;
boolean first = true ;
for ( JsonValue elt : jsonArray )
{
if ( ! first )
{
out.print(SPC) ;
out.print(ArraySep) ;
out.println() ;
}
first = false ;
elt.visit(this) ;
}
out.decIndent() ;
out.ensureStartOfLine() ;
out.print(ArrayFinish) ;
}
@Override
public void visit(JsonString jsonString)
{
JSWriter.outputQuotedString(out, jsonString.value()) ;
}
@Override
public void visit(JsonNumber jsonNumber)
{
out.print(jsonNumber.value().toString()) ;
}
@Override
public void visit(JsonBoolean jsonBoolean)
{
String x = jsonBoolean.value() ? "true" : "false" ;
out.print(x) ;
}
@Override
public void visit(JsonNull jsonNull)
{ out.print("null") ; }
}