+++ /dev/null
-/*--------------------------------------------------------------------------\r
- * Copyright 2008 Taro L. Saito\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *--------------------------------------------------------------------------*/\r
-//--------------------------------------\r
-// XerialJ\r
-//\r
-// JSONWriter.java\r
-// Since: Feb 1, 2008 10:22:07 AM\r
-//\r
-// $URL: http://www.xerial.org/svn/project/XerialJ/trunk/xerial-core/src/main/java/org/xerial/json/JSONWriter.java $\r
-// $Author: leo $\r
-//--------------------------------------\r
-package org.xerial.json;\r
-\r
-import java.io.IOException;\r
-import java.io.PrintWriter;\r
-import java.io.Reader;\r
-import java.io.Writer;\r
-import java.util.LinkedList;\r
-import java.util.ListIterator;\r
-\r
-import org.xerial.core.XerialError;\r
-import org.xerial.lens.ObjectLens;\r
-\r
-/**\r
- * A support class for generating JSON data\r
- * \r
- * @author leo\r
- * \r
- */\r
-public class JSONWriter {\r
- private final PrintWriter writer;\r
-\r
- enum JSONState {\r
- InObject, InArray, InString, Root, Unknown\r
- }\r
-\r
- private final LinkedList<JSONState> stateStack = new LinkedList<JSONState>();\r
- private final LinkedList<Integer> elementCountStack = new LinkedList<Integer>();\r
-\r
- public JSONWriter(Writer writer) {\r
- this.writer = new PrintWriter(writer);\r
- stateStack.add(JSONState.Root);\r
- elementCountStack.add(0);\r
- }\r
-\r
- private void pushState(JSONState state) {\r
- stateStack.add(state);\r
- elementCountStack.add(0);\r
- }\r
-\r
- private void popState() {\r
- stateStack.removeLast();\r
- elementCountStack.removeLast();\r
- }\r
-\r
- private JSONState getCurrentState() {\r
- if (stateStack.isEmpty())\r
- return JSONState.Unknown;\r
- else\r
- return stateStack.getLast();\r
- }\r
-\r
- private int getPreviousElementCount() {\r
- return elementCountStack.isEmpty() ? 0 : elementCountStack.getLast();\r
- }\r
-\r
- private void incrementElementCount() {\r
- int count = elementCountStack.removeLast();\r
- elementCountStack.add(++count);\r
- }\r
-\r
- public void startObject() {\r
- if (getCurrentState() == JSONState.InArray)\r
- putComma();\r
- writer.print("{");\r
- pushState(JSONState.InObject);\r
- }\r
-\r
- public void endObject() {\r
- if (getCurrentState() != JSONState.InObject)\r
- throw new XerialError(JSONErrorCode.NotInAJSONObject,\r
- "cannot end the object outside of the JSON object");\r
- writer.print("}");\r
- popState();\r
-\r
- if (getCurrentState() == JSONState.InArray)\r
- incrementElementCount();\r
- }\r
-\r
- public void startArray() {\r
- writer.print("[");\r
- pushState(JSONState.InArray);\r
- }\r
-\r
- public void endArray() {\r
- if (getCurrentState() != JSONState.InArray)\r
- throw new XerialError(JSONErrorCode.NotInAJSONArray,\r
- "cannot end the arry outside of the JSON array");\r
-\r
- writer.print("]");\r
- popState();\r
- }\r
-\r
- public void startString() {\r
- if (getCurrentState() == JSONState.InArray)\r
- throw new XerialError(JSONErrorCode.NotInAJSONArray,\r
- "cannot start a new string value outside of the JSON array in this method");\r
- putComma();\r
- writer.append("\"");\r
- pushState(JSONState.InString);\r
- }\r
-\r
- public void startString(String key) {\r
- putKeyPart(key);\r
- writer.append("\"");\r
- pushState(JSONState.InString);\r
- }\r
-\r
- public void append(String stringFragment) {\r
- if (getCurrentState() != JSONState.InString)\r
- throw new XerialError(JSONErrorCode.NotInAJSONString,\r
- "cannot append any string before invoking startString() method");\r
-\r
- writer.append(stringFragment);\r
- }\r
-\r
- public void endString() {\r
- if (getCurrentState() != JSONState.InString)\r
- throw new XerialError(JSONErrorCode.NotInAJSONString,\r
- "cannot end the string not beginning from startString() method.");\r
- writer.append("\"");\r
- popState();\r
- }\r
-\r
- public void startArray(String key) {\r
- if (getCurrentState() != JSONState.InObject)\r
- throw new XerialError(JSONErrorCode.NotInAJSONObject,\r
- "cannot start a keyed array outside of the JSON object");\r
-\r
- if (getPreviousElementCount() > 0)\r
- writer.print(",");\r
- writer.print(doubleQuote(key));\r
- writer.print(":[");\r
- incrementElementCount();\r
- pushState(JSONState.InArray);\r
- }\r
-\r
- public void add(String value) {\r
- addInternal(doubleQuote(value));\r
- }\r
-\r
- public void add(int value) {\r
- addInternal(value);\r
- }\r
-\r
- public void add(long value) {\r
- addInternal(value);\r
- }\r
-\r
- public void add(double value) {\r
- addInternal(value);\r
- }\r
-\r
- public void add(float value) {\r
- addInternal(value);\r
- }\r
-\r
- public void add(boolean bool) {\r
- if (bool)\r
- addInternal("true");\r
- else\r
- addInternal("false");\r
- }\r
-\r
- public void addNull() {\r
- addInternal("null");\r
- }\r
-\r
- public void addObject(Object bean) {\r
- String jsonObject = ObjectLens.toJSON(bean);\r
- addInternal(jsonObject);\r
- }\r
-\r
- private void addInternal(Object value) {\r
- putComma();\r
- if (value != null)\r
- writer.append(value.toString());\r
- else\r
- writer.append("null");\r
- incrementElementCount();\r
- }\r
-\r
- private void putComma() {\r
- if (getPreviousElementCount() > 0)\r
- writer.print(",");\r
- }\r
-\r
- public void put(String key, String value) {\r
- putInternal(key, doubleQuote(value));\r
- }\r
-\r
- public void put(String key, int value) {\r
- putInternal(key, value);\r
- }\r
-\r
- public void put(String key, float value) {\r
- putInternal(key, value);\r
- }\r
-\r
- public void put(String key, double value) {\r
- putInternal(key, value);\r
- }\r
-\r
- public void put(String key, long value) {\r
- putInternal(key, value);\r
- }\r
-\r
- public void put(String key, boolean value) {\r
- if (value)\r
- putInternal(key, "true");\r
- else\r
- putInternal(key, "false");\r
- }\r
-\r
- public void putObject(String key, Object obj) {\r
- if (obj == null)\r
- return; // output nothing\r
- else {\r
- putInternal(key, ObjectLens.toJSON(obj));\r
- }\r
-\r
- }\r
-\r
- public void putNull(String key) {\r
- putInternal(key, "null");\r
- }\r
-\r
- /**\r
- * Generate the key/value pair from the {@link Reader}\r
- * \r
- * @param key\r
- * @param input\r
- * @throws IOException\r
- * @throws IOException\r
- */\r
- public void putString(String key, Reader input) throws IOException {\r
- putKeyPart(key);\r
- writer.append("\"");\r
- for (int ch; (ch = input.read()) != -1;) {\r
- writer.append((char) ch);\r
- }\r
- writer.append("\"");\r
- }\r
-\r
- private void putInternal(String key, Object value) {\r
- putKeyPart(key);\r
- writer.append(value.toString());\r
- incrementElementCount();\r
- }\r
-\r
- private void putKeyPart(String key) {\r
- if (getCurrentState() != JSONState.InObject)\r
- throw new XerialError(JSONErrorCode.NotInAJSONObject,\r
- "cannot add key and value pair outside of the JSON object");\r
- if (getPreviousElementCount() > 0)\r
- writer.append(",");\r
- writer.append(doubleQuote(key));\r
- writer.append(":");\r
- incrementElementCount();\r
- }\r
-\r
- public void startObject(String key) {\r
- putKeyPart(key);\r
- startObject();\r
- }\r
-\r
- public void flush() {\r
- writer.flush();\r
- }\r
-\r
- public void endJSON() {\r
- for (ListIterator<JSONState> it = stateStack.listIterator(stateStack.size()); it\r
- .hasPrevious();) {\r
- JSONState state = it.previous();\r
- switch (state) {\r
- case InObject:\r
- writer.append("}");\r
- break;\r
- case InArray:\r
- writer.append("]");\r
- break;\r
- case InString:\r
- writer.append("\"");\r
- default:\r
- // do nothing\r
- break;\r
- }\r
- }\r
- flush();\r
- }\r
-\r
- private String doubleQuote(String value) {\r
- return "\"" + value + "\"";\r
- }\r
-\r
- public Writer getWriter() {\r
- return writer;\r
- }\r
-\r
-}\r