001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.schematic.internal.document; 017 018import java.io.IOException; 019import java.io.Writer; 020import java.lang.reflect.Array; 021import java.util.Iterator; 022import org.modeshape.schematic.document.Document; 023import org.modeshape.schematic.document.Document.Field; 024 025public class PrettyJsonWriter extends CompactJsonWriter { 026 027 private static final int MAX_CACHED_INDENTS = 10; 028 private static final String[] CACHED_INDENTS; 029 030 static { 031 CACHED_INDENTS = new String[MAX_CACHED_INDENTS]; 032 CACHED_INDENTS[0] = ""; 033 StringBuilder sb = new StringBuilder(); 034 for (int i = 1; i != MAX_CACHED_INDENTS; ++i) { 035 sb.append(' ').append(' '); 036 CACHED_INDENTS[i] = sb.toString(); 037 } 038 } 039 040 private int depth = 0; 041 042 @Override 043 protected void write(Document bson, Writer writer) throws IOException { 044 if (bson.size() == 0) { 045 writer.append("{ }"); 046 return; 047 } 048 ++depth; 049 writer.append('{').append('\n'); 050 indent(writer); 051 Iterator<Field> iter = bson.fields().iterator(); 052 if (iter.hasNext()) { 053 write(iter.next(), writer); 054 while (iter.hasNext()) { 055 writer.append(',').append('\n'); 056 indent(writer); 057 write(iter.next(), writer); 058 } 059 } 060 writer.append('\n'); 061 --depth; 062 indent(writer); 063 writer.append('}'); 064 } 065 066 @Override 067 protected void write(Iterable<?> arrayValue, Writer writer) throws IOException { 068 ++depth; 069 writer.append('['); 070 boolean first = true; 071 for (Object value : arrayValue) { 072 if (first) { 073 first = false; 074 writer.append('\n'); 075 indent(writer); 076 } else { 077 writer.append(',').append('\n'); 078 indent(writer); 079 } 080 write(value, writer); 081 } 082 --depth; 083 if (first) { 084 writer.append(' '); 085 } else { 086 writer.append('\n'); 087 indent(writer); 088 } 089 writer.append(']'); 090 } 091 092 @Override 093 protected void writeArray(Object array, Writer writer) throws IOException { 094 final int len = Array.getLength(array); 095 if (len == 0) { 096 writer.append("[ ]"); 097 return; 098 } 099 ++depth; 100 writer.append('[').append('\n'); 101 indent(writer); 102 for (int i = 0; i < len; i++) { 103 if (i > 0) { 104 writer.append(',').append('\n'); 105 indent(writer); 106 } 107 write(Array.get(array, i), writer); 108 } 109 writer.append('\n'); 110 --depth; 111 indent(writer); 112 writer.append(']'); 113 } 114 115 protected void indent(Writer writer) throws IOException { 116 if (depth == 0) { 117 return; 118 } 119 if (depth < MAX_CACHED_INDENTS) { 120 writer.append(CACHED_INDENTS[depth]); 121 } else { 122 for (int i = 0; i != depth; ++i) { 123 writer.append(' ').append(' '); 124 } 125 } 126 } 127}