| /* |
| * 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.karaf.features.internal.util; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.Writer; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Map; |
| |
| /** |
| */ |
| public final class JsonWriter { |
| |
| private JsonWriter() { |
| } |
| |
| public static void write(OutputStream stream, Object value) throws IOException { |
| write(stream, value, false); |
| } |
| |
| public static void write(OutputStream stream, Object value, boolean format) throws IOException { |
| Writer writer = new OutputStreamWriter(stream); |
| write(writer, value, format); |
| writer.flush(); |
| } |
| |
| public static void write(Writer writer, Object value) throws IOException { |
| write(writer, value, false); |
| } |
| |
| public static void write(Writer writer, Object value, boolean format) throws IOException { |
| int indent = format ? 0 : -1; |
| write(writer, value, indent); |
| } |
| |
| private static void write(Writer writer, Object value, int indent) throws IOException { |
| if (value instanceof Map) { |
| writeObject(writer, (Map) value, indent); |
| } else if (value instanceof Collection) { |
| writeArray(writer, (Collection) value, indent); |
| } else if (value instanceof Number) { |
| writeNumber(writer, (Number) value); |
| } else if (value instanceof String) { |
| writeString(writer, (String) value); |
| } else if (value instanceof Boolean) { |
| writeBoolean(writer, (Boolean) value); |
| } else if (value == null) { |
| writeNull(writer); |
| } else { |
| throw new IllegalArgumentException("Unsupported value: " + value); |
| } |
| } |
| |
| private static void writeObject(Writer writer, Map<?, ?> value, int indent) throws IOException { |
| writer.append('{'); |
| boolean first = true; |
| for (Map.Entry entry : value.entrySet()) { |
| if (!first) { |
| writer.append(','); |
| } else { |
| first = false; |
| } |
| if (indent >= 0) { |
| indent(writer, indent + 1); |
| } |
| writeString(writer, (String) entry.getKey()); |
| if (indent >= 0) { |
| writer.append(' '); |
| } |
| writer.append(':'); |
| if (indent >= 0) { |
| writer.append(' '); |
| } |
| write(writer, entry.getValue(), indent + 1); |
| } |
| if (indent >= 0) { |
| indent(writer, indent); |
| } |
| writer.append('}'); |
| } |
| |
| private static void writeString(Writer writer, String value) throws IOException { |
| writer.append('"'); |
| for (int i = 0; i < value.length(); i++) { |
| char c = value.charAt(i); |
| switch (c) { |
| case '\"': |
| writer.append("\\\""); |
| break; |
| case '\\': |
| writer.append("\\\\"); |
| break; |
| case '\b': |
| writer.append("\\b"); |
| break; |
| case '\f': |
| writer.append("\\f"); |
| break; |
| case '\n': |
| writer.append("\\n"); |
| break; |
| case '\r': |
| writer.append("\\r"); |
| break; |
| case '\t': |
| writer.append("\\t"); |
| break; |
| default: |
| if (c < ' ' || (c >= '\u0080' && c < '\u00a0') || (c >= '\u2000' && c < '\u2100')) { |
| String s = Integer.toHexString(c); |
| writer.append('\\'); |
| writer.append('u'); |
| for (int j = s.length(); j < 4; j++) { |
| writer.append('0'); |
| } |
| writer.append(s); |
| } else { |
| writer.append(c); |
| } |
| break; |
| } |
| } |
| writer.append('"'); |
| } |
| |
| private static void writeNumber(Writer writer, Number value) throws IOException { |
| writer.append(value.toString()); |
| } |
| |
| private static void writeBoolean(Writer writer, Boolean value) throws IOException { |
| writer.append(Boolean.toString(value)); |
| } |
| |
| private static void writeArray(Writer writer, Collection<?> value, int indent) throws IOException { |
| writer.append('['); |
| boolean first = true; |
| for (Object obj : value) { |
| if (!first) { |
| writer.append(','); |
| } else { |
| first = false; |
| } |
| if (indent >= 0) { |
| indent(writer, indent + 1); |
| } |
| write(writer, obj, indent + 1); |
| } |
| if (indent >= 0) { |
| indent(writer, indent); |
| } |
| writer.append(']'); |
| } |
| |
| private static void writeNull(Writer writer) throws IOException { |
| writer.append("null"); |
| } |
| |
| static char[] INDENT; |
| static { |
| INDENT = new char[1]; |
| Arrays.fill(INDENT, '\t'); |
| } |
| |
| private static void indent(Writer writer, int indent) throws IOException { |
| writer.write("\n"); |
| while (indent > INDENT.length) { |
| char[] a = new char[INDENT.length * 2]; |
| Arrays.fill(a, '\t'); |
| INDENT = a; |
| } |
| writer.write(INDENT, 0, indent); |
| } |
| } |