/* * Copyright © 2011 Jason J.A. Stephenson * * This file is part of sigio.jar. * * sigio.jar is free software: you can redistribute it and/or modify it * under the terms of the Lesser GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * sigio.jar is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Lesser GNU General Public License for more details. * * You should have received a copy of the Lesser GNU General Public License * along with sigio.jar. If not, see <http://www.gnu.org/licenses/>. */ package com.sigio.json; import java.io.FilterWriter; import java.io.IOException; import java.io.Writer; import java.util.Collection; import java.util.Map; /** * Writer class to write certain java objects as JSON value strings. */ public class JSONWriter extends FilterWriter { /** * Construct a new JSONWriter. */ public JSONWriter(Writer out) { super(out); } /** * Write a java object as a JSON value string. Classes are * written as follows: * * <ul> * <li>JSONLiteral, null, and Boolean are written as literal * strings.</li> * * <li>Instances of java.util.Map, including JSONObject, are * written as JSON objects.</li> * * <li>Instances of java.util.Collection, including JSONArray, are * written as JSON arrays.</li> * * <li>Instances of Number are written as JSON numbers * (i.e. literal string representation of the numeric value).</li> * * <li>Instances of String are written as JSON strings.</li> * * <li>All other classes have their toString() method called and * the result is written as a JSON string.</li> * * </ul> * * @param o Object to write * @throws IOException If an I/O error occurs */ public void write(Object o) throws IOException { if (o == null) { super.out.write(JSONLiteral.NULL.toString()); } else if (o instanceof JSONLiteral) { JSONLiteral literal = (JSONLiteral) o; super.out.write(literal.toString()); } else if (o instanceof Boolean) { Boolean b = (Boolean) o; if (b == Boolean.TRUE) super.out.write(JSONLiteral.TRUE.toString()); else super.out.write(JSONLiteral.FALSE.toString()); } else if (o instanceof java.util.Map) { Map<?,?> map = (Map<?,?>) o; int count = 0; super.out.write(JSON.BEGIN_OBJECT); for (Object key : map.keySet()) { if (count++ > 0) super.out.write(JSON.VALUE_SEPARATOR); this.write(key); super.out.write(JSON.NAME_SEPARATOR); this.write(map.get(key)); } super.out.write(JSON.END_OBJECT); } else if (o instanceof java.util.Collection) { int count = 0; Collection<?> collection = (Collection<?>) o; super.out.write(JSON.BEGIN_ARRAY); for (Object obj : collection) { if (count++ > 0) super.out.write(JSON.VALUE_SEPARATOR); this.write(obj); } super.out.write(JSON.END_ARRAY); } else if (o instanceof java.lang.String) { String str = (String) o; this.write(str); } else if (o instanceof java.lang.Number) { Number num = (Number) o; super.out.write(num.toString()); } else { this.write(o.toString()); } } /** * Writes a string as a JSON string. * * @param str String to write * @throws IOException If an I/O error occurs */ @Override public void write(String str) throws IOException { String out = JSONStringAdapter.toJSONString(str); super.out.write(out); } /** * Writes a portion of a string as a JSON string. * * @param str String to be written * @param off Offset from which to start reading characters * @param len Number of characters to write * @throws IOException If an I/O error occurs * @throws IndexOutOfBoundsException If {@code off} or {@code len} * are negative or if {@code off + len} exceed the length of str */ @Override public void write(String str, int off, int len) throws IOException, IndexOutOfBoundsException { this.write(str.substring(off, (off + len))); } }