--- /dev/null
+/*\r
+ * JSON array value\r
+ *\r
+ * Copyright(c) 2009 olyutorskii\r
+ * $Id: JsArray.java 914 2009-11-24 11:16:36Z olyutorskii $\r
+ */\r
+\r
+package jp.sourceforge.jindolf.json;\r
+\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+/**\r
+ * JSON 配列Value。\r
+ */\r
+public class JsArray\r
+ extends AbstractJsValue\r
+ implements Iterable<JsValue> {\r
+\r
+ /**\r
+ * JSON Arrayを文字ストリームからパースする。\r
+ * @param reader 文字入力\r
+ * @return JSON Array。入力終了ならnull\r
+ * @throws IOException 入力エラー\r
+ * @throws JsParseException パースエラー\r
+ */\r
+ static JsArray parseArray(JsonReader reader)\r
+ throws IOException,\r
+ JsParseException {\r
+ int chData;\r
+\r
+ Json.skipWhiteSpace(reader);\r
+ chData = reader.read();\r
+ if(chData < '\u0000') return null;\r
+ if(chData != '[') throw new JsParseException();\r
+\r
+ JsArray result = new JsArray();\r
+\r
+ for(;;){\r
+ Json.skipWhiteSpace(reader);\r
+ chData = reader.read();\r
+ if(chData < '\u0000') throw new JsParseException();\r
+ if(chData == ']') break;\r
+\r
+ if(result.size() <= 0){\r
+ reader.unread(chData);\r
+ }else{\r
+ if(chData != ',') throw new JsParseException();\r
+ Json.skipWhiteSpace(reader);\r
+ }\r
+\r
+ JsValue value = Json.parseValue(reader);\r
+ if(value == null){\r
+ throw new JsParseException();\r
+ }\r
+\r
+ result.add(value);\r
+ }\r
+\r
+ return result;\r
+ }\r
+\r
+\r
+ private final List<JsValue> valueList = new ArrayList<JsValue>();\r
+ private boolean changed = false;\r
+\r
+\r
+ /**\r
+ * コンストラクタ。\r
+ */\r
+ public JsArray(){\r
+ super();\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * JSON Valueを追加する。\r
+ * @param value JSON Value\r
+ */\r
+ public void add(JsValue value){\r
+ this.valueList.add(value);\r
+ this.changed = true;\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * 指定された位置のValueを返す。\r
+ * @param index 0で始まる位置\r
+ * @return Value\r
+ * @throws IndexOutOfBoundsException 不正な位置指定\r
+ */\r
+ public JsValue get(int index) throws IndexOutOfBoundsException{\r
+ return this.valueList.get(index);\r
+ }\r
+\r
+ /**\r
+ * 空にする。\r
+ */\r
+ public void clear(){\r
+ if(this.valueList.size() > 0) this.changed = true;\r
+ this.valueList.clear();\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * JSON Valueを削除する。\r
+ * @param value JSON Value\r
+ * @return 既存のValueが削除されたならtrue\r
+ */\r
+ public boolean remove(JsValue value){\r
+ boolean removed = this.valueList.remove(value);\r
+ if(removed) this.changed = true;\r
+ return removed;\r
+ }\r
+\r
+ /**\r
+ * Value総数を返す。\r
+ * @return 総数\r
+ */\r
+ public int size(){\r
+ return this.valueList.size();\r
+ }\r
+\r
+ /**\r
+ * Valueにアクセスするための反復子を提供する。\r
+ * この反復子での削除作業はできない。\r
+ * @return 反復子イテレータ\r
+ */\r
+ public Iterator<JsValue> iterator(){\r
+ Collection<JsValue> unmodColl =\r
+ Collections.unmodifiableCollection(this.valueList);\r
+ return unmodColl.iterator();\r
+ }\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ * @return {@inheritDoc}\r
+ */\r
+ @Override\r
+ public int hashCode(){\r
+ return this.valueList.hashCode();\r
+ }\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ * @param obj {@inheritDoc}\r
+ * @return {@inheritDoc}\r
+ */\r
+ @Override\r
+ public boolean equals(Object obj){\r
+ if(obj == null) return false;\r
+ if(this == obj) return true;\r
+\r
+ if( ! (obj instanceof JsArray) ) return false;\r
+ JsArray array = (JsArray) obj;\r
+\r
+ return this.valueList.equals(array.valueList);\r
+ }\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ * @return {@inheritDoc}\r
+ */\r
+ @Override\r
+ public String toString(){\r
+ StringBuilder text = new StringBuilder();\r
+\r
+ text.append("[");\r
+ boolean hasElem = false;\r
+ for(JsValue value : this.valueList){\r
+ if(hasElem) text.append(',');\r
+ text.append(value);\r
+ hasElem = true;\r
+ }\r
+ text.append("]");\r
+\r
+ return text.toString();\r
+ }\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ * @param visitor {@inheritDoc}\r
+ * @throws JsVisitException {@inheritDoc}\r
+ */\r
+ @Override\r
+ public void traverse(ValueVisitor visitor) throws JsVisitException{\r
+ visitor.visitValue(this);\r
+\r
+ for(JsValue value : this.valueList){\r
+ value.traverse(visitor);\r
+ }\r
+\r
+ visitor.visitCollectionClose(this);\r
+\r
+ return;\r
+ }\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ * @return {@inheritDoc}\r
+ */\r
+ @Override\r
+ public boolean hasChanged(){\r
+ if(this.changed) return true;\r
+\r
+ for(JsValue value : this.valueList){\r
+ if(value.hasChanged()) return true;\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * {@inheritDoc}\r
+ */\r
+ @Override\r
+ public void setUnchanged(){\r
+ this.changed = false;\r
+\r
+ for(JsValue value : this.valueList){\r
+ value.setUnchanged();\r
+ }\r
+\r
+ return;\r
+ }\r
+\r
+}\r