From 2e22be455d2631a51adc74c60516418e84846565 Mon Sep 17 00:00:00 2001
From: olyutorskii
Date: Fri, 13 May 2011 00:47:24 +0900
Subject: [PATCH] =?utf8?q?=E5=88=9D=E5=9B=9E=E3=82=A4=E3=83=B3=E3=83=9D?=
=?utf8?q?=E3=83=BC=E3=83=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit
---
.hgeol | 13 +
.hgignore | 12 +
CHANGELOG.txt | 11 +
LICENSE.txt | 34 ++
README.txt | 56 ++
build.xml | 68 +++
pom.xml | 346 ++++++++++++
src/main/assembly/descriptor.xml | 38 ++
src/main/config/checks.xml | 392 +++++++++++++
src/main/config/pmdrules.xml | 93 ++++
src/main/config/suppressions.xml | 37 ++
src/main/java/jp/sourceforge/jovsonz/JsArray.java | 311 +++++++++++
.../java/jp/sourceforge/jovsonz/JsBoolean.java | 210 +++++++
.../java/jp/sourceforge/jovsonz/JsComposition.java | 52 ++
src/main/java/jp/sourceforge/jovsonz/JsNull.java | 142 +++++
src/main/java/jp/sourceforge/jovsonz/JsNumber.java | 427 ++++++++++++++
src/main/java/jp/sourceforge/jovsonz/JsObject.java | 374 +++++++++++++
src/main/java/jp/sourceforge/jovsonz/JsPair.java | 172 ++++++
.../jp/sourceforge/jovsonz/JsParseException.java | 98 ++++
src/main/java/jp/sourceforge/jovsonz/JsString.java | 380 +++++++++++++
src/main/java/jp/sourceforge/jovsonz/JsTypes.java | 84 +++
src/main/java/jp/sourceforge/jovsonz/JsValue.java | 29 +
.../jp/sourceforge/jovsonz/JsVisitException.java | 58 ++
src/main/java/jp/sourceforge/jovsonz/Json.java | 128 +++++
.../java/jp/sourceforge/jovsonz/JsonAppender.java | 443 +++++++++++++++
.../java/jp/sourceforge/jovsonz/JsonSource.java | 246 ++++++++
.../java/jp/sourceforge/jovsonz/UnmodIterator.java | 111 ++++
.../java/jp/sourceforge/jovsonz/ValueVisitor.java | 42 ++
.../java/jp/sourceforge/jovsonz/package-info.java | 75 +++
.../jovsonz/resources/version.properties | 7 +
.../java/jp/sourceforge/jovsonz/JsArrayTest.java | 503 +++++++++++++++++
.../java/jp/sourceforge/jovsonz/JsBooleanTest.java | 335 +++++++++++
.../java/jp/sourceforge/jovsonz/JsNullTest.java | 196 +++++++
.../java/jp/sourceforge/jovsonz/JsNumberTest.java | 536 ++++++++++++++++++
.../java/jp/sourceforge/jovsonz/JsObjectTest.java | 560 +++++++++++++++++++
.../java/jp/sourceforge/jovsonz/JsPairTest.java | 208 +++++++
.../sourceforge/jovsonz/JsParseExceptionTest.java | 115 ++++
.../java/jp/sourceforge/jovsonz/JsStringTest.java | 508 +++++++++++++++++
.../java/jp/sourceforge/jovsonz/JsTypesTest.java | 134 +++++
.../sourceforge/jovsonz/JsVisitExceptionTest.java | 85 +++
.../jp/sourceforge/jovsonz/JsonAppenderTest.java | 264 +++++++++
.../jp/sourceforge/jovsonz/JsonSourceTest.java | 616 +++++++++++++++++++++
src/test/java/jp/sourceforge/jovsonz/JsonTest.java | 386 +++++++++++++
.../jp/sourceforge/jovsonz/TroubleAppender.java | 60 ++
.../java/jp/sourceforge/jovsonz/TroubleReader.java | 54 ++
.../jp/sourceforge/jovsonz/UnmodIteratorTest.java | 217 ++++++++
46 files changed, 9266 insertions(+)
create mode 100644 .hgeol
create mode 100644 .hgignore
create mode 100644 CHANGELOG.txt
create mode 100644 LICENSE.txt
create mode 100644 README.txt
create mode 100644 build.xml
create mode 100644 pom.xml
create mode 100644 src/main/assembly/descriptor.xml
create mode 100644 src/main/config/checks.xml
create mode 100644 src/main/config/pmdrules.xml
create mode 100644 src/main/config/suppressions.xml
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsArray.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsBoolean.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsComposition.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsNull.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsNumber.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsObject.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsPair.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsParseException.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsString.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsTypes.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsValue.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsVisitException.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/Json.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsonAppender.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/JsonSource.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/UnmodIterator.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/ValueVisitor.java
create mode 100644 src/main/java/jp/sourceforge/jovsonz/package-info.java
create mode 100644 src/main/resources/jp/sourceforge/jovsonz/resources/version.properties
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsArrayTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsBooleanTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsNullTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsNumberTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsObjectTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsPairTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsParseExceptionTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsStringTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsTypesTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsVisitExceptionTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsonAppenderTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsonSourceTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/JsonTest.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/TroubleAppender.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/TroubleReader.java
create mode 100644 src/test/java/jp/sourceforge/jovsonz/UnmodIteratorTest.java
diff --git a/.hgeol b/.hgeol
new file mode 100644
index 0000000..ca5f1c1
--- /dev/null
+++ b/.hgeol
@@ -0,0 +1,13 @@
+[patterns]
+
+**.txt = native
+
+**.java = native
+**.properties = LF
+
+**.xml = LF
+**.xsd = LF
+
+**.css = LF
+**.html = LF
+**.png = BIN
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..c94f6de
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,12 @@
+syntax: regexp
+
+\.orig$
+\.orig\..*$
+\.chg\..*$
+\.rej$
+\.conflict\~$
+^maven-build\.properties$
+^maven-build\.xml$
+^nb-configuration\.xml$
+^nbactions\.xml$
+^target$
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000..db72931
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,11 @@
+[UTF-8 Japanese]
+
+
+Jovsonz å¤æ´å±¥æ´
+
+
+1.101.1-SNAPSHOT (2011-05-11)
+ ã»ååãªãªã¼ã¹æºåã
+
+
+--- EOF ---
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..55bc3e6
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,34 @@
+[UTF-8 English & Japanese]
+
+The MIT License
+
+
+Copyright(c) 2009 olyutorskii
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+Jovsonzãªãªã¸ãã«å¶ä½è
èªèº«ããã®ã³ã¡ã³ãï¼
+
+ â» å°ãªãã¨ããã®ã½ããã¦ã§ã¢ã®å®è¡ãè¤è£½ãé
å¸ãæ¹é ã¯èªç±ã§ãã
+ â» å°ãªãã¨ããã®ã½ããã¦ã§ã¢ã¯ç¡ä¿è¨¼ã§ãã
+
+
+--- EOF ---
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..5291797
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,56 @@
+[UTF-8 Japanese]
+
+ J O V S O N Z
+ Readme
+
+ Copyright(c) 2009 olyutorskii
+
+
+=== Jovsonzã¨ã¯ ===
+
+ Jovsonzã©ã¤ãã©ãªã¯ãJSONãã¼ã¿ã®å
¥åºåãè¡ãããã®Javaã©ã¤ãã©ãªã§ãã
+Jovsonzã¯Jindolfããã¸ã§ã¯ãããæ´¾çãããªã¼ãã³ã½ã¼ã¹ããã¸ã§ã¯ãã§ãã
+
+â» ãã®ã¢ã¼ã«ã¤ãã¯ãéçºè
åãã«Jovsonzã®ã½ã¼ã¹ã³ã¼ãã®ã¿ãã¾ã¨ãããã®ã§ãã
+
+
+=== å®è¡ç°å¢ ===
+
+ - Jovsonzã¯Javaè¨èª(JLS3)ã§è¨è¿°ãããããã°ã©ã ã§ãã
+ - Jovsonzã¯JRE1.5ã«æºæ ããJavaå®è¡ç°å¢ã§å©ç¨ã§ããããã«ä½ããã¦ãã¾ãã
+ ååã¨ãã¦ãJRE1.5ã«æºæ ããå®è¡ç³»ã§ããã°ããã©ãããã©ã¼ã ãé¸ã³ã¾ããã
+
+
+=== ãã£ã¬ã¯ããªå
訳æ§æ ===
+
+åºæ¬çã«ã¯Maven2ã®maven-archetype-quickstartæ§æã«æºãã¾ãã
+
+./README.txt
+ ããªããä»è¦ã¦ãããã
+
+./CHANGELOG.txt
+ å¤æ´å±¥æ´ã
+
+./LICENSE.txt
+ ã©ã¤ã»ã³ã¹ã«é¢ãã¦ã
+
+./pom.xml
+ Maven2ç¨ããã¸ã§ã¯ãæ§æå®ç¾©ãã¡ã¤ã«ã
+
+./src/main/java/
+ Javaã®ã½ã¼ã¹ã³ã¼ãã
+
+./src/test/java/
+ JUnit 4.* ç¨ã®ã¦ããããã¹ãã³ã¼ãã
+
+./src/main/config/
+ å種ãã«ãã»æ§æ管çã«å¿
è¦ãªãã¡ã¤ã«ç¾¤ã
+
+./src/main/config/checks.xml
+ Checkstyleç¨configãã¡ã¤ã«ã
+
+./src/main/config/pmdrules.xml
+ PMDç¨ã«ã¼ã«å®ç¾©ãã¡ã¤ã«ã
+
+
+--- EOF ---
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..2216cdc
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..b577b57
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,346 @@
+
+
+
+
+
+ 4.0.0
+
+
+ jp.sourceforge.jovsonz
+ jovsonz
+
+ 1.101.1-SNAPSHOT
+
+ jar
+ Jovsonz
+
+ Jovsonz is a JSON library for Java
+
+ http://jovsonz.sourceforge.jp/
+ 2009
+
+
+ Jovsonz Partners
+ http://sourceforge.jp/projects/jovsonz/
+
+
+
+
+ The MIT License
+ http://www.opensource.org/licenses/mit-license.php
+ manual
+
+
+
+
+
+ olyutorskii
+ http://sites.google.com/site/olyutorskiipit/
+ Jovsonz Partners
+ http://sourceforge.jp/projects/jovsonz/
+
+ Project Founder
+ Java Developer
+
+
+
+
+
+
+
+
+ 2.2
+
+
+
+
+
+ scm:hg:http://hg.sourceforge.jp/view/jovsonz/Jovsonz
+ scm:hg:ssh://hg.sourceforge.jp//hgroot/jovsonz/Jovsonz
+ http://hg.sourceforge.jp/view/jovsonz/Jovsonz/
+
+
+
+ SourceForge.JP
+ http://sourceforge.jp/projects/jovsonz/ticket/
+
+
+
+
+
+
+ UTF-8
+
+ 1.5
+ 1.5
+
+ true
+ true
+
+ UTF-8
+ UTF-8
+
+ ${project.basedir}/src/main/config
+
+
+ ${maven.compiler.source}
+
+
+ ${project.myrepoconf}/checks.xml
+
+
+
+
+
+
+
+
+ junit
+ junit
+ [4.8.2,)
+ test
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 2.4.1
+
+
+
+ ${project.basedir}
+
+ **/.DS_Store
+ **/Thumbs.db
+ **/core
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.5
+ 1.5
+ true
+ true
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.3.1
+
+
+
+ ${project.organization.name}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.2.1
+
+
+ src/main/assembly/descriptor.xml
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 1.0
+
+
+
+ [2.2,3)
+
+
+ [1.5,)
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.1.2
+
+ true
+
+
+ ${project.organization.name}
+
+
+
+
+
+ attach-sources
+ verify
+
+ jar-no-fork
+
+
+
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+ **/version.properties
+
+
+
+
+ src/main/resources
+
+ **/*.css
+ **/*.html
+ **/*.png
+ **/*.properties
+ **/*.txt
+ **/*.xml
+ **/*.xsd
+
+
+ **/version.properties
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 2.2
+
+ ja
+ true
+ true
+ ${project.build.sourceEncoding}
+ ${project.reporting.outputEncoding}
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.8
+
+ protected
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 2.6
+
+ ${checkstyle.config.location}
+ UTF-8
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 2.5
+
+ ${maven.compiler.target}
+
+ ${project.myrepoconf}/pmdrules.xml
+
+
+
+
+
+ pmd
+ cpd
+
+
+
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+ 2.3.2
+
+ Max
+ Low
+ ${project.build.sourceEncoding}
+ ${project.reporting.outputEncoding}
+
+
+
+
+
+ org.codehaus.mojo
+ cobertura-maven-plugin
+ 2.4
+
+
+
+ org.codehaus.mojo
+ javancss-maven-plugin
+ 2.0
+
+
+
+ org.apache.maven.plugins
+ maven-jxr-plugin
+ 2.2
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/assembly/descriptor.xml b/src/main/assembly/descriptor.xml
new file mode 100644
index 0000000..b744cbd
--- /dev/null
+++ b/src/main/assembly/descriptor.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ src
+
+
+ zip
+
+
+
+
+
+ *.txt
+ pom.xml
+ build.xml
+
+ true
+
+
+ src/
+ true
+
+
+
+
+
+
diff --git a/src/main/config/checks.xml b/src/main/config/checks.xml
new file mode 100644
index 0000000..0b45e05
--- /dev/null
+++ b/src/main/config/checks.xml
@@ -0,0 +1,392 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/config/pmdrules.xml b/src/main/config/pmdrules.xml
new file mode 100644
index 0000000..ad3dba9
--- /dev/null
+++ b/src/main/config/pmdrules.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/config/suppressions.xml b/src/main/config/suppressions.xml
new file mode 100644
index 0000000..1d736c1
--- /dev/null
+++ b/src/main/config/suppressions.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsArray.java b/src/main/java/jp/sourceforge/jovsonz/JsArray.java
new file mode 100644
index 0000000..df80a51
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsArray.java
@@ -0,0 +1,311 @@
+/*
+ * JSON array value
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * JSON ARRAYåValueã表ãã
+ * åè¦ç´ ã®é
åãªã¹ããåæ ããã
+ * 表è¨ä¾
+ *
+ * [
+ * true ,
+ * "ABC" ,
+ * 12.3
+ * ]
+ *
+ */
+public class JsArray
+ implements JsComposition {
+
+ private static final String ERRMSG_NOARRAYCOMMA =
+ "missing comma in ARRAY";
+ private static final String ERRMSG_NOELEM =
+ "missing element in ARRAY";
+
+ private final List valueList = new LinkedList();
+ private boolean changed = false;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ */
+ public JsArray(){
+ super();
+ return;
+ }
+
+ /**
+ * JSONæååã½ã¼ã¹ããARRAYåValueãèªã¿è¾¼ãã
+ * ããã«åValueã¸ã¨ãã¼ã¹è§£æãé²ãå¯è½æ§ãããã
+ * å¥åã®å¯è½æ§ã®ããå
é æåãèªã¿è¾¼ãã å ´åã
+ * ã½ã¼ã¹ã«æåãèªã¿æ»ããå¾nullãè¿ãããã
+ * @param source æååã½ã¼ã¹
+ * @return ARRAYåValueãå¥åã®å¯è½æ§ãããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªè¡¨ç¾ã¾ãã¯æå³ããªãå
¥åçµäº
+ */
+ static JsArray parseArray(JsonSource source)
+ throws IOException, JsParseException {
+ char charHead = source.readOrDie();
+ if(charHead != '['){
+ source.unread(charHead);
+ return null;
+ }
+
+ JsArray result = new JsArray();
+
+ for(;;){
+ source.skipWhiteSpace();
+ char chData = source.readOrDie();
+ if(chData == ']') break;
+
+ if(result.isEmpty()){
+ source.unread(chData);
+ }else{
+ if(chData != ','){
+ throw new JsParseException(ERRMSG_NOARRAYCOMMA,
+ source.getLineNumber() );
+ }
+ }
+
+ JsValue value = Json.parseValue(source);
+ if(value == null){
+ throw new JsParseException(ERRMSG_NOELEM,
+ source.getLineNumber() );
+ }
+
+ result.add(value);
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 常ã«{@link JsTypes#ARRAY}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public JsTypes getJsTypes(){
+ return JsTypes.ARRAY;
+ }
+
+ /**
+ * ãã®Valueããã³åå«ã«å¤æ´ããã£ããå¤å®ããã
+ * åè¦ç´ ã®è¿½å ã»åé¤ãè¡ããããã
+ * ãããã¯åè¦ç´ ã®ããããã«å¤æ´ãèªããããã°ã
+ * ãã®ARRAYåValueã«å¤æ´ããã£ãã¨ã¿ãªãããã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean hasChanged(){
+ if(this.changed) return true;
+
+ for(JsValue value : this.valueList){
+ if( ! (value instanceof JsComposition) ) continue;
+ JsComposition composition = (JsComposition) value;
+ if(composition.hasChanged()) return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * ãã®Valueããã³åå«ã«å¤æ´ããªãã£ããã¨ã«ããã
+ */
+ @Override
+ public void setUnchanged(){
+ this.changed = false;
+
+ for(JsValue value : this.valueList){
+ if( ! (value instanceof JsComposition) ) continue;
+ JsComposition composition = (JsComposition) value;
+ composition.setUnchanged();
+ }
+
+ return;
+ }
+
+ /**
+ * æ·±ãåªå
æ¢ç´¢ãè¡ãå種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * thisãéç¥ããå¾ãåValueãé ã«è¨ªåããæå¾ã«éãæ¬å¼§ãéç¥ããã
+ * @param visitor {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void traverse(ValueVisitor visitor) throws JsVisitException{
+ visitor.visitValue(this);
+
+ for(JsValue value : this.valueList){
+ value.traverse(visitor);
+ }
+
+ visitor.visitCompositionClose(this);
+
+ return;
+ }
+
+ /**
+ * é
åè¦ç´ æ°ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int size(){
+ return this.valueList.size();
+ }
+
+ /**
+ * é
åã空ãå¤å®ããã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean isEmpty(){
+ return this.valueList.isEmpty();
+ }
+
+ /**
+ * é
åã空ã«ããã
+ */
+ @Override
+ public void clear(){
+ if(this.valueList.size() > 0) this.changed = true;
+ this.valueList.clear();
+ return;
+ }
+
+ /**
+ * ããã·ã¥å¤ãè¿ãã
+ * å
¨ã¦ã®åå«Valueã®ããã·ã¥å¤ãããã®é½åº¦åæããããé«ã³ã¹ã注æï¼ã
+ * @return {@inheritDoc}
+ * @see java.util.List#hashCode()
+ */
+ @Override
+ public int hashCode(){
+ return this.valueList.hashCode();
+ }
+
+ /**
+ * ç価å¤å®ãè¡ãã
+ * åæ¹ã®é
åãµã¤ãºãä¸è´ã
+ * ãã®å
¨ã¦ã®åValueã§ã®equals()ãç価ã¨å¤æãããå ´åã®ã¿
+ * ç価ã¨å¤æãããã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ * @see java.util.List#equals(Object)
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+
+ if( ! (obj instanceof JsArray) ) return false;
+ JsArray array = (JsArray) obj;
+
+ return this.valueList.equals(array.valueList);
+ }
+
+ /**
+ * é
åã«Valueã追å ããã
+ * åãJsValueã¤ã³ã¹ã¿ã³ã¹ãè¤æ°å追å ãããã¨ãå¯è½ã
+ * @param value JSON Value
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public void add(JsValue value) throws NullPointerException{
+ if(value == null) throw new NullPointerException();
+ this.valueList.add(value);
+ this.changed = true;
+ return;
+ }
+
+ /**
+ * é
åããæå®ãããä½ç½®ã®Valueãè¿ãã
+ * @param index 0ã§å§ã¾ãé
åä¸ã®ä½ç½®
+ * @return Value JSON Value
+ * @throws IndexOutOfBoundsException ä¸æ£ãªä½ç½®æå®
+ */
+ public JsValue get(int index) throws IndexOutOfBoundsException{
+ return this.valueList.get(index);
+ }
+
+ /**
+ * é
åããValueãåé¤ããã
+ * {@link java.util.List#remove(Object)}ã¨ç°ãªãã
+ * åé¤å¯¾è±¡ã®æ¤ç´¢ã«éãã¦
+ * {@link java.lang.Object#equals(Object)}ã¯ä½¿ãããªãã
+ * ä¸è´ããã¤ã³ã¹ã¿ã³ã¹ãè¤æ°åå¨ããå ´åã
+ * å
é ã«è¿ãã¤ã³ã¹ã¿ã³ã¹ã®ã¿åé¤ãããã
+ * ä¸è´ããã¤ã³ã¹ã¿ã³ã¹ãåå¨ããªããã°ãªã«ãããªãã
+ * @param value JSON Value
+ * @return æ¢åã®Valueãåé¤ããããªãtrue
+ */
+ // TODO å¿
è¦ï¼
+ public boolean remove(JsValue value){
+ boolean removed = false;
+
+ Iterator it = this.valueList.iterator();
+ while(it.hasNext()){
+ JsValue elem = it.next();
+ if(elem == value){
+ it.remove();
+ this.changed = true;
+ removed = true;
+ break;
+ }
+ }
+
+ return removed;
+ }
+
+ /**
+ * é
åããæå®ä½ç½®ã®Valueãåé¤ããã
+ * @param index 0ã§å§ã¾ãåé¤å¯¾è±¡ã®ã¤ã³ããã¯ã¹å¤
+ * @return åé¤ãããValue
+ * @throws IndexOutOfBoundsException ä¸æ£ãªã¤ã³ããã¯ã¹å¤
+ */
+ public JsValue remove(int index) throws IndexOutOfBoundsException{
+ JsValue removed = this.valueList.remove(index);
+ this.changed = true;
+ return removed;
+ }
+
+ /**
+ * Valueã«ã¢ã¯ã»ã¹ããããã®å復åãæä¾ããã
+ * ãã®å復åã§ã®åé¤ä½æ¥ã¯ã§ããªãã
+ * @return å復åã¤ãã¬ã¼ã¿
+ * @see UnmodIterator
+ */
+ public Iterator iterator(){
+ return UnmodIterator.unmodIterator(this.valueList);
+ }
+
+ /**
+ * {@inheritDoc}
+ * æåå表ç¾ãè¿ãã
+ * JSON表è¨ã®å
¨ä½ãããã¯ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ StringBuilder text = new StringBuilder();
+
+ text.append("[");
+ boolean hasElem = false;
+ for(JsValue value : this.valueList){
+ if(hasElem) text.append(',');
+ text.append(value);
+ hasElem = true;
+ }
+ text.append("]");
+
+ return text.toString();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsBoolean.java b/src/main/java/jp/sourceforge/jovsonz/JsBoolean.java
new file mode 100644
index 0000000..06e4a0f
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsBoolean.java
@@ -0,0 +1,210 @@
+/*
+ * JSON boolean value
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+
+/**
+ * JSON BOOLEANåValueã表ãã
+ * çå½å¤ãåæ ããã
+ * ã¤ã³ã¹ã¿ã³ã¹ã¯2ã¤ããåå¨ãããªãã
+ * 表è¨ä¾
+ *
+ * true
+ * false
+ *
+ */
+public final class JsBoolean
+ implements JsValue, Comparable {
+
+ /** å¯ä¸ã®çå¤ã */
+ public static final JsBoolean TRUE = new JsBoolean();
+ /** å¯ä¸ã®å½å¤ã */
+ public static final JsBoolean FALSE = new JsBoolean();
+
+ /** çã®æåå表ç¾ã */
+ public static final String TEXT_TRUE = "true";
+ /** å½ã®æåå表ç¾ã */
+ public static final String TEXT_FALSE = "false";
+
+ /** çã®ããã·ã¥å¤ã */
+ public static final int HASH_TRUE = Boolean.TRUE.hashCode();
+ /** å½ã®ããã·ã¥å¤ã */
+ public static final int HASH_FALSE = Boolean.FALSE.hashCode();
+
+ /**
+ * é ãã³ã³ã¹ãã©ã¯ã¿ã
+ * 2åããå¼ã°ããªãã¯ãã
+ */
+ private JsBoolean(){
+ super();
+ return;
+ }
+
+ /**
+ * JSONæååã½ã¼ã¹ããBOOLEANåValueãèªã¿è¾¼ãã
+ * å¥åã®å¯è½æ§ã®ããå
é æåãèªã¿è¾¼ãã å ´åã
+ * ã½ã¼ã¹ã«æåãèªã¿æ»ããå¾nullãè¿ãããã
+ * @param source æååã½ã¼ã¹
+ * @return BOOLEANåValueãå¥åã®å¯è½æ§ãããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãã¼ã¯ã³ãããã¯æå³ããªãå
¥åçµäº
+ */
+ static JsBoolean parseBoolean(JsonSource source)
+ throws IOException, JsParseException{
+ JsBoolean result = null;
+ boolean hasError = false;
+
+ char charHead = source.readOrDie();
+ switch(charHead){
+ case 't':
+ if(source.matchOrDie("rue")){
+ result = JsBoolean.TRUE;
+ }else{
+ hasError = true;
+ }
+ break;
+ case 'f':
+ if(source.matchOrDie("alse")){
+ result = JsBoolean.FALSE;
+ }else{
+ hasError = true;
+ }
+ break;
+ default:
+ source.unread(charHead);
+ break;
+ }
+
+ if(hasError){
+ throw new JsParseException(JsParseException.ERRMSG_INVALIDTOKEN,
+ source.getLineNumber() );
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 常ã«{@link JsTypes#BOOLEAN}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public JsTypes getJsTypes(){
+ return JsTypes.BOOLEAN;
+ }
+
+ /**
+ * å種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * ãã®å®è£
ã§ã¯thisã®åºç¾ã®ã¿ãéç¥ããã
+ * @param visitor {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void traverse(ValueVisitor visitor)
+ throws JsVisitException{
+ visitor.visitValue(this);
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ããã·ã¥å¤ãè¿ãã
+ * çãªã{@link #HASH_TRUE}ãå½ãªã{@link #HASH_FALSE}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode(){
+ int result;
+ if(this == TRUE) result = HASH_TRUE;
+ else result = HASH_FALSE;
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ç価å¤å®ãè¡ãã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+ if(obj instanceof JsBoolean) return false;
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * BOOLEANåValueãé åºä»ããã
+ * ({@link #TRUE}ã{@link #FALSE})ã®é ã«é åºä»ããããã
+ * @param value {@inheritDoc}
+ * @return {@inheritDoc}
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ @Override
+ public int compareTo(JsBoolean value) throws NullPointerException{
+ if(value == null) throw new NullPointerException();
+
+ int result;
+ if(this == value) result = 0;
+ else if(this == TRUE) result = -1;
+ else result = +1;
+
+ return result;
+ }
+
+ /**
+ * booleanå¤ãåæ ããBOOLEANåValueãè¿ãã
+ * @param bool booleanå¤
+ * @return BOOLEANåValue
+ */
+ public static JsBoolean valueOf(boolean bool){
+ if(bool) return TRUE;
+ return FALSE;
+ }
+
+ /**
+ * booleanå¤ãè¿ãã
+ * @return booleanå¤
+ */
+ public boolean booleanValue(){
+ if(this == TRUE) return true;
+ return false;
+ }
+
+ /**
+ * çãå¤å®ããã
+ * @return çãªãtrue
+ */
+ public boolean isTrue(){
+ if(this == TRUE) return true;
+ return false;
+ }
+
+ /**
+ * å½ãå¤å®ããã
+ * @return å½ãªãtrue
+ */
+ public boolean isFalse(){
+ if(this != TRUE) return true;
+ return false;
+ }
+
+ /**
+ * æåå表ç¾ãè¿ãã
+ * JSON表è¨ã®ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ if(this == TRUE) return TEXT_TRUE;
+ return TEXT_FALSE;
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsComposition.java b/src/main/java/jp/sourceforge/jovsonz/JsComposition.java
new file mode 100644
index 0000000..e18ec8b
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsComposition.java
@@ -0,0 +1,52 @@
+/*
+ * composition type value
+ *
+ * License : The MIT License
+ * Copyright(c) 2010 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+/**
+ * åè¦ç´ ãæã¤JSONåã®æ½è±¡ã¤ã³ã¿ãã§ã¼ã¹ã
+ * JSONæä¸ä½æ§é ã§ããããã®å¿
è¦æ¡ä»¶ã
+ * åè¦ç´ ãæã¡ããJSONåã¯OBJECTåãARRAYåã®ã¿ã
+ * @param å復åã®è¦ç´ å
+ */
+public interface JsComposition extends JsValue, Iterable {
+
+ /**
+ * è¦ç´ æ°ãè¿ãã
+ * OBJECTåã®å ´åã¯ç´ä¸ã®PAIRç·æ°ã
+ * ARRAYåã®å ´åã¯ç´ä¸ã®åè¦ç´ ç·æ°ã
+ * @return è¦ç´ æ°
+ */
+ int size();
+
+ /**
+ * åè¦ç´ ã空ãå¦ãå¤å®ããã
+ * @return è¦ç´ ããªããã°true
+ */
+ boolean isEmpty();
+
+ /**
+ * åè¦ç´ ã空ã«ããã
+ */
+ void clear();
+
+ /**
+ * ãã®Valueããã³åå«ã«å¤æ´ããã£ããå¤å®ããã
+ * Valueçæç´å¾ã¯falseã§ãªããã°ãªããªãã
+ * ãã¼ããããã¼ã¿ã«å¯¾ã
+ * åã»ã¼ãã®å¿
è¦ããããã©ããã®å¤å®ãªã©ãç®çã¨ããã
+ * å¤æ´ãå¯è½ãªValueã¯OBJECTåãARRAYåã®ã¿ã
+ * @return å¤æ´ãããã°true
+ */
+ boolean hasChanged();
+
+ /**
+ * ãã®Valueããã³åå«ã«å¤æ´ããªãã£ããã¨ã«ããã
+ */
+ void setUnchanged();
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsNull.java b/src/main/java/jp/sourceforge/jovsonz/JsNull.java
new file mode 100644
index 0000000..b0e1015
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsNull.java
@@ -0,0 +1,142 @@
+/*
+ * JSON null value
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+
+/**
+ * JSON NULLåValueã表ãã
+ * Javaã®nullã¨ã¯ä¸åç¡é¢ä¿ã
+ * ãã®å®ä½ã¯ã·ã³ã°ã«ãã³ã
+ * 表è¨ä¾
+ *
+ * null
+ *
+ */
+public final class JsNull
+ implements JsValue, Comparable {
+
+ /** ãã å¯ä¸ã®ã¤ã³ã¹ã¿ã³ã¹ã */
+ public static final JsNull NULL = new JsNull();
+
+ /** å¯ä¸ã®æåå表ç¾ã */
+ public static final String TEXT = "null";
+
+ /** å¯ä¸ã®ããã·ã¥å¤ã */
+ public static final int ONLYHASH = 982451653; // 大ããªç´ æ°;
+
+ /**
+ * é ãã³ã³ã¹ãã©ã¯ã¿ã
+ * 1åããå¼ã°ããªãã¯ã
+ */
+ private JsNull(){
+ super();
+ return;
+ }
+
+ /**
+ * JSONæååã½ã¼ã¹ããNULLåValueãèªã¿è¾¼ãã
+ * å¥åã®å¯è½æ§ã®ããå
é æåãèªã¿è¾¼ãã å ´åã
+ * ã½ã¼ã¹ã«æåãèªã¿æ»ããå¾nullãè¿ãããã
+ * @param source æååã½ã¼ã¹
+ * @return NULLåValueãå¥åã®å¯è½æ§ãããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãã¼ã¯ã³ãããã¯æå³ããªãå
¥åçµäº
+ */
+ static JsNull parseNull(JsonSource source)
+ throws IOException, JsParseException{
+ char charHead = source.readOrDie();
+
+ if(charHead != 'n'){
+ source.unread(charHead);
+ return null;
+ }
+
+ if( ! source.matchOrDie("ull") ){
+ throw new JsParseException(JsParseException.ERRMSG_INVALIDTOKEN,
+ source.getLineNumber() );
+ }
+
+ return JsNull.NULL;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 常ã«{@link JsTypes#NULL}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public JsTypes getJsTypes(){
+ return JsTypes.NULL;
+ }
+
+ /**
+ * å種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * ãã®å®è£
ã§ã¯thisã®åºç¾ã®ã¿ãéç¥ããã
+ * @param visitor {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void traverse(ValueVisitor visitor)
+ throws JsVisitException{
+ visitor.visitValue(this);
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ããã·ã¥å¤ãè¿ãã
+ * 常ã«{@value ONLYHASH}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode(){
+ return ONLYHASH;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ç価å¤å®ãè¡ãã
+ * {@link #NULL}ã渡ãããæã®ã¿trueãè¿ãã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+ if(obj instanceof JsNull) return true; // ã·ã³ã°ã«ãã³ã«ã¯åé·
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * NULLåValueãé åºä»ãããã·ã³ã°ã«ãã³ç¸æã«ã»ã¼ç¡æå³ã
+ * null以å¤ã®å¼æ°ã«ã¯å¿
ã0ãè¿ãã
+ * @param value {@inheritDoc}
+ * @return {@inheritDoc}
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ @Override
+ public int compareTo(JsNull value) throws NullPointerException{
+ if(value == null) throw new NullPointerException();
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ * æåå表ç¾ãè¿ãã
+ * 常ã«æåå {@value TEXT} ãè¿ãã
+ * JSON表è¨ã®ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ return TEXT;
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsNumber.java b/src/main/java/jp/sourceforge/jovsonz/JsNumber.java
new file mode 100644
index 0000000..8185715
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsNumber.java
@@ -0,0 +1,427 @@
+/*
+ * JSON number value
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+
+/**
+ * JSON NUMBERåValueã表ãã
+ * æ´æ°ãå®æ°ãå«ããæ°å¤ãåæ ããã
+ *
+ * 10ãåºæ°ã¨ãã{@link java.math.BigDecimal}ãå®è£
ãã¼ã¹ã¨ããã
+ * â» IEEE754æµ®åå°æ°ã§ã¯ãªãã
+ *
+ * (1)ã¨(1.0)ã¯ã¹ã±ã¼ã«å¤ã«ãã£ã¦åºå¥ããã
+ * 表è¨ä¾
+ *
+ * -43
+ * 0.56
+ * 3.23E-06
+ *
+ * @see java.math.BigDecimal
+ */
+public class JsNumber
+ implements JsValue, Comparable {
+
+ private static final MathContext DEF_MC =
+ new MathContext(0, RoundingMode.UNNECESSARY);
+
+ private static final String ERRMSG_INVFRAC =
+ "invalid fractional number";
+ private static final String ERRMSG_NONUMBER =
+ "no number";
+ private static final String ERRMSG_EXTRAZERO =
+ "extra zero found";
+
+ private final BigDecimal decimal;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param val åææ´æ°å¤
+ */
+ public JsNumber(long val){
+ this(BigDecimal.valueOf(val));
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ *
+ * {@link java.math.BigDecimal#valueOf(double)}ã¨åçã®ä¸¸ããè¡ãããã
+ * (1.0/10.0)ã渡ãã¨0.1ç¸å½ã«ãªãã
+ * å¿
è¦ã«å¿ãã¦{@link java.math.BigDecimal}ã
+ * å¼æ°ã«æã¤ã³ã³ã¹ãã©ã¯ã¿ã¨ä½¿ãåãããã¨ã
+ *
+ * @param val åæå®æ°å¤
+ * @see java.math.BigDecimal#valueOf(double)
+ */
+ public JsNumber(double val){
+ this(BigDecimal.valueOf(val));
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param val åææ´æ°å¤
+ * @throws ArithmeticException æ£ç¢ºãªçµæã
+ * {@link java.math.BigDecimal}ã«ç´ãåããªã
+ */
+ public JsNumber(BigInteger val) throws ArithmeticException{
+ this(new BigDecimal(val, DEF_MC));
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * æ¸å¼ã¯{@link java.math.BigDecimal#BigDecimal(String)}ã«æºããã
+ * @param val åææ°å¤ã®æåå表è¨
+ * @throws NumberFormatException ä¸æ£ãªæ°å¤è¡¨è¨
+ * @throws ArithmeticException æ£ç¢ºãªçµæã
+ * {@link java.math.BigDecimal}ã«ç´ãåããªã
+ * @see java.math.BigDecimal#BigDecimal(String)
+ */
+ public JsNumber(CharSequence val)
+ throws NumberFormatException, ArithmeticException{
+ this(new BigDecimal(val.toString(), DEF_MC));
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param val åææ°å¤
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public JsNumber(BigDecimal val) throws NullPointerException{
+ super();
+ if(val == null) throw new NullPointerException();
+ this.decimal = val;
+ return;
+ }
+
+ /**
+ * ä»»æã®æåãUnicodeã®Basic-Latinã®æ°åãå¦ãå¤å®ããã
+ * @param ch æå
+ * @return æ°åãªãtrue
+ * @see java.lang.Character#isDigit(char)
+ */
+ public static boolean isLatinDigit(char ch){
+ if('0' <= ch && ch <= '9') return true;
+ return false;
+ }
+
+ /**
+ * æåã½ã¼ã¹ãã符å·ä»ãã®æ°å並ã³ãèªã¿è¾¼ãã
+ * å
é '+'符å·ã¯èªã¿é£ã°ãããã
+ * åé ã®ã¼ã'0'ã«ç¶ãæ°åã許ããå¦ãæå®ãå¯è½ã
+ * NUMBERå表è¨ã®æ´æ°é¨ãå°æ°é¨ãææ°é¨èªã¿è¾¼ã¿ã®ä¸è«ãã¡ã½ããã
+ * @param source æååã½ã¼ã¹
+ * @param app åºåå
+ * @param allowZeroTrail åé ã®ã¼ã'0'ã«ç¶ãæ°åã許ããªãtrue
+ * @return å¼æ°ã¨åãåºåå
+ * @throws IOException å
¥åºåã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªæ¸å¼ãããã¯æå³ããªãå
¥åçµäº
+ */
+ private static Appendable appendDigitText(JsonSource source,
+ Appendable app,
+ boolean allowZeroTrail)
+ throws IOException, JsParseException{
+ char head = source.readOrDie();
+ if (head == '-') app.append('-');
+ else if(head != '+') source.unread(head);
+
+ boolean hasAppended = false;
+ boolean zeroStarted = false; // å
é ã¯0ã
+ for(;;){
+ if( ! source.hasMore() && hasAppended) break;
+
+ char readedCh = source.readOrDie();
+
+ if( ! isLatinDigit(readedCh) ){
+ if( ! hasAppended ){
+ throw new JsParseException(ERRMSG_NONUMBER,
+ source.getLineNumber() );
+ }
+ source.unread(readedCh);
+ break;
+ }
+
+ if(hasAppended){
+ if(zeroStarted && ! allowZeroTrail){
+ throw new JsParseException(ERRMSG_EXTRAZERO,
+ source.getLineNumber() );
+ }
+ }else{ // 1st char
+ if(readedCh == '0'){
+ zeroStarted = true;
+ }
+ }
+
+ app.append(readedCh);
+ hasAppended = true;
+ }
+
+ return app;
+ }
+
+ /**
+ * æåã½ã¼ã¹ãããããªãªãã.ãã§å§ã¾ãNUMBERåå°æ°é¨ãèªã¿è¾¼ãã
+ * å°æ°é¨ããªããã°ãªã«ãããã«æ»ãã
+ * @param source æååã½ã¼ã¹
+ * @param app åºåå
+ * @return å¼æ°ã¨åãåºåå
+ * @throws IOException å
¥åºåã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªæ¸å¼ãããã¯æå³ããªãå
¥åçµäº
+ */
+ private static Appendable appendFractionPart(JsonSource source,
+ Appendable app )
+ throws IOException, JsParseException{
+ if( ! source.hasMore() ) return app;
+
+ char chData;
+
+ chData = source.readOrDie();
+ if(chData != '.'){
+ source.unread(chData);
+ return app;
+ }
+
+ app.append(".");
+
+ boolean hasAppended = false;
+ for(;;){
+ if( ! source.hasMore() && hasAppended) break;
+
+ chData = source.readOrDie();
+
+ if( ! isLatinDigit(chData) ){
+ if( ! hasAppended ){
+ throw new JsParseException(ERRMSG_INVFRAC,
+ source.getLineNumber());
+ }
+ source.unread(chData);
+ break;
+ }
+
+ app.append(chData);
+ hasAppended = true;
+ }
+
+ return app;
+ }
+
+ /**
+ * æåã½ã¼ã¹ãããeããããã¯ãEãã§å§ã¾ãNUMBERåææ°é¨ãèªã¿è¾¼ãã
+ * ææ°é¨ããªããã°ãªã«ãããã«æ»ãã
+ * @param source æååã½ã¼ã¹
+ * @param app åºåå
+ * @return å¼æ°ã¨åãåºåå
+ * @throws IOException å
¥åºåã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªæ¸å¼ãããã¯æå³ããªãå
¥åçµäº
+ */
+ private static Appendable appendExpPart(JsonSource source,
+ Appendable app )
+ throws IOException, JsParseException{
+ if( ! source.hasMore() ) return app;
+
+ char chData = source.readOrDie();
+ if(chData != 'e' && chData != 'E'){
+ source.unread(chData);
+ return app;
+ }
+
+ app.append('E');
+
+ appendDigitText(source, app, true);
+
+ return app;
+ }
+
+ /**
+ * JSONæååã½ã¼ã¹ããNUMBERåValueãèªã¿è¾¼ãã
+ * å¥åã®å¯è½æ§ã®ããå
é æåãèªã¿è¾¼ãã å ´åã
+ * ã½ã¼ã¹ã«æåãèªã¿æ»ããå¾nullãè¿ãããã
+ * @param source æååã½ã¼ã¹
+ * @return NUMBERåValueãå¥åã®å¯è½æ§ãããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªè¡¨è¨ãããã¯æå³ããªãå
¥åçµäº
+ */
+ static JsNumber parseNumber(JsonSource source)
+ throws IOException, JsParseException{
+ char charHead = source.readOrDie();
+ source.unread(charHead);
+ if( charHead != '-' && ! JsNumber.isLatinDigit(charHead) ){
+ return null;
+ }
+
+ StringBuilder numText = new StringBuilder();
+
+ appendDigitText (source, numText, false);
+ appendFractionPart(source, numText);
+ appendExpPart (source, numText);
+
+ JsNumber result = new JsNumber(numText);
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 常ã«{@link JsTypes#NUMBER}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public JsTypes getJsTypes(){
+ return JsTypes.NUMBER;
+ }
+
+ /**
+ * å種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * ãã®å®è£
ã§ã¯thisã®åºç¾ã®ã¿ãéç¥ããã
+ * @param visitor {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void traverse(ValueVisitor visitor)
+ throws JsVisitException{
+ visitor.visitValue(this);
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ããã·ã¥å¤ãè¿ãã
+ * {@link java.math.BigDecimal#hashCode()}ã¨åãå¤ãè¿ãã
+ * @return {@inheritDoc}
+ * @see java.math.BigDecimal#hashCode()
+ */
+ @Override
+ public int hashCode(){
+ return this.decimal.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ * ç価å¤å®ãè¡ãã
+ * {@link java.math.BigDecimal#equals(Object)}ã¨åçã®å¤æãè¡ãããã
+ * ã1.2ãã¨ã0.12E+1ããªã©ã
+ * ã¹ã±ã¼ã«ã®ä¸è´ããªãå¤ã¯ç°ãªãå¤ã¨è¦ãªãããã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ * @see java.math.BigDecimal#equals(Object)
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+ if( ! (obj instanceof JsNumber) ) return false;
+ JsNumber number = (JsNumber) obj;
+ return this.decimal.equals(number.decimal);
+ }
+
+ /**
+ * {@inheritDoc}
+ * NUMBERåValueãæé ã«é åºä»ããã
+ * ã1.2ãã¨ã0.12E+1ããªã©ãã¹ã±ã¼ã«ãç°ãªã£ã¦ãå¤ãåãã§ããã°
+ * çããå¤ã¨è¦ãªãããã
+ * @param value {@inheritDoc}
+ * @return {@inheritDoc}
+ * @see java.math.BigDecimal#compareTo(BigDecimal)
+ */
+ @Override
+ public int compareTo(JsNumber value){
+ if(this == value) return 0;
+ return this.decimal.compareTo(value.decimal);
+ }
+
+ /**
+ * intåã®æ°å¤ãè¿ãã
+ * æ
å ±ã失ãããå¯è½æ§ãããã
+ * @return intåæ°å¤
+ * @see java.lang.Number#intValue()
+ * @see java.math.BigDecimal#intValue()
+ */
+ public int intValue(){
+ return this.decimal.intValue();
+ }
+
+ /**
+ * longåã®æ°å¤ãè¿ãã
+ * æ
å ±ã失ãããå¯è½æ§ãããã
+ * @return longåæ°å¤
+ * @see java.lang.Number#longValue()
+ * @see java.math.BigDecimal#longValue()
+ */
+ public long longValue(){
+ return this.decimal.longValue();
+ }
+
+ /**
+ * floatåã®æ°å¤ãè¿ãã
+ * æ
å ±ã失ãããå¯è½æ§ãããã
+ * @return floatåæ°å¤
+ * @see java.lang.Number#floatValue()
+ * @see java.math.BigDecimal#floatValue()
+ */
+ public float floatValue(){
+ return this.decimal.floatValue();
+ }
+
+ /**
+ * doubleåã®æ°å¤ãè¿ãã
+ * æ
å ±ã失ãããå¯è½æ§ãããã
+ * @return doubleåæ°å¤
+ * @see java.lang.Number#doubleValue()
+ * @see java.math.BigDecimal#doubleValue()
+ */
+ public double doubleValue(){
+ return this.decimal.doubleValue();
+ }
+
+ /**
+ * {@link java.math.BigDecimal}åã®æ°å¤è¡¨ç¾ãè¿ãã
+ * @return BigDecimalåæ°å¤
+ */
+ public BigDecimal decimalValue(){
+ return this.decimal;
+ }
+
+ /**
+ * ã¹ã±ã¼ã«å¤ãè¿ãã
+ * ãã®ã¤ã³ã¹ã¿ã³ã¹ãæ´æ°æåå表è¨ã«ç±æ¥ããå ´åã
+ * ã¹ã±ã¼ã«å¤ã¯0ã«ãªãã¯ãã
+ *
+ *
+ * "99"ã®ã¹ã±ã¼ã«å¤ã¯0
+ * "99.0"ã®ã¹ã±ã¼ã«å¤ã¯1
+ * "99.01"ã®ã¹ã±ã¼ã«å¤ã¯2
+ * "99E+3"ã®ã¹ã±ã¼ã«å¤ã¯-3
+ * "99.0E+3"ã®ã¹ã±ã¼ã«å¤ã¯-2
+ *
+ *
+ * @return ã¹ã±ã¼ã«å¤
+ * @see java.math.BigDecimal#scale()
+ */
+ public int scale(){
+ return this.decimal.scale();
+ }
+
+ /**
+ * æåå表ç¾ãè¿ãã
+ * {@link java.math.BigDecimal#toString()}ã«æºããã
+ * JSON表è¨ã®ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ return this.decimal.toString();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsObject.java b/src/main/java/jp/sourceforge/jovsonz/JsObject.java
new file mode 100644
index 0000000..49cd49a
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsObject.java
@@ -0,0 +1,374 @@
+/*
+ * JSON object value
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * JSON OBJECTåValueã表ãã
+ * PAIRåã¨åè¦ç´ ã®çµ(PAIR)ã®éåãåæ ããã
+ * PAIRåã®ä¸¦ã³é ã«é¢ãã¦ã¯æªå®ç¾©ã¨ããã
+ * 表è¨ä¾
+ *
+ * {
+ * "Name" : "Joe" ,
+ * "Age" : 19
+ * }
+ *
+ */
+public class JsObject
+ implements JsComposition {
+
+ private static final String ERRMSG_NOOBJECTCOMMA =
+ "missing comma in OBJECT";
+ private static final String ERRMSG_NOHASHNAME =
+ "no hash name in OBJECT";
+ private static final String ERRMSG_NOHASHSEP =
+ "missing hash separator(:) in OBJECT";
+ private static final String ERRMSG_NOHASHVAL =
+ "no hash value in OBJECT";
+
+ private final Map pairMap =
+ new TreeMap();
+ private final Collection pairCollection = this.pairMap.values();
+
+ private boolean changed = false;
+
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ */
+ public JsObject(){
+ super();
+ return;
+ }
+
+ /**
+ * JSONæååã½ã¼ã¹ããOBJECTåValueãèªã¿è¾¼ãã
+ * ããã«åValueã¸ã¨ãã¼ã¹è§£æãé²ãå¯è½æ§ãããã
+ * å¥åã®å¯è½æ§ã®ããå
é æåãèªã¿è¾¼ãã å ´åã
+ * ã½ã¼ã¹ã«æåãèªã¿æ»ããå¾nullãè¿ãããã
+ * @param source æååã½ã¼ã¹
+ * @return OBJECTåValueãå¥åã®å¯è½æ§ãããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªè¡¨è¨ãããã¯æå³ããªãå
¥åçµäº
+ */
+ static JsObject parseObject(JsonSource source)
+ throws IOException, JsParseException{
+ char charHead = source.readOrDie();
+ if(charHead != '{'){
+ source.unread(charHead);
+ return null;
+ }
+
+ JsObject result = new JsObject();
+
+ for(;;){
+ source.skipWhiteSpace();
+ char chData = source.readOrDie();
+ if(chData == '}') break;
+
+ if(result.isEmpty()){
+ source.unread(chData);
+ }else{
+ if(chData != ','){
+ throw new JsParseException(ERRMSG_NOOBJECTCOMMA,
+ source.getLineNumber() );
+ }
+ source.skipWhiteSpace();
+ }
+
+ JsString name = JsString.parseString(source);
+ if(name == null){
+ throw new JsParseException(ERRMSG_NOHASHNAME,
+ source.getLineNumber() );
+ }
+
+ source.skipWhiteSpace();
+ chData = source.readOrDie();
+ if(chData != ':'){
+ throw new JsParseException(ERRMSG_NOHASHSEP,
+ source.getLineNumber() );
+ }
+
+ JsValue value = Json.parseValue(source);
+ if(value == null){
+ throw new JsParseException(ERRMSG_NOHASHVAL,
+ source.getLineNumber() );
+ }
+
+ result.putValue(name.toRawString(), value);
+ }
+
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 常ã«{@link JsTypes#OBJECT}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public JsTypes getJsTypes(){
+ return JsTypes.OBJECT;
+ }
+
+ /**
+ * ãã®Valueããã³åå«ã«å¤æ´ããã£ããå¤å®ããã
+ * PAIRã®è¿½å ã»åé¤ãè¡ããããã
+ * ãããã¯PAIRã®Valueå¤ããããã«å¤æ´ãèªããããã°ã
+ * ãã®OBJECTåValueã«å¤æ´ããã£ãã¨ã¿ãªãããã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean hasChanged(){
+ if(this.changed) return true;
+
+ for(JsPair pair : this){
+ JsValue value = pair.getValue();
+ if( ! (value instanceof JsComposition) ) continue;
+ JsComposition composition = (JsComposition) value;
+ if(composition.hasChanged()) return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * ãã®Valueããã³åå«ã«å¤æ´ããªãã£ããã¨ã«ããã
+ */
+ @Override
+ public void setUnchanged(){
+ this.changed = false;
+
+ for(JsPair pair : this){
+ JsValue value = pair.getValue();
+ if( ! (value instanceof JsComposition) ) continue;
+ JsComposition composition = (JsComposition) value;
+ composition.setUnchanged();
+ }
+
+ return;
+ }
+
+ /**
+ * æ·±ãåªå
æ¢ç´¢ãè¡ãå種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * thisãéç¥ããå¾ãPAIRã®åååããã³Valueãé ã«è¨ªåãã
+ * æå¾ã«éãæ¬å¼§ãéç¥ããã
+ * PAIRã®è¨ªåé ã«é¢ãã¦ã¯æªå®ç¾©ã
+ * @param visitor {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void traverse(ValueVisitor visitor) throws JsVisitException{
+ visitor.visitValue(this);
+
+ for(JsPair pair : this){
+ String name = pair.getName();
+ JsValue value = pair.getValue();
+ visitor.visitPairName(name);
+ value.traverse(visitor);
+ }
+
+ visitor.visitCompositionClose(this);
+
+ return;
+ }
+
+ /**
+ * PAIRç·æ°ãè¿ãã
+ * @return PAIRç·æ°
+ */
+ @Override
+ public int size(){
+ return this.pairMap.size();
+ }
+
+ /**
+ * PAIRéåã空ãå¤å®ããã
+ * @return 空ãªãtrue
+ */
+ @Override
+ public boolean isEmpty(){
+ return this.pairMap.isEmpty();
+ }
+
+ /**
+ * PAIRéåã空ã«ããã
+ */
+ @Override
+ public void clear(){
+ if(this.pairMap.size() > 0) this.changed = true;
+ this.pairMap.clear();
+ return;
+ }
+
+ /**
+ * ããã·ã¥å¤ãè¿ãã
+ * å
¨ã¦ã®PAIRã®ããã·ã¥å¤ãããã®é½åº¦åæããããé«ã³ã¹ã注æï¼ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode(){
+ return this.pairMap.hashCode();
+ }
+
+ /**
+ * ç価å¤å®ãè¡ãã
+ * åæ¹ã®PAIRæ°ãä¸è´ãã
+ * å
¨ã¦ã®PAIRåããã³ããã«å¯¾å¿ä»ããããValueãä¸è´ããå ´åã®ã¿
+ * ç価ã¨å¤æãããã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+
+ if( ! (obj instanceof JsObject) ) return false;
+ JsObject composit = (JsObject) obj;
+
+ return this.pairMap.equals(composit.pairMap);
+ }
+
+ /**
+ * ååã¨ValueããPAIRãç»é²ããã
+ * @param name åå
+ * @param value Value
+ * @return æ§Valueãåãå
容ã®PAIRããã§ã«åå¨ãã¦ãããnull
+ * @throws NullPointerException å¼æ°ã®ãããããnull
+ */
+ public JsValue putValue(String name, JsValue value)
+ throws NullPointerException{
+ if(name == null) throw new NullPointerException();
+ if(value == null) throw new NullPointerException();
+
+ JsValue oldValue = null;
+ JsPair oldPair = this.pairMap.get(name);
+ if(oldPair != null){
+ oldValue = oldPair.getValue();
+ if(value.equals(oldValue)) return null;
+ }
+
+ JsPair newPair = new JsPair(name, value);
+ this.pairMap.put(name, newPair);
+
+ this.changed = true;
+ return oldValue;
+ }
+
+ /**
+ * PAIRåããValueãåå¾ããã
+ * @param name PAIRå
+ * @return 対å¿ããValueãè¦ã¤ãããªããã°null
+ */
+ public JsValue getValue(String name){
+ JsPair pair = this.pairMap.get(name);
+ if(pair == null) return null;
+ JsValue value = pair.getValue();
+ return value;
+ }
+
+ /**
+ * PAIRã追å ããã
+ * åãPAIRåãæã¤PAIRã¯ç¡æ¡ä»¶ã«ä¸æ¸ããããã
+ * @param pair PAIR
+ */
+ public void putPair(JsPair pair){
+ this.pairMap.put(pair.getName(), pair);
+ return;
+ }
+
+ /**
+ * PAIRåããPAIRãè¿ãã
+ * @param name PAIRå
+ * @return PAIRãè¦ã¤ãããªããã°null
+ */
+ public JsPair getPair(String name){
+ JsValue value = getValue(name);
+ if(value == null) return null;
+
+ return new JsPair(name, value);
+ }
+
+ /**
+ * æå®ããååã®PAIRãåé¤ããã
+ * @param name PAIRå
+ * @return æ¶ãããPAIRã該å½ããPAIRããªããã°null
+ */
+ public JsPair remove(String name){
+ JsPair oldPair = this.pairMap.remove(name);
+ if(oldPair != null) this.changed = true;
+
+ return oldPair;
+ }
+
+ /**
+ * ä¿æããå
¨PAIRã®PAIRåã®éåãè¿ãã
+ * @return ãã¹ã¦ã®åå
+ */
+ public Set nameSet(){
+ return this.pairMap.keySet();
+ }
+
+ /**
+ * PAIRã®ãªã¹ããè¿ãã
+ * ãã®ãªã¹ããä¸æ¸ãæä½ãã¦ãå½±é¿ã¯ãªãã
+ * @return PAIRãªã¹ã
+ */
+ public List getPairList(){
+ List result = new ArrayList(this.pairMap.size());
+
+ for(JsPair pair : this){
+ result.add(pair);
+ }
+
+ return result;
+ }
+
+ /**
+ * PAIRã«ã¢ã¯ã»ã¹ããããã®å復åãæä¾ããã
+ * ãã®å復åã§ã®åé¤ä½æ¥ã¯ã§ããªãã
+ * PAIRåºç¾é åºã¯æªå®ç¾©ã
+ * @return å復åã¤ãã¬ã¼ã¿
+ */
+ public Iterator iterator(){
+ return UnmodIterator.unmodIterator(this.pairCollection);
+ }
+
+ /**
+ * æåå表ç¾ãè¿ãã
+ * JSON表è¨ã®å
¨ä½ãããã¯ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ StringBuilder text = new StringBuilder();
+
+ text.append("{");
+
+ boolean hasElem = false;
+ for(JsPair pair : this){
+ if(hasElem) text.append(',');
+ text.append(pair);
+ hasElem = true;
+ }
+
+ text.append("}");
+
+ return text.toString();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsPair.java b/src/main/java/jp/sourceforge/jovsonz/JsPair.java
new file mode 100644
index 0000000..4e4f5d6
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsPair.java
@@ -0,0 +1,172 @@
+/*
+ * JSON pair in object
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+
+/**
+ * OBJECTåValueå
ã«åæããããååã®ä»ããValueã¨ã®çµ(PAIR)ã
+ * PAIRã¯Valueã§ã¯ãªãã
+ *
+ *
+ *
+ * {
+ * "PairName1" : 99.9 ,
+ * "PairName2" : "textValue"
+ * }
+ *
+ *
+ *
+ */
+public class JsPair {
+
+ private final String name;
+ private final JsValue value;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param name PAIRå
+ * @param value PAIRåã«å¯¾å¿ä»ããããValue
+ * @throws NullPointerException å¼æ°ã®ãããããnull
+ */
+ public JsPair(String name, JsValue value)
+ throws NullPointerException{
+ super();
+
+ if(name == null || value == null) throw new NullPointerException();
+
+ this.name = name;
+ this.value = value;
+
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * STRINGåãValueã«æã¤PAIRãçæãããã
+ * @param name PAIRå
+ * @param text PAIRåã«å¯¾å¿ä»ããããæååãã¼ã¿ã
+ * ã¨ã¹ã±ã¼ããããå段éã®è¡¨è¨ã
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public JsPair(String name, CharSequence text)
+ throws NullPointerException{
+ this(name, (JsValue) new JsString(text) );
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * BOOLEANåãValueã«æã¤PAIRãçæãããã
+ * @param name PAIRå
+ * @param bool PAIRåã«å¯¾å¿ä»ããããçå½å¤
+ * @throws NullPointerException PAIRåãnull
+ */
+ public JsPair(String name, boolean bool)
+ throws NullPointerException{
+ this(name, JsBoolean.valueOf(bool));
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * NUMBERåãValueã«æã¤PAIRãçæãããã
+ * @param name PAIRå
+ * @param number PAIRåã«å¯¾å¿ä»ããããæ´æ°å¤
+ * @throws NullPointerException PAIRåãnull
+ */
+ public JsPair(String name, long number)
+ throws NullPointerException{
+ this(name, new JsNumber(number));
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * NUMBERåãValueã«æã¤PAIRãçæãããã
+ * @param name PAIRå
+ * @param number PAIRåã«å¯¾å¿ä»ããããå®æ°å¤
+ * @throws NullPointerException PAIRåãnull
+ */
+ public JsPair(String name, double number)
+ throws NullPointerException{
+ this(name, new JsNumber(number));
+ return;
+ }
+
+ /**
+ * PAIRåãè¿ãã
+ * @return PAIRå
+ */
+ public String getName(){
+ return this.name;
+ }
+
+ /**
+ * Valueãè¿ãã
+ * @return Value
+ */
+ public JsValue getValue(){
+ return this.value;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ããã·ã¥å¤ãè¿ãã
+ * PAIRåã¨Valueåæ¹ã®ããã·ã¥å¤ããåæãããã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode(){
+ int nameHash = this.name.hashCode();
+ int valHash = this.value.hashCode();
+ return nameHash ^ valHash;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ç価å¤å®ãè¡ãã
+ * PAIRåã¨Valueåæ¹ãä¸è´ããå ´åã®ã¿çã¨ãªãã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+
+ if( ! (obj instanceof JsPair) ) return false;
+ JsPair target = (JsPair) obj;
+
+ if( ! this.name .equals(target.name) ) return false;
+ if( ! this.value.equals(target.value) ) return false;
+
+ return true;
+ }
+
+ /**
+ * æåå表ç¾ãè¿ãã
+ * JSON表è¨ã®ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ StringBuilder result = new StringBuilder();
+ try{
+ JsString.dumpString(result, this.name);
+ }catch(IOException e){
+ assert false;
+ throw new AssertionError(e);
+ }
+
+ result.append(':')
+ .append(this.value.toString());
+
+ return result.toString();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsParseException.java b/src/main/java/jp/sourceforge/jovsonz/JsParseException.java
new file mode 100644
index 0000000..094da39
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsParseException.java
@@ -0,0 +1,98 @@
+/*
+ * JSON parse error information
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+/**
+ * å
¥åæååãã¼ã¹ä¸æä¾å¤ã
+ * JSONæååã½ã¼ã¹ã¸ã®ãã¼ã¹å¦çã®ä¸ææã«æããããã
+ */
+@SuppressWarnings("serial")
+public class JsParseException extends Exception {
+
+ static final String ERRMSG_INVALIDTOKEN =
+ "invalid JSON token";
+ static final String ERRMSG_INVALIDROOT =
+ "top root JSON value must be OBJECT or ARRAY";
+ static final String ERRMSG_NODATA =
+ "We need but no more JSON data";
+
+ private static final int LINE_UNKNOWN = 0;
+
+ private final int lineNumber;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ */
+ public JsParseException(){
+ this(null, LINE_UNKNOWN);
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param message 詳細ã¡ãã»ã¼ã¸ãä¸æãªå ´åã¯null
+ * @param lineNumber è¡çªå·ãä¸æãªå ´åã¯0以ä¸ã®å¤
+ */
+ public JsParseException(String message, int lineNumber){
+ this(message, (Throwable) null, lineNumber);
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param message 詳細ã¡ãã»ã¼ã¸ãä¸æãªå ´åã¯null
+ * @param cause åå ã¨ãªã£ãä¾å¤ãä¸æãªå ´åã¯null
+ * @param lineNumber è¡çªå·ãä¸æãªå ´åã¯0以ä¸ã®å¤
+ */
+ public JsParseException(String message, Throwable cause, int lineNumber){
+ super(message, cause);
+ this.lineNumber = lineNumber;
+ return;
+ }
+
+ /**
+ * ãã¼ã¹ã¨ã©ã¼ã®èµ·ããè¡çªå·ãè¿ãã
+ * @return è¡çªå·ãä¸æãªå ´åã¯0以ä¸ã®å¤ã
+ */
+ public int getLineNumber(){
+ return this.lineNumber;
+ }
+
+ /**
+ * æå¹ãªè¡çªå·ãä¿æãã¦ãããå¤å®ããã
+ * @return æå¹ãªè¡çªå·(1以ä¸)ãä¿æãã¦ããã°true
+ */
+ public boolean hasValidLineNumber(){
+ if(this.lineNumber > 0) return true;
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * æå¹ãªè¡çªå·ãããã°ä¸ç·ã«åºåãããã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String getMessage(){
+ StringBuilder message = new StringBuilder();
+
+ String superMessage = super.getMessage();
+ if(superMessage != null){
+ message.append(superMessage);
+ }
+
+ if(hasValidLineNumber()){
+ if(message.length() > 0) message.append(' ');
+ message.append("[line:").append(this.lineNumber).append(']');
+ }
+
+ if(message.length() <= 0) return null;
+ return message.toString();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsString.java b/src/main/java/jp/sourceforge/jovsonz/JsString.java
new file mode 100644
index 0000000..3f2ecc3
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsString.java
@@ -0,0 +1,380 @@
+/*
+ * JSON string value
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+
+/**
+ * JSON STRINGåValueã表ãã
+ * Unicodeæååãã¼ã¿ãåæ ããã
+ * 表è¨ä¾
+ *
+ * "xyz"
+ * "æ¼¢"
+ * "foo\nbar"
+ * "{@literal \}u304a"
+ * ""
+ *
+ */
+public class JsString
+ implements JsValue, CharSequence, Comparable {
+
+ private static final int HEX_BASE = 16;
+ private static final int NIBBLE_WIDE = 4;
+ private static final int NIBBLES_CHAR = Character.SIZE / NIBBLE_WIDE;
+
+ private static final String ERRMSG_INVESC = "invalid escape character";
+ private static final String ERRMSG_INVCTR = "invalid control character";
+
+ private final String rawText;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * é·ã0ã®ç©ºæåãè¨å®ãããã
+ */
+ public JsString(){
+ this("");
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * å¼æ°ã¯JSONæ¸å¼ã§ã¯ãªãçæååã
+ * @param rawSeq çæåå
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public JsString(CharSequence rawSeq) throws NullPointerException{
+ super();
+ if(rawSeq == null) throw new NullPointerException();
+ this.rawText = rawSeq.toString();
+ return;
+ }
+
+ /**
+ * FFFFå½¢å¼4æ¡ã§16é²ã¨ã¹ã±ã¼ããããæååãèªã¿ã
+ * char1æåã«ãã³ã¼ãããã
+ * @param source æååã½ã¼ã¹
+ * @return æå
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£è¡¨è¨ãããã¯æå³ããªãå
¥åçµäº
+ */
+ static char parseHexChar(JsonSource source)
+ throws IOException, JsParseException{
+ char hex1Ch = source.readOrDie();
+ char hex2Ch = source.readOrDie();
+ char hex3Ch = source.readOrDie();
+ char hex4Ch = source.readOrDie();
+
+ int digit1 = Character.digit(hex1Ch, HEX_BASE);
+ int digit2 = Character.digit(hex2Ch, HEX_BASE);
+ int digit3 = Character.digit(hex3Ch, HEX_BASE);
+ int digit4 = Character.digit(hex4Ch, HEX_BASE);
+
+ if( digit1 < 0
+ || digit2 < 0
+ || digit3 < 0
+ || digit4 < 0 ){
+ throw new JsParseException(ERRMSG_INVESC, source.getLineNumber());
+ }
+
+ int digit = 0;
+ digit += digit1;
+ digit <<= NIBBLE_WIDE;
+ digit += digit2;
+ digit <<= NIBBLE_WIDE;
+ digit += digit3;
+ digit <<= NIBBLE_WIDE;
+ digit += digit4;
+
+ char result = (char) digit;
+
+ return result;
+ }
+
+ /**
+ * '\'ã«ç¶ãã¹ãã·ã£ã«ãã£ã©ã®èªã¿è¾¼ã¿ãè¡ãã
+ * @param source æååã½ã¼ã¹
+ * @param app ã¹ãã·ã£ã«ãã£ã©æ ¼ç´æåå
+ * @throws IOException å
¥åºåã¨ã©ã¼
+ * @throws JsParseException "\z"ãªã©ã®ä¸æ£ãªã¹ãã·ã£ã«ãã£ã©
+ * ãããã¯æå³ããªãå
¥åçµäº
+ */
+ private static void parseSpecial(JsonSource source, Appendable app)
+ throws IOException, JsParseException{
+ char special;
+
+ char chData = source.readOrDie();
+ switch(chData){
+ case '"': special = '"'; break;
+ case '\\': special = '\\'; break;
+ case '/': special = '/'; break;
+ case 'b': special = '\b'; break;
+ case 'f': special = '\f'; break;
+ case 'n': special = '\n'; break;
+ case 'r': special = '\r'; break;
+ case 't': special = '\t'; break;
+ case 'u': special = parseHexChar(source); break;
+ default:
+ throw new JsParseException(ERRMSG_INVESC, source.getLineNumber());
+ }
+
+ app.append(special);
+
+ return;
+ }
+
+ /**
+ * JSONæååã½ã¼ã¹ããSTRINGåValueãèªã¿è¾¼ãã
+ * å¥åã®å¯è½æ§ã®ããå
é æåãèªã¿è¾¼ãã å ´åã
+ * ã½ã¼ã¹ã«æåãèªã¿æ»ããå¾nullãè¿ãããã
+ * @param source æååã½ã¼ã¹
+ * @return STRINGåValueãå¥åã®å¯è½æ§ãããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ä¸æ£ãªè¡¨è¨ãããã¯æå³ããªãå
¥åçµäº
+ */
+ static JsString parseString(JsonSource source)
+ throws IOException, JsParseException{
+ char charHead = source.readOrDie();
+ if(charHead != '"'){
+ source.unread(charHead);
+ return null;
+ }
+
+ StringBuilder text = new StringBuilder();
+
+ for(;;){
+ char chData = source.readOrDie();
+ if(chData == '"') break;
+
+ if(chData == '\\'){
+ parseSpecial(source, text);
+ }else if(Character.isISOControl(chData)){
+ throw new JsParseException(ERRMSG_INVCTR,
+ source.getLineNumber());
+ }else{
+ text.append(chData);
+ }
+ }
+
+ JsString result = new JsString(text);
+
+ return result;
+ }
+
+ /**
+ * ä»»æã®æåããã¨ã¹ã±ã¼ãåºåç¨ã·ã³ãã«ãå¾ãã
+ * ãã®ã·ã³ãã«ã¯'\'ã«ç¶ãã¦ç¨ãããã1æåã§ããã
+ * 'u'ãè¿ãäºã¯ããããªãã
+ * @param ch ä»»æã®æå
+ * @return ã¨ã¹ã±ã¼ãåºåç¨ã·ã³ãã«ã
+ * 1æåã¨ã¹ã±ã¼ãã®å¿
è¦ããªãå ´åã¯'\0'
+ */
+ private static char escapeSymbol(char ch){
+ char result;
+ switch(ch){
+ case '"' : result = '"'; break;
+ case '\\': result = '\\'; break;
+ case '/' : result = '/'; break;
+ case '\b': result = 'b'; break;
+ case '\f': result = 'f'; break;
+ case '\n': result = 'n'; break;
+ case '\r': result = 'r'; break;
+ case '\t': result = 't'; break;
+ default: result = '\0'; break;
+ }
+ return result;
+ }
+
+ /**
+ * ç¹æ®æåãã¨ã¹ã±ã¼ãåºåããã
+ * ç¹æ®æåã§ãªããã°ãªã«ãããªãã
+ * @param appout åºåå
+ * @param ch æå
+ * @return ç¹æ®æååºåãã¨ã¹ã±ã¼ããããæã«true
+ * @throws IOException åºåã¨ã©ã¼
+ */
+ private static boolean dumpSpecialChar(Appendable appout, char ch)
+ throws IOException{
+ char esc1ch = escapeSymbol(ch);
+
+ if(esc1ch != '\0'){
+ appout.append('\\').append(esc1ch);
+ }else if(Character.isISOControl(ch)){
+ // TODO ãããªãé«éåãå¿
è¦
+ String hex = "0000" + Integer.toHexString(ch);
+ hex = hex.substring(hex.length() - NIBBLES_CHAR);
+ appout.append("\\u").append(hex);
+ }else{
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * JSON STRINGåValueå½¢å¼ã§æååãåºåããã
+ * @param appout æååºå
+ * @param seq æåå
+ * @throws IOException åºåã¨ã©ã¼
+ */
+ public static void dumpString(Appendable appout, CharSequence seq)
+ throws IOException{
+ appout.append('"');
+
+ int length = seq.length();
+ for(int pos = 0; pos < length; pos++){
+ char ch = seq.charAt(pos);
+ if( ! dumpSpecialChar(appout, ch) ){
+ appout.append(ch);
+ }
+ }
+
+ appout.append('"');
+
+ return;
+ }
+
+ /**
+ * JSON STRINGåValueå½¢å¼ã®æååãè¿ãã
+ * @param seq çæåå
+ * @return STRINGå表è¨ã«å¤æãããæåå
+ */
+ // TODO ãããªã
+ public static StringBuilder escapeText(CharSequence seq){
+ StringBuilder result = new StringBuilder();
+ try{
+ dumpString(result, seq);
+ }catch(IOException e){
+ assert false;
+ throw new AssertionError(e);
+ }
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ * 常ã«{@link JsTypes#STRING}ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public JsTypes getJsTypes(){
+ return JsTypes.STRING;
+ }
+
+ /**
+ * å種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * ãã®å®è£
ã§ã¯thisã®åºç¾ã®ã¿ãéç¥ããã
+ * @param visitor {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void traverse(ValueVisitor visitor)
+ throws JsVisitException{
+ visitor.visitValue(this);
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ããã·ã¥å¤ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int hashCode(){
+ return this.rawText.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ * ç価å¤å®ãè¡ãã
+ * {@link java.lang.String#equals(Object)}ã«æºããã
+ * @param obj {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj){
+ if(this == obj) return true;
+
+ if( ! (obj instanceof JsString) ) return false;
+ JsString string = (JsString) obj;
+
+ return this.rawText.equals(string.rawText);
+ }
+
+ /**
+ * {@inheritDoc}
+ * STRINGåValueãæé ã«é åºä»ããã
+ * {@link java.lang.String#compareTo(String)}ã«æºããã
+ * @param value {@inheritDoc}
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int compareTo(JsString value){
+ if(this == value) return 0;
+ if(value == null) return +1;
+ return this.rawText.compareTo(value.rawText);
+ }
+
+ /**
+ * {@inheritDoc}
+ * æå®ä½ç½®ã®æåãè¿ãã
+ * @param index {@inheritDoc}
+ * @return {@inheritDoc}
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public char charAt(int index)
+ throws IndexOutOfBoundsException{
+ return this.rawText.charAt(index);
+ }
+
+ /**
+ * {@inheritDoc}
+ * æååé·(charå¤ç·æ°)ãè¿ãã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public int length(){
+ return this.rawText.length();
+ }
+
+ /**
+ * {@inheritDoc}
+ * é¨åæååãè¿ãã
+ * @param start {@inheritDoc}
+ * @param end {@inheritDoc}
+ * @return {@inheritDoc}
+ * @throws IndexOutOfBoundsException {@inheritDoc}
+ */
+ @Override
+ public CharSequence subSequence(int start, int end)
+ throws IndexOutOfBoundsException{
+ return this.rawText.subSequence(start, end);
+ }
+
+ /**
+ * ã¯ã©ã¼ãã¼ã·ã§ã³ãã¨ã¹ã±ã¼ãå¦çã®æ½ããã¦ããªãçã®æååãè¿ãã
+ * @return çã®æåå
+ */
+ public String toRawString(){
+ return this.rawText;
+ }
+
+ /**
+ * {@inheritDoc}
+ * ã¯ã©ã¼ãã¼ã·ã§ã³ã¨ã¨ã¹ã±ã¼ãå¦çã®æ½ãããæåå表è¨ãçæããã
+ * JSON表è¨ã®ä¸é¨ã¨ãã¦ã®å©ç¨ãå¯è½ã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public String toString(){
+ StringBuilder string = escapeText(this.rawText);
+ return string.toString();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsTypes.java b/src/main/java/jp/sourceforge/jovsonz/JsTypes.java
new file mode 100644
index 0000000..3e00a13
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsTypes.java
@@ -0,0 +1,84 @@
+/*
+ * JSON types
+ *
+ * License : The MIT License
+ * Copyright(c) 2010 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+/**
+ * JSON å種ååæã
+ */
+public enum JsTypes {
+
+ /** NUMBERåã«å¯¾å¿ã */
+ NUMBER (JsNumber .class),
+ /** STRINGåã«å¯¾å¿ã */
+ STRING (JsString .class),
+ /** BOOLEANåã«å¯¾å¿ã */
+ BOOLEAN (JsBoolean.class),
+ /** ARRAYåã«å¯¾å¿ã */
+ ARRAY (JsArray .class),
+ /** OBJECTåã«å¯¾å¿ã */
+ OBJECT (JsObject .class),
+ /** NULLåã«å¯¾å¿ã */
+ NULL (JsNull .class),
+ ;
+
+ private static final JsTypes[] VALUE_ARRAY = values();
+
+ private final Class extends JsValue> klass;
+ private final boolean isComposition;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param klass {@link java.lang.Class}å
+ */
+ private JsTypes(Class extends JsValue> klass){
+ this.klass = klass;
+
+ if(JsComposition.class.isAssignableFrom(this.klass)){
+ this.isComposition = true;
+ }else{
+ this.isComposition = false;
+ }
+
+ return;
+ }
+
+ /**
+ * {@link java.lang.Class}åãã対å¿ããååæãè¿ãã
+ * @param carg ä»»æã®java.lang.Classåå¤æ°
+ * @return ååæãJSONåã«ç±æ¥ããªãã¯ã©ã¹ãæå®ãããã¨ãã¯null
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public static JsTypes getJsTypes(Class> carg)
+ throws NullPointerException{
+ if(carg == null) throw new NullPointerException();
+
+ for(JsTypes types : VALUE_ARRAY){
+ if(types.klass == carg) return types;
+ }
+
+ return null;
+ }
+
+ /**
+ * 対å¿ãã{@link java.lang.Class}åãè¿ãã
+ * @return java.lang.Classå
+ */
+ public Class extends JsValue> getJsClass(){
+ return this.klass;
+ }
+
+ /**
+ * ãã®JSONåãåè¦ç´ ãæã¡ãããå¤å®ããã
+ * åè¦ç´ ãæã¡ããJSONåã¯OBJECTåãARRAYåã®ã¿ã
+ * @return åè¦ç´ ãæã¡ãããªãtrue
+ */
+ public boolean isComposition(){
+ return this.isComposition;
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsValue.java b/src/main/java/jp/sourceforge/jovsonz/JsValue.java
new file mode 100644
index 0000000..9635760
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsValue.java
@@ -0,0 +1,29 @@
+/*
+ * JSON value common interface
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+/**
+ * JSONå種Valueå
±éã¤ã³ã¿ãã§ã¼ã¹ã
+ */
+public interface JsValue {
+
+ /**
+ * 対å¿ããJSONååæãè¿ãã
+ * @return JSONååæ
+ */
+ JsTypes getJsTypes();
+
+ /**
+ * æ·±ãåªå
æ¢ç´¢ãè¡ãå種æ§é ã®åºç¾ããã¸ã¿ã¼ã«éç¥ããã
+ * @param visitor ãã¸ã¿ã¼
+ * @throws JsVisitException ãã¸ã¿ã¼ã«ãã
+ * ãã©ãã¼ã¹ä¸æãå¤æãããæã«æããããã
+ */
+ void traverse(ValueVisitor visitor) throws JsVisitException;
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsVisitException.java b/src/main/java/jp/sourceforge/jovsonz/JsVisitException.java
new file mode 100644
index 0000000..e976c47
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsVisitException.java
@@ -0,0 +1,58 @@
+/*
+ * JSON traverse error exception
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+/**
+ * ãã©ãã¼ã¹ä¸æä¾å¤ã
+ * JSONããªã¼æ§é ã®ãã©ãã¼ã¹å¦çã®ä¸ææã«æããããã
+ *
+ * ãã©ãã¼ã¹å¦çå
é¨ã§IOExceptionãªã©ã®ãã§ãã¯ä¾å¤ãçºçããå ´åã
+ * ãã§ã¼ã³ä¾å¤æ©æ§({@link java.lang.Throwable#getCause()} etc.)
+ * ãç¨ããã®ãæã¾ããã
+ *
+ */
+@SuppressWarnings("serial")
+public class JsVisitException extends Exception {
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ */
+ public JsVisitException(){
+ super();
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param message 詳細ã¡ãã»ã¼ã¸ãä¸æãªå ´åã¯null
+ */
+ public JsVisitException(String message){
+ super(message);
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param message 詳細ã¡ãã»ã¼ã¸ãä¸æãªå ´åã¯null
+ * @param cause åå ã¨ãªã£ãä¾å¤ãä¸æãªå ´åã¯null
+ */
+ public JsVisitException(String message, Throwable cause){
+ super(message, cause);
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param cause åå ã¨ãªã£ãä¾å¤ãä¸æãªå ´åã¯null
+ */
+ public JsVisitException(Throwable cause){
+ super(cause);
+ return;
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/Json.java b/src/main/java/jp/sourceforge/jovsonz/Json.java
new file mode 100644
index 0000000..b946308
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/Json.java
@@ -0,0 +1,128 @@
+/*
+ * JSON utilities
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * JSONå種å
±éã¦ã¼ãã£ãªãã£ã
+ */
+public final class Json {
+
+ /** MIME ã¿ã¤ãã */
+ public static final String MIME_TYPE = "application/json";
+
+
+ /**
+ * é ãã³ã³ã¹ãã©ã¯ã¿ã
+ */
+ private Json(){
+ assert false;
+ throw new AssertionError();
+ }
+
+ /**
+ * JSONæä¸ä½æ§é ããæååºåãéå§ããã
+ * @param appout åºåå
+ * @param topValue OBJECTåãARRAYåã®Value
+ * @throws NullPointerException å¼æ°ãnull
+ * @throws JsVisitException ä½ããã®çç±ã§å¦çä¸æ
+ * @throws IOException åºåã¨ã©ã¼
+ */
+ public static void dumpJson(Appendable appout, JsComposition topValue)
+ throws NullPointerException,
+ JsVisitException,
+ IOException {
+ if(appout == null || topValue == null){
+ throw new NullPointerException();
+ }
+
+ JsonAppender appender = new JsonAppender(appout);
+
+ try{
+ topValue.traverse(appender);
+ }catch(JsVisitException e){
+ assert appender.hasIOException();
+ throw appender.getIOException();
+ }
+
+ return;
+ }
+
+ /**
+ * JSONã®å種Valueãæåã½ã¼ã¹ããèªã¿åãã
+ * @param source æåå
¥å
+ * @return å種Valueã
+ * 0å以ä¸é£ç¶ãããã¯ã¤ãã¹ãã¼ã¹ã¨å
±ã«ã½ã¼ã¹ã®çµããã«éããã¨ãã¯null
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ãã¼ã¹ã¨ã©ã¼
+ */
+ static JsValue parseValue(JsonSource source)
+ throws IOException, JsParseException{
+ source.skipWhiteSpace();
+ if( ! source.hasMore() ) return null;
+
+ JsValue result;
+ result = JsObject .parseObject (source);
+ if(result != null) return result;
+ result = JsArray .parseArray (source);
+ if(result != null) return result;
+ result = JsString .parseString (source);
+ if(result != null) return result;
+ result = JsNull .parseNull (source);
+ if(result != null) return result;
+ result = JsBoolean.parseBoolean(source);
+ if(result != null) return result;
+ result = JsNumber .parseNumber (source);
+
+ if(result == null){
+ throw new JsParseException(JsParseException.ERRMSG_INVALIDTOKEN,
+ source.getLineNumber() );
+ }
+
+ return result;
+ }
+
+ /**
+ * JSONã®æä¸ä½æ§é ãæåã½ã¼ã¹ããèªã¿åãã
+ * @param source æåå
¥åã½ã¼ã¹
+ * @return JSONæä¸ä½æ§é ãOBJECTåãARRAYåã®ããããã
+ * å
¥åã0å以ä¸ã®ãã¯ã¤ãã¹ãã¼ã¹ã®ã¿ã§åãããã¦ããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ãã¼ã¹ã¨ã©ã¼
+ */
+ private static JsComposition parseJson(JsonSource source)
+ throws IOException, JsParseException{
+ JsValue topValue = parseValue(source);
+ if(topValue == null) return null;
+
+ if( ! (topValue instanceof JsComposition) ){
+ throw new JsParseException(JsParseException.ERRMSG_INVALIDROOT,
+ source.getLineNumber() );
+ }
+ JsComposition result = (JsComposition) topValue;
+
+ return result;
+ }
+
+ /**
+ * JSONã®æä¸ä½æ§é ãæåãªã¼ãããèªã¿åãã
+ * @param source æåå
¥åãªã¼ã
+ * @return JSONæä¸ä½æ§é ãOBJECTåãARRAYåã®ããããã
+ * å
¥åã0å以ä¸ã®ãã¯ã¤ãã¹ãã¼ã¹ã®ã¿ã§åãããã¦ããå ´åã¯nullã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException ãã¼ã¹ã¨ã©ã¼
+ */
+ public static JsComposition parseJson(Reader source)
+ throws IOException, JsParseException{
+ JsonSource jsonSource = new JsonSource(source);
+ return parseJson(jsonSource);
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsonAppender.java b/src/main/java/jp/sourceforge/jovsonz/JsonAppender.java
new file mode 100644
index 0000000..cbba7ad
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsonAppender.java
@@ -0,0 +1,443 @@
+/*
+ * JSON output
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.Flushable;
+import java.io.IOException;
+import java.util.EmptyStackException;
+import java.util.Stack;
+
+/**
+ * JSONæååºåç¨ãã¸ã¿ã¼ã
+ *
+ * JSON Valueã®ãã©ãã¼ã¹æã«ãã®ãã¸ã¿ã¼ãæå®ããã¨ã
+ * äºåã«ç¨æããæååºåå
ã«JSONãã©ã¼ãããã§åºåãããã
+ *
+ *
+ * åºåã«ä¼´ã{@link java.io.IOException}ã¯
+ * {@link JsVisitException}ã®ãã§ã¼ã³ä¾å¤ã¨ãªãã
+ *
+ *
+ * ååãã¼ã¹ã®æåï¼å¤±æã«é¢ãããã
+ * ã¤ã³ã¹ã¿ã³ã¹ã®åå©ç¨æã®æåã¯ä¿è¨¼ãããªãã
+ *
+ */
+class JsonAppender implements ValueVisitor {
+
+ /** æ¹è¡ã */
+ public static final String NEWLINE = "\n";
+ /** ã¤ã³ãã³ãåä½ã */
+ public static final String INDENT_UNIT = "\u0020\u0020";
+ /** Pairåºåãã */
+ public static final String PAIR_SEPARATOR = "\u0020:\u0020";
+ /** ã³ã³ãåºåãã */
+ public static final String COMMA = "\u0020,";
+ /** 空è¦ç´ ã */
+ public static final String EMPTY = "\u0020";
+
+
+ private final Appendable appout;
+
+ private final Stack contextStack =
+ new Stack();
+
+ private IOException ioException = null;
+
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param appout åºåå
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public JsonAppender(Appendable appout)
+ throws NullPointerException{
+ super();
+ if(appout == null) throw new NullPointerException();
+ this.appout = appout;
+ return;
+ }
+
+ /**
+ * ã³ã³ããã¹ããããã·ã¥éé¿ããã
+ * @param composition ç¾å¨ã®ã³ã³ããã¹ã
+ */
+ protected void pushComposition(JsComposition composition){
+ DumpContext context = new DumpContext(composition);
+ this.contextStack.push(context);
+ return;
+ }
+
+ /**
+ * ã³ã³ããã¹ããããã復帰ããã
+ * @return ã¹ã¿ãã¯ãããã®ã³ã³ããã¹ã
+ * @throws EmptyStackException ã¹ã¿ãã¯æ§é ã空
+ */
+ protected JsComposition popComposition() throws EmptyStackException{
+ DumpContext context = this.contextStack.pop();
+ JsComposition composition = context.getComposition();
+ return composition;
+ }
+
+ /**
+ * ãã¹ãæ§é ã®æ·±ããè¿ãã
+ * @return 0ããå§ã¾ãæ·±ã
+ */
+ protected int nestDepth(){
+ return this.contextStack.size();
+ }
+
+ /**
+ * ãã¹ãæ§é ã空(æ·±ã0)ãå¤å®ããã
+ * @return 空ãªãtrue
+ */
+ protected boolean isNestEmpty(){
+ return this.contextStack.isEmpty();
+ }
+
+ /**
+ * ãã¹ãå¾ãä¸ã¤ã§ãåè¦ç´ ãåºåããããå¤å®ããã
+ * @return åè¦ç´ ãåºåããã¦ããã°true
+ */
+ protected boolean hasChildDumped(){
+ if(isNestEmpty()) return false;
+ boolean result = this.contextStack.peek().hasChildDumped();
+ return result;
+ }
+
+ /**
+ * ç¾æç¹ã§ã®ãã¹ãã«å¯¾ããåè¦ç´ ãä¸ã¤ä»¥ä¸åºåæ¸ã¿ã§ããã¨è¨å®ããã
+ */
+ protected void setChildDumped(){
+ if(isNestEmpty()) return;
+ this.contextStack.peek().setChildDumped();
+ return;
+ }
+
+ /**
+ * ç¾å¨ã®ã³ã³ããã¹ããARRAYåé
åè¦ç´ åºåä¸ã®ç¶æ
ãå¦ãå¤å®ããã
+ * @return ç¾å¨ã®ã³ã³ããã¹ããARRAYåé
åè¦ç´ åºåä¸ãªãtrue
+ */
+ protected boolean isArrayContext(){
+ if(isNestEmpty()) return false;
+
+ DumpContext context = this.contextStack.peek();
+ JsComposition composition = context.getComposition();
+ JsTypes type = composition.getJsTypes();
+ if(type != JsTypes.ARRAY) return false;
+
+ return true;
+ }
+
+ /**
+ * 1æååºåã
+ * @param ch æå
+ * @throws JsVisitException åºåã¨ã©ã¼ã
+ * @see java.lang.Appendable#append(char)
+ */
+ protected void append(char ch) throws JsVisitException{
+ try{
+ this.appout.append(ch);
+ }catch(IOException e){
+ this.ioException = e;
+ throw new JsVisitException(e);
+ }
+ return;
+ }
+
+ /**
+ * æåååºåã
+ * @param seq æåå
+ * @throws JsVisitException åºåã¨ã©ã¼ã
+ * @see java.lang.Appendable#append(CharSequence)
+ */
+ protected void append(CharSequence seq) throws JsVisitException{
+ try{
+ this.appout.append(seq);
+ }catch(IOException e){
+ this.ioException = e;
+ throw new JsVisitException(e);
+ }
+ return;
+ }
+
+ /**
+ * å¯è½ã§ããã°åºåå
ããã©ãã·ã¥ããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ * @see java.io.Flushable
+ */
+ protected void flush() throws JsVisitException{
+ try{
+ if(this.appout instanceof Flushable){
+ ((Flushable)this.appout).flush();
+ }
+ }catch(IOException e){
+ this.ioException = e;
+ throw new JsVisitException(e);
+ }
+ return;
+ }
+
+ /**
+ * ãã©ãã¼ã¹ä¸æã®åå ã¨ãªã£ãIOExceptionãè¿ãã
+ * @return ãã©ãã¼ã¹ä¸æã®åå ã¨ãªã£ãIOExceptionããªããã°nullã
+ */
+ public IOException getIOException(){
+ return this.ioException;
+ }
+
+ /**
+ * ãã©ãã¼ã¹ä¸æã®åå ã¨ãªã£ãIOExceptionããããå¤å®ããã
+ * @return ãã©ãã¼ã¹ä¸æã®åå ã¨ãªã£ãIOExceptionãããã°true
+ */
+ public boolean hasIOException(){
+ if(this.ioException != null) return true;
+ return false;
+ }
+
+ /**
+ * pairã®ååãåºåããã
+ * @param name pairå
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putPairName(String name) throws JsVisitException{
+ try{
+ JsString.dumpString(this.appout, name);
+ }catch(IOException e){
+ this.ioException = e;
+ throw new JsVisitException(e);
+ }
+ return;
+ }
+
+ /**
+ * pairåºåãã³ãã³ãåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putPairSeparator() throws JsVisitException{
+ append(PAIR_SEPARATOR);
+ return;
+ }
+
+ /**
+ * è¦ç´ éåºåãã³ã³ããåºåããã
+ * JSONã§ã¯æå¾ã®è¦ç´ ã®å¾ã«ã³ã³ããåºåãã¦ã¯ãããªãã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putComma() throws JsVisitException{
+ append(COMMA);
+ return;
+ }
+
+ /**
+ * æ¹è¡ãåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼ã
+ */
+ protected void putNewLine() throws JsVisitException{
+ append(NEWLINE);
+ return;
+ }
+
+ /**
+ * ã¤ã³ãã³ããåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putIndent() throws JsVisitException{
+ int level = nestDepth();
+ for(int ct = 1; ct <= level; ct++){
+ append(INDENT_UNIT);
+ }
+ return;
+ }
+
+ /**
+ * OBJECTåã³ARRAYåã®æåã®è¦ç´ ã®åé¨åãåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putBefore1stElement() throws JsVisitException{
+ putNewLine();
+ putIndent();
+ return;
+ }
+
+ /**
+ * OBJECTåã³ARRAYåã®è¦ç´ éåºåããåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putBetweenElement() throws JsVisitException{
+ putComma();
+ putNewLine();
+ putIndent();
+ return;
+ }
+
+ /**
+ * OBJECTåã³ARRAYåã®æå¾ã®è¦ç´ ã®å¾é¨åãåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putAfterLastElement() throws JsVisitException{
+ putNewLine();
+ putIndent();
+ return;
+ }
+
+ /**
+ * OBJECTåã³ARRAYåã®ç©ºè¦ç´ ãåºåããã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putEmptyElement() throws JsVisitException{
+ append(EMPTY);
+ return;
+ }
+
+ /**
+ * ãã¼ã¹åã®åºåãè¡ãã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putBeforeParse() throws JsVisitException{
+ //NOTHING
+ return;
+ }
+
+ /**
+ * ãã¼ã¹å¾ã®åºåãè¡ãã
+ * @throws JsVisitException åºåã¨ã©ã¼
+ */
+ protected void putAfterParse() throws JsVisitException{
+ putNewLine();
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * Valueã®åºåãè¡ãã
+ * @param value {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ if(isNestEmpty()) putBeforeParse();
+
+ if(isArrayContext()){
+ if(hasChildDumped()) putBetweenElement();
+ else putBefore1stElement();
+ }
+
+ JsTypes type = value.getJsTypes();
+ switch(type){
+ case OBJECT: append('{'); break;
+ case ARRAY: append('['); break;
+ default: append(value.toString()); break;
+ }
+ setChildDumped();
+
+ if(type.isComposition()){
+ assert value instanceof JsComposition;
+ JsComposition composition = (JsComposition) value;
+ pushComposition(composition);
+ }
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * OBJECTå
ã®åpairã®ååãåºåããã
+ * @param pairName {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void visitPairName(String pairName)
+ throws JsVisitException{
+ if(hasChildDumped()) putBetweenElement();
+ else putBefore1stElement();
+
+ putPairName(pairName);
+ putPairSeparator();
+
+ setChildDumped();
+
+ return;
+ }
+
+ /**
+ * {@inheritDoc}
+ * éãæ¬å¼§ãåºåããã
+ * @param closed {@inheritDoc}
+ * @throws JsVisitException {@inheritDoc}
+ */
+ @Override
+ public void visitCompositionClose(JsComposition closed)
+ throws JsVisitException{
+ boolean hasDumped = hasChildDumped();
+ JsComposition composition = popComposition();
+
+ if(hasDumped) putAfterLastElement();
+ else putEmptyElement();
+
+ char closeBrace;
+ switch(composition.getJsTypes()){
+ case OBJECT: closeBrace = '}'; break;
+ case ARRAY: closeBrace = ']'; break;
+ default: assert false; throw new AssertionError();
+ }
+ append(closeBrace);
+
+ if(isNestEmpty()){
+ putAfterParse();
+ flush();
+ }
+
+ return;
+ }
+
+ /**
+ * ãã¹ããããåJSONéç´åã³ã³ããã¹ãã®åºåç¶æ³ã
+ */
+ private static class DumpContext{
+ private final JsComposition composition;
+ private boolean childDumped;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * åè¦ç´ ãåºåãããäºå®ã¯ç¡ãç¶æ
ã§å§ã¾ãã
+ * @param composition ã¬ãã«ã«å¯¾å¿ããOBJECTãããã¯ARRAYåValue
+ */
+ DumpContext(JsComposition composition){
+ this.composition = composition;
+ this.childDumped = false;
+ return;
+ }
+
+ /**
+ * ãã®ã¬ãã«ã«å¯¾å¿ããJSONéç´åãè¿ãã
+ * @return OBJECTãããã¯ARRAYåValue
+ */
+ JsComposition getComposition(){
+ return this.composition;
+ }
+
+ /**
+ * ãã®ã¬ãã«ã§åè¦ç´ åºåãè¡ããããå¤å®ããã
+ * @return åè¦ç´ åºåãè¡ããã¦ãããªãtrue
+ */
+ boolean hasChildDumped(){
+ return this.childDumped;
+ }
+
+ /**
+ * ãã®ã¬ãã«ã§åè¦ç´ åºåãè¡ãããäºå®ãè¨å®ããã
+ */
+ void setChildDumped(){
+ this.childDumped = true;
+ return;
+ }
+
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/JsonSource.java b/src/main/java/jp/sourceforge/jovsonz/JsonSource.java
new file mode 100644
index 0000000..1cb3566
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/JsonSource.java
@@ -0,0 +1,246 @@
+/*
+ * JSON stream source
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+/**
+ * JSONãã¼ã¿ç¨å
¥åã½ã¼ã¹ã
+ * å
èªã¿ããæåã®ããã·ã¥ããã¯æ©è½ã¨è¡çªå·ã®ã«ã¦ã³ãæ©è½ãæããã
+ * è¡çªå·ã¯1ããå§ã¾ãã
+ * è¡ã¨è¡ã¯LF('\n')ã§åºåããããã®ã¨ããã(â»CRã¯ç¡è¦)
+ * @see java.io.PushbackReader
+ * @see java.io.LineNumberReader
+ */
+class JsonSource implements Closeable {
+
+ /** ããã·ã¥ããã¯å¯è½ãªæåæ°ã */
+ private static final int PUSHBACK_TOKENS = 10;
+
+ private static final char LINEFEED = '\n'; // LF(0x0a)
+
+ private static final String ERRMSG_OVERFLOW =
+ "Pushback buffer overflow";
+ private static final String ERRMSG_CLOSED =
+ "Stream closed";
+
+ static{
+ assert "\\uXXXX".length() < PUSHBACK_TOKENS;
+ }
+
+ private final Reader reader;
+
+ // ããã·ã¥ããã¯ç¨æåã¹ã¿ãã¯æ§é ã
+ private final char[] charStack = new char[PUSHBACK_TOKENS];
+ private int stackPt = 0;
+
+ private int lineNumber = 1;
+
+ private boolean closed = false;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param reader æåå
¥åãªã¼ãã¼
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public JsonSource(Reader reader) throws NullPointerException{
+ super();
+ if(reader == null) throw new NullPointerException();
+ this.reader = reader;
+ return;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * ä»»æã®æååãå
¥åã½ã¼ã¹ã¨ããã
+ * @param text æåå
+ * @see java.io.StringReader
+ */
+ public JsonSource(CharSequence text){
+ this(new StringReader(text.toString()));
+ return;
+ }
+
+ /**
+ * JSONè¦æ ¼ã®whitespaceæåãå¤å®ããã
+ * @param ch å¤å®å¯¾è±¡æå
+ * @return whitespaceãªãtrue
+ */
+ public static boolean isWhitespace(char ch){
+ switch(ch){
+ case '\u0020':
+ case '\t':
+ case '\r':
+ case '\n':
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * JSONè¦æ ¼ã®whitespaceæåãå¤å®ããã
+ * @param ch å¤å®å¯¾è±¡æåã
+ * ä¸ä½16bitãã¼ãã§ãªããã°whitespaceã¨å¤å®ãããªãã
+ * @return whitespaceãªãtrueãå¼æ°ãè² ã®å ´åã¯falseã
+ */
+ public static boolean isWhitespace(int ch){
+ if((int)Character.MIN_VALUE > ch) return false;
+ if((int)Character.MAX_VALUE < ch) return false;
+ return isWhitespace((char)ch);
+ }
+
+ /**
+ * ããã·ã¥ããã¯å¯è½ãªæ®ãæåæ°ãè¿ãã
+ * @return ããã·ã¥ããã¯å¯è½ãªæ®ãæåæ°
+ */
+ public int getPushBackSpared(){
+ return PUSHBACK_TOKENS - this.stackPt;
+ }
+
+ /**
+ * ç¾æç¹ã§ã®è¡çªå·ãè¿ãã
+ * @return 1ããå§ã¾ãè¡çªå·
+ */
+ public int getLineNumber(){
+ return this.lineNumber;
+ }
+
+ /**
+ * 1æåèªã¿è¾¼ãã
+ * @return èªã¿è¾¼ãã æåãå
¥åãçµãã£ã¦ããå ´åã¯è² ã®å¤ã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @see java.io.Reader#read()
+ */
+ public int read() throws IOException{
+ if(this.closed) throw new IOException(ERRMSG_CLOSED);
+
+ int chData;
+ if(this.stackPt > 0){
+ chData = (int) this.charStack[--this.stackPt];
+ }else{
+ chData = this.reader.read();
+ }
+
+ if(chData == (int)LINEFEED) this.lineNumber++;
+
+ return chData;
+ }
+
+ /**
+ * å
¥åæ«ç«¯ã§ã¯ãªãã¨ä»®å®ãã¦1æåèªã¿è¾¼ãã
+ * @return èªã¿è¾¼ãã æåã
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException å
¥åãçµãã£ã¦ãã
+ */
+ public char readOrDie() throws IOException, JsParseException{
+ int chData = read();
+ if(chData < 0){
+ throw new JsParseException(JsParseException.ERRMSG_NODATA,
+ this.lineNumber);
+ }
+ return (char)chData;
+ }
+
+ /**
+ * å
¥åãæååã¨ããããããå¤å®ããã
+ * 失æãã¦ãèªã¿æ»ãã¯è¡ãããªãã
+ * é·ã0ã®æååã¯å¿
ããããã«æåããã
+ * @param seq ããã対象æåå
+ * @return ãããããã°true
+ * @throws IOException å
¥åã¨ã©ã¼
+ * @throws JsParseException å
¥åãçµãã£ã¦ããã
+ */
+ public boolean matchOrDie(CharSequence seq)
+ throws IOException, JsParseException{
+ int length = seq.length();
+ for(int pt = 0; pt < length; pt++){
+ if(readOrDie() != seq.charAt(pt)) return false;
+ }
+ return true;
+ }
+
+ /**
+ * 1æåèªã¿æ»ãã
+ * è¡æ°ã«ã¦ã³ãã¸ãåæ ãããã
+ * @param ch èªã¿æ»ãæå
+ * @throws IOException ãããã¡ããµããããã¯ã¯ãã¼ãºæ¸ã¿
+ */
+ public void unread(char ch) throws IOException{
+ if(this.closed) throw new IOException(ERRMSG_CLOSED);
+
+ if(this.stackPt >= PUSHBACK_TOKENS){
+ throw new IOException(ERRMSG_OVERFLOW);
+ }
+
+ this.charStack[this.stackPt++] = ch;
+
+ if(ch == LINEFEED) this.lineNumber--;
+
+ return;
+ }
+
+ /**
+ * 1æåèªã¿æ»ãã
+ * charåã«ãã£ã¹ãããå¼æ°ã次åèªã¿è¾¼ã¾ããã
+ * è¡æ°ã«ã¦ã³ãã¸ãåæ ãããã
+ * @param ch èªã¿æ»ãæåãè² ã®ç¬¦å·ãå«ãä¸ä½16bitã¯ç¡è¦ãããã
+ * @throws IOException ãããã¡ããµããããã¯ã¯ãã¼ãºæ¸ã¿
+ */
+ public void unread(int ch) throws IOException{
+ unread((char) ch);
+ return;
+ }
+
+ /**
+ * whitespaceæåãèªã¿é£ã°ãã
+ * @throws IOException å
¥åã¨ã©ã¼
+ */
+ public void skipWhiteSpace() throws IOException{
+ for(;;){
+ int chData = read();
+ if(chData < 0) break;
+ if( ! isWhitespace(chData) ){
+ unread(chData);
+ break;
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * ã¾ã èªã¿è¾¼ãããã¼ã¿ããããå¤å®ããã
+ * @return ã¾ã èªãããã¼ã¿ãããã°true
+ * @throws IOException IOå
¥åã¨ã©ã¼
+ */
+ public boolean hasMore() throws IOException{
+ int chData = read();
+ if(chData < 0) return false;
+ unread(chData);
+ return true;
+ }
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã§æå®ãããReaderãéããã
+ * ã¯ãã¼ãºå¾ã®èªã¿è¾¼ã¿ããã³èªã¿æ»ãåä½ã¯å
¨ã¦ä¾å¤ãæããã
+ * @throws IOException å
¥åºåã¨ã©ã¼
+ * @see java.io.Closeable
+ */
+ public void close() throws IOException{
+ this.closed = true;
+ this.stackPt = 0;
+ this.reader.close();
+ return;
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/UnmodIterator.java b/src/main/java/jp/sourceforge/jovsonz/UnmodIterator.java
new file mode 100644
index 0000000..2d42f95
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/UnmodIterator.java
@@ -0,0 +1,111 @@
+/*
+ * unmodifiable iterator wrap
+ *
+ * License : The MIT License
+ * Copyright(c) 2010 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * æ¢åã®{@link java.util.Iterator}ããã³{@link java.lang.Iterable}ã«å¯¾ãã
+ * åé¤ã®ã§ããªãå¤æ´æä½ä¸å¯ãªIteratorã©ãããæä¾ããã
+ * @param ã³ã¬ã¯ã·ã§ã³å
ã®è¦ç´ å
+ */
+public class UnmodIterator implements Iterator {
+
+ private final Iterator rawIterator;
+
+ /**
+ * ã³ã³ã¹ãã©ã¯ã¿ã
+ * @param iterator ã©ããå
Iterator
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public UnmodIterator(Iterator iterator) throws NullPointerException{
+ super();
+ if(iterator == null) throw new NullPointerException();
+ this.rawIterator = iterator;
+ return;
+ }
+
+ /**
+ * åé¤æä½ä¸å¯ãªã©ããIteratorãçæããã
+ * @param ã³ã¬ã¯ã·ã§ã³å
ã®è¦ç´ å
+ * @param iterator ã©ããå
Iterator
+ * @return å¤æ´æä½ä¸å¯ãªIterator
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public static Iterator wrapUnmod(Iterator iterator)
+ throws NullPointerException{
+ if(iterator == null) throw new NullPointerException();
+ return new UnmodIterator(iterator);
+ }
+
+ /**
+ * åé¤æä½ä¸å¯ãªã©ããIterableãçæããã
+ * @param ã³ã¬ã¯ã·ã§ã³å
ã®è¦ç´ å
+ * @param iterable ã©ããå
Iterable
+ * @return å¤æ´æä½ä¸å¯ãªIteratorãçæããIterable
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public static Iterable wrapUnmod(Iterable iterable)
+ throws NullPointerException{
+ if(iterable == null) throw new NullPointerException();
+ final Iterable innerArg = iterable;
+ return new Iterable(){
+ public Iterator iterator(){
+ Iterator iterator = innerArg.iterator();
+ return new UnmodIterator(iterator);
+ }
+ };
+ }
+
+ /**
+ * Iterableã«ç±æ¥ããåé¤æä½ä¸å¯ãªã©ããIteratorãçæããã
+ * @param ã³ã¬ã¯ã·ã§ã³å
ã®è¦ç´ å
+ * @param iterable Iterable
+ * @return å¤æ´æä½ä¸å¯ãªIterator
+ * @throws NullPointerException å¼æ°ãnull
+ */
+ public static Iterator unmodIterator(Iterable iterable)
+ throws NullPointerException{
+ if(iterable == null) throw new NullPointerException();
+ Iterator iterator = iterable.iterator();
+ return new UnmodIterator(iterator);
+ }
+
+ /**
+ * {@inheritDoc}
+ * å復åã«æ¬¡ã®è¦ç´ ããããå¤å®ããã
+ * @return {@inheritDoc}
+ */
+ @Override
+ public boolean hasNext(){
+ return this.rawIterator.hasNext();
+ }
+
+ /**
+ * {@inheritDoc}
+ * å復åã®æ¬¡ã®è¦ç´ ãåå¾ããã
+ * @return {@inheritDoc}
+ * @throws NoSuchElementException ãã以ä¸è¦ç´ ã¯ãªãã
+ */
+ @Override
+ public E next() throws NoSuchElementException{
+ return this.rawIterator.next();
+ }
+
+ /**
+ * {@inheritDoc}
+ * å¿
ã失æãä¾å¤ãæããã
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public void remove() throws UnsupportedOperationException{
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/ValueVisitor.java b/src/main/java/jp/sourceforge/jovsonz/ValueVisitor.java
new file mode 100644
index 0000000..99ba49a
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/ValueVisitor.java
@@ -0,0 +1,42 @@
+/*
+ * JSON value visitor
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+/**
+ * JSONããªã¼ä¸ã®åValueã¸ã®æ·±ãåªå
ãã¸ã¿ã¼å
±éã¤ã³ã¿ãã§ã¼ã¹ã
+ */
+public interface ValueVisitor {
+
+ /**
+ * Valueç»å ´ã®éç¥ãåãåãã
+ * @param value JSON Value
+ * @throws JsVisitException ãã¸ã¿ã¼ããã©ãã¼ã¹ä¸æ¢ãå¤æããéã«
+ * æããããã
+ */
+ void visitValue(JsValue value) throws JsVisitException;
+
+ /**
+ * OBJECTåå
é¨ã®PAIRåç»å ´ã®éç¥ãåãåãã
+ * PAIRã®ç¤ºãValueã®åºç¾ããç´åã«éç¥ãè¡ãããã
+ * @param pairName PAIRå
+ * @throws JsVisitException ãã¸ã¿ã¼ããã©ãã¼ã¹ä¸æ¢ãå¤æããéã«
+ * æããããã
+ */
+ void visitPairName(String pairName) throws JsVisitException;
+
+ /**
+ * æ¬å¼§æ§é çµäºã®éç¥ãåãåãã
+ * æ¬å¼§æ§é ãæã¤JSONåã¯ãOBJECTåãARRAYåã®ã¿ã
+ * @param composition OBJECTåãARRAYåã®ããããã®Value
+ * @throws JsVisitException ãã¸ã¿ã¼ããã©ãã¼ã¹ä¸æ¢ãå¤æããéã«
+ * æããããã
+ */
+ void visitCompositionClose(JsComposition composition)
+ throws JsVisitException;
+
+}
diff --git a/src/main/java/jp/sourceforge/jovsonz/package-info.java b/src/main/java/jp/sourceforge/jovsonz/package-info.java
new file mode 100644
index 0000000..7176733
--- /dev/null
+++ b/src/main/java/jp/sourceforge/jovsonz/package-info.java
@@ -0,0 +1,75 @@
+/*
+ * Jovsonz library package comment
+ *
+ * This source-file is something special for SunJDK5.0 Javadoc or later.
+ *
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+/**
+ * Jovsonz is a Java-library for JSON read/write purpose.
+ * Jovsonz library was derived from Jindolf project.
+ *
+ *
+ *
+ *
+ * The MIT License
+ *
+ *
+ * Copyright(c) 2009 olyutorskii
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ *
+ *
+ * JSONåºæ¬å
+ *
+ * OBJECTå
+ * { "Name" : "Joe", "Age" : 88 }
+ * ARRAYå
+ * [ true, "ABC", 23 ]
+ * STRINGå
+ * "ABC"
+ * NUMBERå
+ * -12.34
+ * BOOLEANå
+ * true
+ * NULLå
+ * null
+ *
+ *
+ * @see Introducing JSON
+ * @see JSONã®ç´¹ä»
+ * @see RFC4627
+ * @see
+ * Wikipedia(ja)解説
+ * @see
+ * Wikipedia(en)
+ */
+
+package jp.sourceforge.jovsonz;
+
+/* EOF */
diff --git a/src/main/resources/jp/sourceforge/jovsonz/resources/version.properties b/src/main/resources/jp/sourceforge/jovsonz/resources/version.properties
new file mode 100644
index 0000000..debc29b
--- /dev/null
+++ b/src/main/resources/jp/sourceforge/jovsonz/resources/version.properties
@@ -0,0 +1,7 @@
+# Version definition
+# [ with Maven resource filtering ]
+
+library.name = ${pom.name}
+library.version = ${pom.version}
+
+# EOF #
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsArrayTest.java b/src/test/java/jp/sourceforge/jovsonz/JsArrayTest.java
new file mode 100644
index 0000000..878d7f5
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsArrayTest.java
@@ -0,0 +1,503 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsArrayTest {
+
+ public JsArrayTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of parseArray method, of class JsArray.
+ */
+ @Test
+ public void testParseArray() throws Exception{
+ System.out.println("parseArray");
+
+ JsonSource source;
+ JsArray array;
+
+ source = new JsonSource("[]");
+ array = JsArray.parseArray(source);
+ assertEquals(0, array.size());
+
+ source = new JsonSource("[true]");
+ array = JsArray.parseArray(source);
+ assertEquals(1, array.size());
+ assertEquals(JsBoolean.TRUE, array.get(0));
+
+ source = new JsonSource("[true,false]");
+ array = JsArray.parseArray(source);
+ assertEquals(2, array.size());
+ assertEquals(JsBoolean.TRUE, array.get(0));
+ assertEquals(JsBoolean.FALSE, array.get(1));
+
+ source = new JsonSource("\n[\rtrue\t, false\n]\r");
+ array = JsArray.parseArray(source);
+ assertNull(array);
+
+ source = new JsonSource("[\rtrue\t, false\n]\r");
+ array = JsArray.parseArray(source);
+ assertEquals(2, array.size());
+ assertEquals(JsBoolean.TRUE, array.get(0));
+ assertEquals(JsBoolean.FALSE, array.get(1));
+
+ try{
+ source = new JsonSource("[,]");
+ array = JsArray.parseArray(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("[true,]");
+ array = JsArray.parseArray(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("[true#]");
+ array = JsArray.parseArray(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("[true,");
+ array = JsArray.parseArray(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("[true");
+ array = JsArray.parseArray(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ source = new JsonSource("true]");
+ array = JsArray.parseArray(source);
+ assertNull(array);
+
+ return;
+ }
+
+ /**
+ * Test of add method, of class JsArray.
+ */
+ @Test
+ public void testAdd(){
+ System.out.println("add");
+
+ JsArray array = new JsArray();
+
+ JsNumber number = new JsNumber("1.23");
+ assertEquals(0, array.size());
+ array.add(number);
+ assertEquals(1, array.size());
+ array.add(number);
+ assertEquals(2, array.size());
+
+ return;
+ }
+
+ /**
+ * Test of get method, of class JsArray.
+ */
+ @Test
+ public void testGet(){
+ System.out.println("get");
+
+ JsArray array = new JsArray();
+
+ JsValue val1 = new JsNumber("1.23");
+ JsValue val2 = new JsString("abc");
+
+ array.add(val1);
+ array.add(val2);
+
+ assertEquals(val1, array.get(0));
+ assertEquals(val2, array.get(1));
+
+ try{
+ array.get(2);
+ fail();
+ }catch(IndexOutOfBoundsException e){
+ // NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of clear method, of class JsArray.
+ */
+ @Test
+ public void testClear(){
+ System.out.println("clear");
+
+ JsArray array = new JsArray();
+
+ JsValue val1 = new JsNumber("1.23");
+ JsValue val2 = new JsString("abc");
+
+ array.add(val1);
+ array.add(val2);
+ assertEquals(2, array.size());
+
+ array.clear();
+ assertEquals(0, array.size());
+
+ try{
+ array.get(0);
+ fail();
+ }catch(IndexOutOfBoundsException e){
+ // NOTHING
+ }
+
+ array = new JsArray();
+ array.add(JsNull.NULL);
+ assertEquals(1, array.size());
+ assertTrue(array.hasChanged());
+ array.setUnchanged();
+ assertFalse(array.hasChanged());
+ array.clear();
+ assertEquals(0, array.size());
+ assertTrue(array.hasChanged());
+ array.setUnchanged();
+ array.clear();
+ assertEquals(0, array.size());
+ assertFalse(array.hasChanged());
+
+ return;
+ }
+
+ /**
+ * Test of remove method, of class JsArray.
+ */
+ @Test
+ public void testRemove_JsValue(){
+ System.out.println("remove");
+
+ JsArray array = new JsArray();
+
+ JsValue val1 = new JsNumber("1.23");
+ JsValue val2 = new JsString("abc");
+ JsValue val3 = JsBoolean.TRUE;
+
+ array.add(val1);
+ array.add(val2);
+ assertEquals(2, array.size());
+
+ assertTrue(array.remove(val1));
+ assertEquals(1, array.size());
+ assertEquals(val2, array.get(0));
+
+ assertFalse(array.remove(val3));
+ assertEquals(1, array.size());
+
+ return;
+ }
+
+ /**
+ * Test of remove method, of class JsArray.
+ */
+ @Test
+ public void testRemove_int(){
+ System.out.println("remove");
+
+ JsArray array = new JsArray();
+
+ JsValue val1 = new JsNumber("1.23");
+ JsValue val2 = new JsString("abc");
+ JsValue val3 = JsBoolean.TRUE;
+
+ array.add(val1);
+ array.add(val2);
+ array.add(val3);
+ assertEquals(3, array.size());
+
+ assertEquals(val1, array.remove(0));
+ assertEquals(2, array.size());
+ assertEquals(val2, array.get(0));
+
+ assertEquals(val3, array.remove(1));
+ assertEquals(1, array.size());
+ assertEquals(val2, array.get(0));
+
+ return;
+ }
+
+ /**
+ * Test of size method, of class JsArray.
+ */
+ @Test
+ public void testSize(){
+ System.out.println("size");
+
+ JsArray array = new JsArray();
+ assertEquals(0, array.size());
+ assertTrue(array.isEmpty());
+
+ JsValue val1 = new JsNumber("1.23");
+
+ array.add(val1);
+ assertEquals(1, array.size());
+ assertFalse(array.isEmpty());
+
+ return;
+ }
+
+ /**
+ * Test of iterator method, of class JsArray.
+ */
+ @Test
+ public void testIterator(){
+ System.out.println("iterator");
+
+ JsArray array = new JsArray();
+
+ JsValue val1 = new JsNumber("1.23");
+ JsValue val2 = new JsString("abc");
+
+ array.add(val1);
+ array.add(val2);
+
+ Iterator it = array.iterator();
+
+ assertTrue(it.hasNext());
+ assertEquals(val1, it.next());
+
+ assertTrue(it.hasNext());
+ assertEquals(val2, it.next());
+
+ assertFalse(it.hasNext());
+
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsArray.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+
+ JsArray array1 = new JsArray();
+ JsArray array2 = new JsArray();
+
+ assertEquals(array1.hashCode(), array2.hashCode());
+
+ array1.add(new JsString("abc"));
+ array2.add(new JsString("abc"));
+
+ assertEquals(array1.hashCode(), array2.hashCode());
+
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsArray.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ JsArray array1 = new JsArray();
+ JsArray array2 = new JsArray();
+
+ assertTrue(array1.equals(array2));
+
+ array1.add(new JsString("abc"));
+ array2.add(new JsString("abc"));
+
+ assertTrue(array1.equals(array2));
+
+ array1.add(new JsString("xyz"));
+ array2.add(new JsString("XYZ"));
+
+ assertFalse(array1.equals(array2));
+
+ JsArray nullVal = null;
+
+ assertFalse(array1.equals(nullVal));
+
+ assertFalse(array1.equals(""));
+
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsArray.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+
+ JsArray array = new JsArray();
+
+ assertEquals("[]", array.toString());
+
+ array.add(JsBoolean.TRUE);
+ assertEquals("[true]", array.toString());
+
+ array.add(JsBoolean.FALSE);
+ assertEquals("[true,false]", array.toString());
+
+ array.add(new JsArray());
+ assertEquals("[true,false,[]]", array.toString());
+
+ return;
+ }
+
+ /**
+ * Test of traverse method, of class JsArray.
+ */
+ @Test
+ public void testTraverse() throws Exception{
+ System.out.println("traverse");
+
+ JsArray array = new JsArray();
+ JsValue val1 = new JsNumber("12");
+ JsValue val2 = new JsString("AB");
+ array.add(val1);
+ array.add(val2);
+
+ final List visited = new LinkedList();
+
+ try{
+ array.traverse(new ValueVisitor(){
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ visited.add(value);
+ return;
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ visited.add(name);
+ return;
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ visited.add(composite);
+ return;
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+
+ assertEquals(4, visited.size());
+ assertEquals(array, visited.get(0));
+ assertEquals(val1, visited.get(1));
+ assertEquals(val2, visited.get(2));
+ assertEquals(array, visited.get(3));
+
+ return;
+ }
+
+ /**
+ * Test of hasChanged method, of class JsArray.
+ */
+ @Test
+ public void testHasChanged(){
+ System.out.println("hasChanged");
+
+ JsArray array = new JsArray();
+ assertFalse(array.hasChanged());
+
+ array.add(new JsNumber("0"));
+ assertTrue(array.hasChanged());
+
+ array.setUnchanged();
+ assertFalse(array.hasChanged());
+
+ JsArray child = new JsArray();
+ array.add(child);
+ array.setUnchanged();
+ assertFalse(array.hasChanged());
+
+ child.add(JsNull.NULL);
+ assertTrue(array.hasChanged());
+ array.setUnchanged();
+ assertFalse(array.hasChanged());
+
+ return;
+ }
+
+ /**
+ * Test of setUnchanged method, of class JsArray.
+ */
+ @Test
+ public void testSetUnchanged(){
+ System.out.println("setUnchanged");
+
+ JsArray array = new JsArray();
+ JsArray child = new JsArray();
+ array.add(child);
+
+ child.add(JsNull.NULL);
+ assertTrue(child.hasChanged());
+
+ array.setUnchanged();
+ assertFalse(child.hasChanged());
+
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsArray.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ JsArray instance = new JsArray();
+
+ assertEquals(JsTypes.ARRAY, instance.getJsTypes());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsBooleanTest.java b/src/test/java/jp/sourceforge/jovsonz/JsBooleanTest.java
new file mode 100644
index 0000000..2753630
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsBooleanTest.java
@@ -0,0 +1,335 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsBooleanTest {
+
+ public JsBooleanTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of traverse method, of class JsBoolean.
+ */
+ @Test
+ public void testTraverse(){
+ System.out.println("traverse");
+
+ try{
+ JsBoolean.TRUE.traverse(new ValueVisitor(){
+ int ct = 0;
+
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ assertEquals(JsBoolean.TRUE, value);
+ assertTrue(this.ct++ <= 0);
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+
+ try{
+ JsBoolean.FALSE.traverse(new ValueVisitor(){
+ int ct = 0;
+
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ assertEquals(JsBoolean.FALSE, value);
+ assertTrue(this.ct++ <= 0);
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+
+ return;
+ }
+
+ /**
+ * Test of valueOf method, of class JsBoolean.
+ */
+ @Test
+ public void testValueOf(){
+ System.out.println("valueOf");
+ assertEquals(JsBoolean.TRUE, JsBoolean.valueOf(true));
+ assertEquals(JsBoolean.FALSE, JsBoolean.valueOf(false));
+ return;
+ }
+
+ /**
+ * Test of booleanValue method, of class JsBoolean.
+ */
+ @Test
+ public void testBooleanValue(){
+ System.out.println("booleanValue");
+ assertTrue(JsBoolean.TRUE.booleanValue());
+ assertFalse(JsBoolean.FALSE.booleanValue());
+ return;
+ }
+
+ /**
+ * Test of isTrue method, of class JsBoolean.
+ */
+ @Test
+ public void testIsTrue(){
+ System.out.println("isTrue");
+ assertTrue(JsBoolean.TRUE.isTrue());
+ assertFalse(JsBoolean.FALSE.isTrue());
+ return;
+ }
+
+ /**
+ * Test of isFalse method, of class JsBoolean.
+ */
+ @Test
+ public void testIsFalse(){
+ System.out.println("isFalse");
+ assertFalse(JsBoolean.TRUE.isFalse());
+ assertTrue(JsBoolean.FALSE.isFalse());
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsBoolean.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+ assertEquals(JsBoolean.TRUE.hashCode(), JsBoolean.TRUE.hashCode());
+ assertEquals(JsBoolean.FALSE.hashCode(), JsBoolean.FALSE.hashCode());
+ // NOTHING
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsBoolean.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ JsBoolean nullVal = null;
+
+ assertTrue(JsBoolean.TRUE.equals(JsBoolean.TRUE));
+ assertFalse(JsBoolean.TRUE.equals(JsBoolean.FALSE));
+ assertFalse(JsBoolean.TRUE.equals(JsNull.NULL));
+ assertFalse(JsBoolean.TRUE.equals(nullVal));
+
+ assertFalse(JsBoolean.FALSE.equals(JsBoolean.TRUE));
+ assertTrue(JsBoolean.FALSE.equals(JsBoolean.FALSE));
+ assertFalse(JsBoolean.TRUE.equals(JsNull.NULL));
+ assertFalse(JsBoolean.FALSE.equals(nullVal));
+
+ return;
+ }
+
+ /**
+ * Test of compareTo method, of class JsBoolean.
+ */
+ @Test
+ public void testCompareTo(){
+ System.out.println("compareTo");
+ assertEquals(0, JsBoolean.TRUE.compareTo(JsBoolean.TRUE));
+ assertEquals(0, JsBoolean.FALSE.compareTo(JsBoolean.FALSE));
+ assertTrue(0 > JsBoolean.TRUE.compareTo(JsBoolean.FALSE));
+ assertTrue(0 < JsBoolean.FALSE.compareTo(JsBoolean.TRUE));
+
+ try{
+ JsBoolean.TRUE.compareTo(null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ try{
+ JsBoolean.FALSE.compareTo(null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ SortedSet set = new TreeSet();
+
+ set.clear();
+ set.add(JsBoolean.TRUE);
+ set.add(JsBoolean.FALSE);
+ assertEquals(JsBoolean.TRUE, set.first());
+ assertEquals(JsBoolean.FALSE, set.last());
+ set.clear();
+ set.add(JsBoolean.FALSE);
+ set.add(JsBoolean.TRUE);
+ assertEquals(JsBoolean.TRUE, set.first());
+ assertEquals(JsBoolean.FALSE, set.last());
+
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsBoolean.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+ assertEquals("true", JsBoolean.TRUE.toString());
+ assertEquals("false", JsBoolean.FALSE.toString());
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsBoolean.
+ */
+ @Test
+ public void testEtc(){
+ System.out.println("etc.");
+ assertNotNull(JsBoolean.TRUE);
+ assertNotNull(JsBoolean.FALSE);
+ assertTrue(JsBoolean.TRUE instanceof JsBoolean);
+ assertTrue(JsBoolean.FALSE instanceof JsBoolean);
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsBoolean.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ assertEquals(JsTypes.BOOLEAN, JsBoolean.TRUE.getJsTypes());
+
+ return;
+ }
+
+ /**
+ * Test of parseBoolean method, of class JsBoolean.
+ */
+ @Test
+ public void testParseBoolean() throws Exception{
+ System.out.println("parseBoolean");
+
+ JsonSource source;
+ JsBoolean result;
+
+ source = new JsonSource("true");
+ result = JsBoolean.parseBoolean(source);
+ assertEquals(JsBoolean.TRUE, result);
+
+ source = new JsonSource("false");
+ result = JsBoolean.parseBoolean(source);
+ assertEquals(JsBoolean.FALSE, result);
+
+ source = new JsonSource("X");
+ result = JsBoolean.parseBoolean(source);
+ assertNull(result);
+
+ try{
+ source = new JsonSource("tX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("trX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("truX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("fX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("faX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("falX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("falsX");
+ result = JsBoolean.parseBoolean(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsNullTest.java b/src/test/java/jp/sourceforge/jovsonz/JsNullTest.java
new file mode 100644
index 0000000..5e0f8e5
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsNullTest.java
@@ -0,0 +1,196 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsNullTest {
+
+ public JsNullTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of etc of class JsNull.
+ */
+ @Test
+ public void testEtc(){
+ System.out.println("etc");
+ assertNotNull(JsNull.NULL);
+ assertTrue(JsNull.NULL instanceof JsNull);
+ return;
+ }
+
+ /**
+ * Test of traverse method, of class JsNull.
+ */
+ @Test
+ public void testTraverse(){
+ System.out.println("traverse");
+ try{
+ JsNull.NULL.traverse(new ValueVisitor(){
+ int ct = 0;
+
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ assertEquals(JsNull.NULL, value);
+ assertTrue(this.ct++ <= 0);
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+ return;
+ }
+
+ /**
+ * Test of compareTo method, of class JsNull.
+ */
+ @Test
+ public void testCompareTo(){
+ System.out.println("compareTo");
+ assertEquals(0, JsNull.NULL.compareTo(JsNull.NULL));
+ try{
+ JsNull.NULL.compareTo(null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsNull.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+ assertEquals("null", JsNull.NULL.toString());
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsNull.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ JsNull instance = JsNull.NULL;
+
+ assertEquals(JsTypes.NULL, instance.getJsTypes());
+
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsNull.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ assertTrue(JsNull.NULL.equals(JsNull.NULL));
+
+ JsNull nullVal = null;
+ assertFalse(JsNull.NULL.equals(nullVal));
+
+ assertFalse(JsNull.NULL.equals(""));
+
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsNull.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+
+ assertEquals(JsNull.NULL.hashCode(), JsNull.NULL.hashCode());
+
+ return;
+ }
+
+ /**
+ * Test of parseNull method, of class JsNull.
+ */
+ @Test
+ public void testParseNull() throws Exception{
+ System.out.println("parseNull");
+
+ JsonSource source;
+ JsNull result;
+
+ source = new JsonSource("null");
+ result = JsNull.parseNull(source);
+ assertEquals(JsNull.NULL, result);
+
+ source = new JsonSource("X");
+ result = JsNull.parseNull(source);
+ assertNull(result);
+
+ try{
+ source = new JsonSource("nX");
+ result = JsNull.parseNull(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("nuX");
+ result = JsNull.parseNull(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource("nulX");
+ result = JsNull.parseNull(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsNumberTest.java b/src/test/java/jp/sourceforge/jovsonz/JsNumberTest.java
new file mode 100644
index 0000000..7eb5356
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsNumberTest.java
@@ -0,0 +1,536 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsNumberTest {
+
+ public JsNumberTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of parseNumber method, of class JsNumber.
+ */
+ @Test
+ public void testParseNumber() throws Exception{
+ System.out.println("parseNumber");
+
+ JsonSource source;
+ JsNumber number;
+
+ source = new JsonSource("0");
+ number = JsNumber.parseNumber(source);
+ assertEquals("0", number.toString());
+
+ source = new JsonSource("-0");
+ number = JsNumber.parseNumber(source);
+ assertEquals("0", number.toString());
+
+ source = new JsonSource("12");
+ number = JsNumber.parseNumber(source);
+ assertEquals("12", number.toString());
+
+ source = new JsonSource("-12");
+ number = JsNumber.parseNumber(source);
+ assertEquals("-12", number.toString());
+
+ source = new JsonSource("+12");
+ number = JsNumber.parseNumber(source);
+ assertNull(number);
+
+ try{
+ source = new JsonSource("12.");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("12.@");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ source = new JsonSource("12.34");
+ number = JsNumber.parseNumber(source);
+ assertEquals("12.34", number.toString());
+
+ source = new JsonSource("12.0");
+ number = JsNumber.parseNumber(source);
+ assertEquals("12.0", number.toString());
+
+ source = new JsonSource("12.00");
+ number = JsNumber.parseNumber(source);
+ assertEquals("12.00", number.toString());
+
+ source = new JsonSource("12.003");
+ number = JsNumber.parseNumber(source);
+ assertEquals("12.003", number.toString());
+
+ source = new JsonSource("12.0030");
+ number = JsNumber.parseNumber(source);
+ assertEquals("12.0030", number.toString());
+
+ try{
+ source = new JsonSource("09");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ source = new JsonSource("12e34");
+ number = JsNumber.parseNumber(source);
+ assertEquals("1.2E+35", number.toString());
+
+ source = new JsonSource("12E34");
+ number = JsNumber.parseNumber(source);
+ assertEquals("1.2E+35", number.toString());
+
+ source = new JsonSource("12e+34");
+ number = JsNumber.parseNumber(source);
+ assertEquals("1.2E+35", number.toString());
+
+ source = new JsonSource("12e-34");
+ number = JsNumber.parseNumber(source);
+ assertEquals("1.2E-33", number.toString());
+
+ source = new JsonSource("12e0034");
+ number = JsNumber.parseNumber(source);
+ assertEquals("1.2E+35", number.toString());
+
+ try{
+ source = new JsonSource("12e");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("12e+");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("12e-");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("12e#");
+ number = JsNumber.parseNumber(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ source = new JsonSource("-12.34e-056");
+ number = JsNumber.parseNumber(source);
+ assertEquals("-1.234E-55", number.toString());
+
+ return;
+ }
+
+ /**
+ * Test of constructor, of class JsNumber.
+ */
+ @Test
+ public void testConstructors() throws Exception{
+ System.out.println("constructor");
+
+ JsNumber number;
+ BigDecimal decimal;
+
+ number = new JsNumber(99L);
+ decimal = number.decimalValue();
+ assertEquals(new BigInteger("99"), decimal.unscaledValue());
+ assertEquals(0, decimal.scale());
+
+ number = new JsNumber(99.0);
+ decimal = number.decimalValue();
+ assertEquals(new BigInteger("990"), decimal.unscaledValue());
+ assertEquals(1, decimal.scale());
+
+ number = new JsNumber(new BigInteger("99"));
+ decimal = number.decimalValue();
+ assertEquals(new BigInteger("99"), decimal.unscaledValue());
+ assertEquals(0, decimal.scale());
+
+ number = new JsNumber("99.9");
+ decimal = number.decimalValue();
+ assertEquals(new BigInteger("999"), decimal.unscaledValue());
+ assertEquals(1, decimal.scale());
+
+ number = new JsNumber(new BigDecimal("99.9"));
+ decimal = number.decimalValue();
+ assertEquals(new BigInteger("999"), decimal.unscaledValue());
+ assertEquals(1, decimal.scale());
+
+ number = new JsNumber(1.0 / 10.0);
+ decimal = number.decimalValue();
+ assertEquals(new BigInteger("1"), decimal.unscaledValue());
+ assertEquals(1, decimal.scale());
+
+ number = new JsNumber(new BigDecimal(1.0 / 10.0));
+ decimal = number.decimalValue();
+ assertEquals(
+ new BigInteger(
+ "1000000000000000055511151231257827021181583404541015625"),
+ decimal.unscaledValue());
+ assertEquals(55, decimal.scale());
+
+ try{
+ number = new JsNumber((BigDecimal)null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of traverse method, of class JsNumber.
+ */
+ @Test
+ public void testTraverse(){
+ System.out.println("traverse");
+
+ JsNumber number = new JsNumber("0");
+
+ try{
+ number.traverse(new ValueVisitor(){
+ int ct = 0;
+
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ assertEquals(new JsNumber("0"), value);
+ assertTrue(this.ct++ <= 0);
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+
+ return;
+ }
+
+ /**
+ * Test of decimalValue method, of class JsNumber.
+ */
+ @Test
+ public void testDecimalValue(){
+ System.out.println("decimalValue");
+
+ JsNumber number = new JsNumber("-123.456e+1");
+ BigDecimal decimal = number.decimalValue();
+
+ assertEquals(new BigDecimal("-123.456e+1"), decimal);
+ assertEquals(2, decimal.scale());
+ assertEquals(new BigInteger("-123456"), decimal.unscaledValue());
+
+ return;
+ }
+
+ /**
+ * Test of intValue method, of class JsNumber.
+ */
+ @Test
+ public void testIntValue(){
+ System.out.println("intValue");
+
+ assertEquals(0, new JsNumber("0").intValue());
+ assertEquals(99, new JsNumber("99.9").intValue());
+ assertEquals(-99, new JsNumber("-99.9").intValue());
+ assertEquals(2147483647, new JsNumber("2147483647").intValue());
+
+ return;
+ }
+
+ /**
+ * Test of longValue method, of class JsNumber.
+ */
+ @Test
+ public void testLongValue(){
+ System.out.println("longValue");
+
+ assertEquals(0L, new JsNumber("0").longValue());
+ assertEquals(99L, new JsNumber("99.9").longValue());
+ assertEquals(-99L, new JsNumber("-99.9").longValue());
+ assertEquals(999999999999L, new JsNumber("999999999999").longValue());
+
+ return;
+ }
+
+ /**
+ * Test of floatValue method, of class JsNumber.
+ */
+ @Test
+ public void testFloatValue(){
+ System.out.println("floatValue");
+
+ assertEquals(1.25f, new JsNumber("1.25").floatValue(), 0.0);
+ assertEquals(1.25f, new JsNumber("125E-2").floatValue(), 0.0);
+
+ return;
+ }
+
+ /**
+ * Test of doubleValue method, of class JsNumber.
+ */
+ @Test
+ public void testDoubleValue(){
+ System.out.println("doubleValue");
+
+ assertEquals(1.25, new JsNumber("1.25").doubleValue(), 0.0);
+ assertEquals(1.25, new JsNumber("125E-2").doubleValue(), 0.0);
+
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsNumber.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+
+ assertEquals(new JsNumber("1").hashCode(), new JsNumber("1").hashCode());
+ assertEquals(new JsNumber("1.23").hashCode(), new JsNumber("123e-2").hashCode());
+
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsNumber.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ JsNumber nullVal = null;
+
+ assertTrue(new JsNumber("1").equals(new JsNumber("1")));
+ assertFalse(new JsNumber("1").equals(new JsNumber("2")));
+ assertFalse(new JsNumber("1").equals(nullVal));
+ assertFalse(new JsNumber("1").equals(""));
+
+ assertTrue(new JsNumber("1.23").equals(new JsNumber("123e-2")));
+ assertFalse(new JsNumber("1.0").equals(new JsNumber("1.00")));
+
+ return;
+ }
+
+ /**
+ * Test of compareTo method, of class JsNumber.
+ */
+ @Test
+ public void testCompareTo(){
+ System.out.println("compareTo");
+
+ assertTrue(0 > new JsNumber("-1").compareTo(new JsNumber("1")));
+ assertTrue(0 < new JsNumber("1").compareTo(new JsNumber("-1")));
+ assertTrue(new JsNumber("1").compareTo(new JsNumber("1")) == 0);
+
+ assertTrue(0 > new JsNumber("1").compareTo(new JsNumber("2")));
+ assertTrue(0 < new JsNumber("9").compareTo(new JsNumber("8")));
+
+ assertTrue(new JsNumber("1.23").compareTo(new JsNumber("123e-2")) == 0);
+ assertTrue(new JsNumber("1.0").compareTo(new JsNumber("1.00")) == 0);
+
+ JsNumber number = new JsNumber("99");
+ assertTrue(number.compareTo(number) == 0);
+
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsNumber.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+
+ JsNumber number;
+
+ number = new JsNumber("0");
+ assertEquals("0", number.toString());
+ number = new JsNumber("+0");
+ assertEquals("0", number.toString());
+ number = new JsNumber("-0");
+ assertEquals("0", number.toString());
+
+ number = new JsNumber("1");
+ assertEquals("1", number.toString());
+ number = new JsNumber("+1");
+ assertEquals("1", number.toString());
+ number = new JsNumber("-1");
+ assertEquals("-1", number.toString());
+
+ number = new JsNumber("0.0");
+ assertEquals("0.0", number.toString());
+
+ number = new JsNumber("1.0");
+ assertEquals("1.0", number.toString());
+
+ number = new JsNumber("1.00");
+ assertEquals("1.00", number.toString());
+
+ number = new JsNumber("0.1");
+ assertEquals("0.1", number.toString());
+
+ number = new JsNumber("0.10");
+ assertEquals("0.10", number.toString());
+
+ number = new JsNumber("0.000001");
+ assertEquals("0.000001", number.toString());
+
+ number = new JsNumber("0.0000001");
+ assertEquals("1E-7", number.toString());
+
+ number = new JsNumber("123e0");
+ assertEquals("123", number.toString());
+
+ number = new JsNumber("123e1");
+ assertEquals("1.23E+3", number.toString());
+
+ number = new JsNumber("123E1");
+ assertEquals("1.23E+3", number.toString());
+
+ number = new JsNumber("123e+1");
+ assertEquals("1.23E+3", number.toString());
+
+ number = new JsNumber("123e-1");
+ assertEquals("12.3", number.toString());
+
+ number = new JsNumber("123e-8");
+ assertEquals("0.00000123", number.toString());
+
+ number = new JsNumber("123e-9");
+ assertEquals("1.23E-7", number.toString());
+
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsNumber.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ JsNumber instance = new JsNumber(0);
+
+ assertEquals(JsTypes.NUMBER, instance.getJsTypes());
+
+ return;
+ }
+
+ /**
+ * Test of isLatinDigit method, of class JsNumber.
+ */
+ @Test
+ public void testIsLatinDigit(){
+ System.out.println("isLatinDigit");
+
+ assertTrue(JsNumber.isLatinDigit('0'));
+ assertTrue(JsNumber.isLatinDigit('1'));
+ assertTrue(JsNumber.isLatinDigit('2'));
+ assertTrue(JsNumber.isLatinDigit('3'));
+ assertTrue(JsNumber.isLatinDigit('4'));
+ assertTrue(JsNumber.isLatinDigit('5'));
+ assertTrue(JsNumber.isLatinDigit('6'));
+ assertTrue(JsNumber.isLatinDigit('7'));
+ assertTrue(JsNumber.isLatinDigit('8'));
+ assertTrue(JsNumber.isLatinDigit('9'));
+
+ assertFalse(JsNumber.isLatinDigit('A'));
+ assertFalse(JsNumber.isLatinDigit('+'));
+ assertFalse(JsNumber.isLatinDigit('-'));
+ assertFalse(JsNumber.isLatinDigit('.'));
+ assertFalse(JsNumber.isLatinDigit('\u0000'));
+ assertFalse(JsNumber.isLatinDigit('\uffff'));
+
+ return;
+ }
+
+ /**
+ * Test of scale method, of class JsNumber.
+ */
+ @Test
+ public void testScale() throws Exception{
+ System.out.println("scale");
+
+ JsNumber number;
+ JsonSource source;
+
+ source = new JsonSource("10");
+ number = JsNumber.parseNumber(source);
+ assertEquals(0, number.scale());
+
+ source = new JsonSource("10.0");
+ number = JsNumber.parseNumber(source);
+ assertEquals(1, number.scale());
+
+ source = new JsonSource("10.0E+3");
+ number = JsNumber.parseNumber(source);
+ assertEquals(-2, number.scale());
+
+ source = new JsonSource("10E+3");
+ number = JsNumber.parseNumber(source);
+ assertEquals(-3, number.scale());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsObjectTest.java b/src/test/java/jp/sourceforge/jovsonz/JsObjectTest.java
new file mode 100644
index 0000000..de35604
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsObjectTest.java
@@ -0,0 +1,560 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsObjectTest {
+
+ public JsObjectTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of parseObject method, of class JsObject.
+ */
+ @Test
+ public void testParseObject() throws Exception{
+ System.out.println("parseObject");
+
+ JsonSource source;
+ JsObject object;
+
+ source = new JsonSource("{}");
+ object = JsObject.parseObject(source);
+ assertEquals(0, object.size());
+
+ source = new JsonSource("{\"A\":true}");
+ object = JsObject.parseObject(source);
+ assertEquals(1, object.size());
+ assertEquals(JsBoolean.TRUE, object.getPair("A").getValue());
+
+ source = new JsonSource("{\"A\":true,\"B\":false}");
+ object = JsObject.parseObject(source);
+ assertEquals(2, object.size());
+ assertEquals(JsBoolean.TRUE, object.getPair("A").getValue());
+ assertEquals(JsBoolean.FALSE, object.getPair("B").getValue());
+
+ source = new JsonSource("\n{\r\"A\"\t: true,\"B\":false\n}\r");
+ object = JsObject.parseObject(source);
+ assertNull(object);
+
+ source = new JsonSource("{\r\"A\"\t: true,\"B\":false\n}\r");
+ object = JsObject.parseObject(source);
+ assertEquals(2, object.size());
+ assertEquals(JsBoolean.TRUE, object.getPair("A").getValue());
+ assertEquals(JsBoolean.FALSE, object.getPair("B").getValue());
+
+ try{
+ source = new JsonSource("{,}");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{true,}");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{true");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{\"A\",");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{\"A\":");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{\"A\":#");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{\"A\":true#");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{\"A\":true,");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("{\"A\":true,#");
+ object = JsObject.parseObject(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ source = new JsonSource("true}");
+ object = JsObject.parseObject(source);
+ assertNull(object);
+
+ return;
+ }
+
+ /**
+ * Test of putValue method, of class JsObject.
+ */
+ @Test
+ public void testPutGetValue(){
+ System.out.println("putValue");
+
+ JsObject object = new JsObject();
+ assertEquals(0, object.size());
+
+ object.putValue("x", JsNull.NULL);
+ assertEquals(1, object.size());
+ assertEquals(JsNull.NULL, object.getValue("x"));
+ assertEquals(null, object.getValue("y"));
+
+ object.putValue("y", JsBoolean.TRUE);
+ assertEquals(2, object.size());
+ assertEquals(JsBoolean.TRUE, object.getValue("y"));
+
+ object.putValue("x", JsBoolean.FALSE);
+ assertEquals(2, object.size());
+ assertEquals(JsBoolean.FALSE, object.getValue("x"));
+
+ try{
+ object.putValue("x", null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ try{
+ object.putValue(null, JsNull.NULL);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of putPair method, of class JsObject.
+ */
+ @Test
+ public void testPutGetPair(){
+ System.out.println("putPair");
+
+ JsObject object = new JsObject();
+ assertEquals(0, object.size());
+
+ JsPair pair = new JsPair("x", JsNull.NULL);
+ object.putPair(pair);
+ assertEquals(1, object.size());
+ assertEquals(JsNull.NULL, object.getValue("x"));
+
+ JsPair pair2 = object.getPair("x");
+ assertNotNull(pair2);
+ assertEquals("x", pair2.getName());
+ assertEquals(JsNull.NULL, pair2.getValue());
+
+ assertNull(object.getPair("y"));
+
+ return;
+ }
+
+ /**
+ * Test of clear method, of class JsObject.
+ */
+ @Test
+ public void testClear(){
+ System.out.println("clear");
+
+ JsObject object = new JsObject();
+ assertEquals(0, object.size());
+
+ object.putValue("x", JsNull.NULL);
+ assertEquals(1, object.size());
+
+ object.clear();
+ assertEquals(0, object.size());
+
+ object = new JsObject();
+ object.putValue("x", JsNull.NULL);
+ assertEquals(1, object.size());
+ assertTrue(object.hasChanged());
+ object.setUnchanged();
+ assertFalse(object.hasChanged());
+ object.clear();
+ assertEquals(0, object.size());
+ assertTrue(object.hasChanged());
+ object.setUnchanged();
+ object.clear();
+ assertEquals(0, object.size());
+ assertFalse(object.hasChanged());
+
+ return;
+ }
+
+ /**
+ * Test of remove method, of class JsObject.
+ */
+ @Test
+ public void testRemove(){
+ System.out.println("remove");
+
+ JsObject object = new JsObject();
+
+ object.putValue("x", JsNull.NULL);
+ assertEquals(1, object.size());
+
+ assertNotNull(object.getValue("x"));
+
+ assertEquals(JsNull.NULL, object.remove("x").getValue());
+ assertEquals(0, object.size());
+ assertNull(object.getValue("x"));
+
+ assertNull(object.remove("y"));
+
+ return;
+ }
+
+ /**
+ * Test of nameSet method, of class JsObject.
+ */
+ @Test
+ public void testNameSet(){
+ System.out.println("nameSet");
+
+ JsObject object = new JsObject();
+ Set set;
+
+ set = object.nameSet();
+ assertEquals(0, set.size());
+
+ object.putValue("y", JsNull.NULL);
+ object.putValue("z", JsNull.NULL);
+ object.putValue("x", JsNull.NULL);
+
+ set = object.nameSet();
+ assertEquals(3, set.size());
+ Object[] names = set.toArray();
+
+ assertEquals("x", names[0]);
+ assertEquals("y", names[1]);
+ assertEquals("z", names[2]);
+
+ return;
+ }
+
+ /**
+ * Test of getPairList method, of class JsObject.
+ */
+ @Test
+ public void testGetPairList(){
+ System.out.println("getPairList");
+
+ JsObject object = new JsObject();
+ List list;
+
+ list = object.getPairList();
+ assertEquals(0, list.size());
+
+ object.putValue("y", JsNull.NULL);
+ object.putValue("z", JsBoolean.TRUE);
+ object.putValue("x", JsBoolean.FALSE);
+
+ list = object.getPairList();
+ assertEquals(3, list.size());
+
+ assertEquals("x", list.get(0).getName());
+ assertEquals("y", list.get(1).getName());
+ assertEquals("z", list.get(2).getName());
+ assertEquals(JsBoolean.FALSE, list.get(0).getValue());
+ assertEquals(JsNull.NULL, list.get(1).getValue());
+ assertEquals(JsBoolean.TRUE, list.get(2).getValue());
+
+ return;
+ }
+
+ /**
+ * Test of iterator method, of class JsObject.
+ */
+ @Test
+ public void testIterator(){
+ System.out.println("iterator");
+
+ JsObject object = new JsObject();
+ object.putValue("y", JsBoolean.FALSE);
+ object.putValue("x", JsBoolean.TRUE);
+
+ Iterator it = object.iterator();
+
+ assertTrue(it.hasNext());
+ assertEquals(JsBoolean.TRUE, it.next().getValue());
+ assertTrue(it.hasNext());
+ assertEquals(JsBoolean.FALSE, it.next().getValue());
+ assertFalse(it.hasNext());
+
+ return;
+ }
+
+ /**
+ * Test of size method, of class JsObject.
+ */
+ @Test
+ public void testSize(){
+ System.out.println("size");
+
+ JsObject object = new JsObject();
+ assertEquals(0, object.size());
+ assertTrue(object.isEmpty());
+
+ object.putValue("x", JsBoolean.TRUE);
+ assertEquals(1, object.size());
+ assertFalse(object.isEmpty());
+
+ object.putValue("y", JsBoolean.FALSE);
+ assertEquals(2, object.size());
+ assertFalse(object.isEmpty());
+
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsObject.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+
+ JsObject obj1 = new JsObject();
+ JsObject obj2 = new JsObject();
+ assertEquals(obj1.hashCode(), obj2.hashCode());
+
+ obj1.putValue("x", new JsNumber("99"));
+ obj2.putValue("x", new JsNumber("99"));
+ assertEquals(obj1.hashCode(), obj2.hashCode());
+
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsObject.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ JsObject obj1 = new JsObject();
+ JsObject obj2 = new JsObject();
+ assertTrue(obj1.equals(obj2));
+
+ obj1.putValue("x", new JsNumber("99"));
+ obj2.putValue("x", new JsNumber("99"));
+ assertTrue(obj1.equals(obj2));
+
+ obj1.putValue("x", new JsNumber("99"));
+ obj2.putValue("x", new JsNumber("999"));
+ assertFalse(obj1.equals(obj2));
+
+ JsObject nullVal = null;
+ assertFalse(obj1.equals(nullVal));
+ assertFalse(obj1.equals(""));
+
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsObject.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+
+ JsObject object = new JsObject();
+
+ assertEquals("{}", object.toString());
+
+ object.putValue("x", JsBoolean.TRUE);
+ assertEquals("{\"x\":true}", object.toString());
+
+ object.putValue("y", JsBoolean.FALSE);
+ assertEquals("{\"x\":true,\"y\":false}", object.toString());
+
+ object.putValue("z", new JsObject());
+ assertEquals("{\"x\":true,\"y\":false,\"z\":{}}", object.toString());
+
+ return;
+ }
+
+ /**
+ * Test of traverse method, of class JsObject.
+ */
+ @Test
+ public void testTraverse() throws Exception{
+ System.out.println("traverse");
+
+ JsObject obj = new JsObject();
+ JsValue val1 = new JsNumber("12");
+ JsValue val2 = new JsString("AB");
+ obj.putValue("x", val1);
+ obj.putValue("y", val2);
+
+ final List visited = new LinkedList();
+
+ try{
+ obj.traverse(new ValueVisitor(){
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ visited.add(value);
+ return;
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ visited.add(name);
+ return;
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ visited.add(composite);
+ return;
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+
+ assertEquals(6, visited.size());
+ assertEquals(obj, visited.get(0));
+ assertEquals("x", visited.get(1));
+ assertEquals(val1, visited.get(2));
+ assertEquals("y", visited.get(3));
+ assertEquals(val2, visited.get(4));
+ assertEquals(obj, visited.get(5));
+
+ return;
+ }
+
+ /**
+ * Test of hasChanged method, of class JsObject.
+ */
+ @Test
+ public void testHasChanged(){
+ System.out.println("hasChanged");
+
+ JsObject obj = new JsObject();
+ assertFalse(obj.hasChanged());
+
+ obj.putValue("x", JsNull.NULL);
+ assertTrue(obj.hasChanged());
+
+ obj.setUnchanged();
+ assertFalse(obj.hasChanged());
+
+ JsObject child = new JsObject();
+ obj.putValue("y", child);
+ obj.setUnchanged();
+ assertFalse(obj.hasChanged());
+
+ child.putValue("z", JsBoolean.TRUE);
+ assertTrue(obj.hasChanged());
+ obj.setUnchanged();
+ assertFalse(obj.hasChanged());
+
+ return;
+ }
+
+ /**
+ * Test of setUnchanged method, of class JsObject.
+ */
+ @Test
+ public void testSetUnchanged(){
+ System.out.println("setUnchanged");
+
+ JsObject obj = new JsObject();
+ JsObject child = new JsObject();
+ obj.putValue("x", child);
+
+ child.putValue("y", JsNull.NULL);
+ assertTrue(child.hasChanged());
+
+ obj.setUnchanged();
+ assertFalse(child.hasChanged());
+
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsObject.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ JsObject instance = new JsObject();
+
+ assertEquals(JsTypes.OBJECT, instance.getJsTypes());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsPairTest.java b/src/test/java/jp/sourceforge/jovsonz/JsPairTest.java
new file mode 100644
index 0000000..803ee68
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsPairTest.java
@@ -0,0 +1,208 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsPairTest {
+
+ public JsPairTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of Constructor, of class JsPair.
+ */
+ @Test
+ public void testConstructor(){
+ System.out.println("constructor");
+
+ JsPair pair = null;
+
+ try{
+ pair = new JsPair(null, 3);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ try{
+ pair = new JsPair("three", (String)null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ try{
+ pair = new JsPair(null, (String)null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ try{
+ pair = new JsPair("three", (JsValue)null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ try{
+ pair = new JsPair(null, (JsValue)null);
+ fail();
+ }catch(NullPointerException e){
+ // NOTHING
+ }
+
+ assertNull(pair);
+
+ return;
+ }
+
+ /**
+ * Test of getName method, of class JsPair.
+ */
+ @Test
+ public void testGetName(){
+ System.out.println("getName");
+
+ JsPair pair;
+
+ pair = new JsPair("", JsNull.NULL);
+ assertEquals("", pair.getName());
+
+ pair = new JsPair("a", JsNull.NULL);
+ assertEquals("a", pair.getName());
+
+ return;
+ }
+
+ /**
+ * Test of getValue method, of class JsPair.
+ */
+ @Test
+ public void testGetValue(){
+ System.out.println("getValue");
+
+ JsPair pair;
+
+ pair = new JsPair("x", JsNull.NULL);
+ assertEquals(JsNull.NULL, pair.getValue());
+
+ pair = new JsPair("x", "abc");
+ assertEquals(new JsString("abc"), pair.getValue());
+
+ pair = new JsPair("x", true);
+ assertEquals(JsBoolean.TRUE, pair.getValue());
+
+ pair = new JsPair("x", false);
+ assertEquals(JsBoolean.FALSE, pair.getValue());
+
+ pair = new JsPair("x", 999999999999L);
+ assertEquals(new JsNumber("999999999999"), pair.getValue());
+
+ pair = new JsPair("x", 1.25);
+ assertEquals(new JsNumber("1.25"), pair.getValue());
+
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsPair.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+
+ JsPair pair;
+
+ pair = new JsPair("x", JsNull.NULL);
+ assertEquals("\"x\":null", pair.toString());
+
+ pair = new JsPair("", JsNull.NULL);
+ assertEquals("\"\":null", pair.toString());
+
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsPair.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ JsPair pair1;
+ JsPair pair2;
+ JsPair nullVal = null;
+
+ pair1 = new JsPair("three", 3);
+ pair2 = new JsPair("three", 3);
+
+ assertFalse(pair1.equals(nullVal));
+ assertTrue(pair1.equals(pair1));
+ assertTrue(pair1.equals(pair2));
+ assertFalse(pair1.equals(new Object()));
+
+ pair2 = new JsPair("three", 4);
+ assertFalse(pair1.equals(pair2));
+
+ pair2 = new JsPair("two", 3);
+ assertFalse(pair1.equals(pair2));
+
+ pair2 = new JsPair("four", 4);
+ assertFalse(pair1.equals(pair2));
+
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsPair.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+
+ JsPair pair1;
+ JsPair pair2;
+
+ pair1 = new JsPair("three", 3);
+ pair2 = new JsPair("three", 3);
+
+ assertEquals(pair1.hashCode(), pair2.hashCode());
+
+ int hash1 = pair1.hashCode();
+ int hash2 = pair1.hashCode();
+
+ assertEquals(hash1, hash2);
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsParseExceptionTest.java b/src/test/java/jp/sourceforge/jovsonz/JsParseExceptionTest.java
new file mode 100644
index 0000000..3b81940
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsParseExceptionTest.java
@@ -0,0 +1,115 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsParseExceptionTest {
+
+ public JsParseExceptionTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of getLineNumber method, of class JsParseException.
+ */
+ @Test
+ public void testGetLineNumber(){
+ System.out.println("getLineNumber");
+
+ JsParseException ex;
+
+ ex = new JsParseException();
+ assertTrue(1 > ex.getLineNumber());
+ assertFalse(ex.hasValidLineNumber());
+
+ ex = new JsParseException("abc", 99);
+ assertEquals(99, ex.getLineNumber());
+ assertTrue(ex.hasValidLineNumber());
+
+ ex = new JsParseException("abc", new Throwable(), 99);
+ assertEquals(99, ex.getLineNumber());
+ assertTrue(ex.hasValidLineNumber());
+
+ return;
+ }
+
+ /**
+ * Test of getMessage method, of class JsParseException.
+ */
+ @Test
+ public void testGetMessage(){
+ System.out.println("getMessage");
+
+ JsParseException ex;
+
+ ex = new JsParseException();
+ assertNull(ex.getMessage());
+
+ ex = new JsParseException("abc", 99);
+ assertEquals("abc [line:99]", ex.getMessage());
+
+ ex = new JsParseException("abc", new Throwable(), 99);
+ assertEquals("abc [line:99]", ex.getMessage());
+
+ ex = new JsParseException(null, new Throwable(), 99);
+ assertEquals("[line:99]", ex.getMessage());
+
+ ex = new JsParseException(null, new Throwable(), 0);
+ assertNull(ex.getMessage());
+
+ ex = new JsParseException("abc", new Throwable(), 0);
+ assertEquals("abc", ex.getMessage());
+
+ return;
+ }
+
+ /**
+ * Test of getCause method, of class JsParseException.
+ */
+ @Test
+ public void testGetCause(){
+ System.out.println("getMessage");
+
+ JsParseException ex;
+
+ ex = new JsParseException();
+ assertNull(ex.getCause());
+
+ ex = new JsParseException("abc", 99);
+ assertNull(ex.getCause());
+
+ Throwable cause = new Throwable();
+ ex = new JsParseException("abc", cause, 99);
+ assertTrue(cause == ex.getCause());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsStringTest.java b/src/test/java/jp/sourceforge/jovsonz/JsStringTest.java
new file mode 100644
index 0000000..7e86b77
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsStringTest.java
@@ -0,0 +1,508 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsStringTest {
+
+ public JsStringTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of Constructor, of class JsString.
+ */
+ @Test
+ public void testConstructor() throws Exception{
+ System.out.println("constructor");
+
+ JsString string;
+
+ string = new JsString();
+ assertEquals("", string.toRawString());
+
+ string = new JsString("");
+ assertEquals("", string.toRawString());
+
+ string = new JsString("x");
+ assertEquals("x", string.toRawString());
+
+ string = new JsString("\u001f");
+ assertEquals("\u001f", string.toRawString());
+ assertEquals("\"\\u001f\"", string.toString());
+
+ try{
+ string = new JsString(null);
+ fail();
+ }catch(NullPointerException e){
+ //NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of parseHexChar method, of class JsString.
+ */
+ @Test
+ public void testParseHexChar() throws Exception{
+ System.out.println("parseHexChar");
+
+ JsonSource source;
+ char ch;
+
+ source = new JsonSource("0000");
+ ch = JsString.parseHexChar(source);
+ assertEquals('\u0000', ch);
+
+ source = new JsonSource("ffff");
+ ch = JsString.parseHexChar(source);
+ assertEquals('\uffff', ch);
+
+ source = new JsonSource("FFFF");
+ ch = JsString.parseHexChar(source);
+ assertEquals('\uffff', ch);
+
+ source = new JsonSource("dead");
+ ch = JsString.parseHexChar(source);
+ assertEquals('\udead', ch);
+
+ source = new JsonSource("abcde");
+ ch = JsString.parseHexChar(source);
+ assertEquals('\uabcd', ch);
+
+ try{
+ source = new JsonSource("000,");
+ ch = JsString.parseHexChar(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of parseString method, of class JsString.
+ */
+ @Test
+ public void testParseString() throws Exception{
+ System.out.println("parseString");
+
+ JsonSource source;
+ JsString string;
+
+ source = new JsonSource("\"abc\"");
+ string = JsString.parseString(source);
+ assertEquals("abc", string.toRawString());
+
+ source = new JsonSource("\"ããã\"");
+ string = JsString.parseString(source);
+ assertEquals("ããã", string.toRawString());
+
+ source = new JsonSource("\"\\\"\\\\\\/\"");
+ string = JsString.parseString(source);
+ assertEquals("\"\\/", string.toRawString());
+
+ source = new JsonSource("\"\\b\\f\\n\\r\\t\"");
+ string = JsString.parseString(source);
+ assertEquals("\b\f\n\r\t", string.toRawString());
+
+ source = new JsonSource("\"\\uabcd\\uCDEF\"");
+ string = JsString.parseString(source);
+ assertEquals("\uabcd\ucdef", string.toRawString());
+
+ source = new JsonSource("abc\"");
+ string = JsString.parseString(source);
+ assertNull(string);
+
+ try{
+ source = new JsonSource("\"abc");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("\"\\#\"");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("\"\\u#999\"");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("\"\\u9#99\"");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("\"\\u99#9\"");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("\"\\u999#\"");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ try{
+ source = new JsonSource("\"abc\nxyz\"");
+ string = JsString.parseString(source);
+ fail();
+ }catch(JsParseException e){
+ // NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of dumpString method, of class JsString.
+ */
+ @Test
+ public void testDumpString() throws Exception{
+ System.out.println("writeText");
+
+ Appendable appout;
+ JsString string;
+
+ appout = new StringBuilder();
+ string = new JsString();
+ JsString.dumpString(appout, string);
+ assertEquals("\"\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("abc");
+ JsString.dumpString(appout, string);
+ assertEquals("\"abc\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\"");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\\"\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\\");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\\\\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("/");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\/\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\b");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\b\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\f");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\f\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\n");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\n\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\r");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\r\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\t");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\t\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("\u0001");
+ JsString.dumpString(appout, string);
+ assertEquals("\"\\u0001\"", appout.toString());
+
+ appout = new StringBuilder();
+ string = new JsString("ã");
+ JsString.dumpString(appout, string);
+ assertEquals("\"ã\"", appout.toString());
+
+ return;
+ }
+
+ /**
+ * Test of escapeText method, of class JsString.
+ */
+ @Test
+ public void testEscapeText(){
+ System.out.println("escapeText");
+
+ assertEquals("\"A\"", JsString.escapeText("A").toString());
+
+ return;
+ }
+
+ /**
+ * Test of traverse method, of class JsString.
+ */
+ @Test
+ public void testTraverse(){
+ System.out.println("traverse");
+
+ JsString string = new JsString("A");
+
+ try{
+ string.traverse(new ValueVisitor(){
+ int ct = 0;
+
+ public void visitValue(JsValue value)
+ throws JsVisitException{
+ assertEquals(new JsString("A"), value);
+ assertTrue(this.ct++ <= 0);
+ }
+
+ public void visitPairName(String name)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+
+ public void visitCompositionClose(JsComposition composite)
+ throws JsVisitException{
+ throw new JsVisitException();
+ }
+ });
+ }catch(JsVisitException e){
+ fail();
+ }
+
+ return;
+ }
+
+ /**
+ * Test of charAt method, of class JsString.
+ */
+ @Test
+ public void testCharAt(){
+ System.out.println("charAt");
+
+ JsString string;
+
+ string = new JsString("abcde");
+ assertEquals('b', string.charAt(1));
+
+ try{
+ string.charAt(999);
+ fail();
+ }catch(IndexOutOfBoundsException e){
+ // NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of length method, of class JsString.
+ */
+ @Test
+ public void testLength(){
+ System.out.println("length");
+
+ assertEquals(0, new JsString().length());
+ assertEquals(0, new JsString("").length());
+ assertEquals(1, new JsString("A").length());
+ assertEquals(2, new JsString("AB").length());
+ assertEquals(3, new JsString("A\"B").length());
+
+ return;
+ }
+
+ /**
+ * Test of subSequence method, of class JsString.
+ */
+ @Test
+ public void testSubSequence(){
+ System.out.println("subSequence");
+
+ JsString string;
+
+ string = new JsString("abcde");
+ assertEquals("bcd", string.subSequence(1, 4).toString());
+ assertEquals("", string.subSequence(1, 1).toString());
+
+ try{
+ string.subSequence(1,999);
+ fail();
+ }catch(IndexOutOfBoundsException e){
+ // NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of hashCode method, of class JsString.
+ */
+ @Test
+ public void testHashCode(){
+ System.out.println("hashCode");
+ assertEquals(new JsString("A").hashCode(), new JsString("A").hashCode());
+ return;
+ }
+
+ /**
+ * Test of equals method, of class JsString.
+ */
+ @Test
+ public void testEquals(){
+ System.out.println("equals");
+
+ assertTrue(new JsString("A").equals(new JsString("A")));
+ assertFalse(new JsString("A").equals(new JsString("a")));
+ JsString nullVal = null;
+ assertFalse(new JsString("A").equals(nullVal));
+
+ assertFalse(new JsString("A").equals(""));
+
+ return;
+ }
+
+ /**
+ * Test of compareTo method, of class JsString.
+ */
+ @Test
+ public void testCompareTo(){
+ System.out.println("compareTo");
+
+ assertTrue(0 == new JsString("A").compareTo(new JsString("A")));
+ assertTrue(0 > new JsString("A").compareTo(new JsString("a")));
+ assertTrue(0 < new JsString("a").compareTo(new JsString("A")));
+ assertTrue(0 < new JsString("A").compareTo(null));
+
+ SortedSet set = new TreeSet();
+
+ set.clear();
+ set.add(new JsString("A"));
+ set.add(new JsString("a"));
+ assertEquals(new JsString("A"), set.first());
+ assertEquals(new JsString("a"), set.last());
+
+ set.clear();
+ set.add(new JsString("a"));
+ set.add(new JsString("A"));
+ assertEquals(new JsString("A"), set.first());
+ assertEquals(new JsString("a"), set.last());
+
+ JsString string = new JsString("A");
+ assertEquals(0, string.compareTo(string));
+
+ return;
+ }
+
+ /**
+ * Test of toString method, of class JsString.
+ */
+ @Test
+ public void testToString(){
+ System.out.println("toString");
+
+ assertEquals("\"\"", new JsString("").toString());
+ assertEquals("\"abc\"", new JsString("abc").toString());
+ assertEquals("\"\\\"\"", new JsString("\"").toString());
+ assertEquals("\"\\\\\"", new JsString("\\").toString());
+ assertEquals("\"\\/\"", new JsString("/").toString());
+ assertEquals("\"\\b\"", new JsString("\b").toString());
+ assertEquals("\"\\f\"", new JsString("\f").toString());
+ assertEquals("\"\\n\"", new JsString("\n").toString());
+ assertEquals("\"\\r\"", new JsString("\r").toString());
+ assertEquals("\"\\t\"", new JsString("\t").toString());
+ assertEquals("\"\\u0001\"", new JsString("\u0001").toString());
+ assertEquals("\"ã\"", new JsString("ã").toString());
+
+ return;
+ }
+
+ /**
+ * Test of toRawString method, of class JsString.
+ */
+ @Test
+ public void testToRawString(){
+ System.out.println("toRawString");
+
+ assertEquals("", new JsString("").toRawString());
+ assertEquals("abc", new JsString("abc").toRawString());
+ assertEquals("\"", new JsString("\"").toRawString());
+ assertEquals("\\", new JsString("\\").toRawString());
+ assertEquals("/", new JsString("/").toRawString());
+ assertEquals("\b", new JsString("\b").toRawString());
+ assertEquals("\f", new JsString("\f").toRawString());
+ assertEquals("\n", new JsString("\n").toRawString());
+ assertEquals("\r", new JsString("\r").toRawString());
+ assertEquals("\t", new JsString("\t").toRawString());
+ assertEquals("\u0001", new JsString("\u0001").toRawString());
+ assertEquals("ã", new JsString("ã").toRawString());
+
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsString.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ JsString instance = new JsString();
+
+ assertEquals(JsTypes.STRING, instance.getJsTypes());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsTypesTest.java b/src/test/java/jp/sourceforge/jovsonz/JsTypesTest.java
new file mode 100644
index 0000000..590a0fa
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsTypesTest.java
@@ -0,0 +1,134 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsTypesTest {
+
+ public JsTypesTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of values method, of class JsTypes.
+ */
+ @Test
+ public void testValues() {
+ System.out.println("values");
+ JsTypes[] result = JsTypes.values();
+ assertEquals(6, result.length);
+ assertEquals(JsTypes.NUMBER, result[0]);
+ assertEquals(JsTypes.STRING, result[1]);
+ assertEquals(JsTypes.BOOLEAN, result[2]);
+ assertEquals(JsTypes.ARRAY, result[3]);
+ assertEquals(JsTypes.OBJECT, result[4]);
+ assertEquals(JsTypes.NULL, result[5]);
+ return;
+ }
+
+ /**
+ * Test of valueOf method, of class JsTypes.
+ */
+ @Test
+ public void testValueOf() {
+ System.out.println("valueOf");
+
+ assertEquals(JsTypes.NUMBER, JsTypes.valueOf("NUMBER"));
+ assertEquals(JsTypes.STRING, JsTypes.valueOf("STRING"));
+ assertEquals(JsTypes.BOOLEAN, JsTypes.valueOf("BOOLEAN"));
+ assertEquals(JsTypes.ARRAY, JsTypes.valueOf("ARRAY"));
+ assertEquals(JsTypes.OBJECT, JsTypes.valueOf("OBJECT"));
+ assertEquals(JsTypes.NULL, JsTypes.valueOf("NULL"));
+
+ return;
+ }
+
+ /**
+ * Test of getJsTypes method, of class JsTypes.
+ */
+ @Test
+ public void testGetJsTypes() {
+ System.out.println("getJsTypes");
+
+ assertEquals(JsTypes.NUMBER, JsTypes.getJsTypes(JsNumber.class));
+ assertEquals(JsTypes.STRING, JsTypes.getJsTypes(JsString.class));
+ assertEquals(JsTypes.BOOLEAN, JsTypes.getJsTypes(JsBoolean.class));
+ assertEquals(JsTypes.ARRAY, JsTypes.getJsTypes(JsArray.class));
+ assertEquals(JsTypes.OBJECT, JsTypes.getJsTypes(JsObject.class));
+ assertEquals(JsTypes.NULL, JsTypes.getJsTypes(JsNull.class));
+
+ assertNull(JsTypes.getJsTypes(Object.class));
+
+ try{
+ JsTypes.getJsTypes(null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of getJsClass method, of class JsTypes.
+ */
+ @Test
+ public void testGetJsClass() {
+ System.out.println("getJsClass");
+
+ assertEquals(JsNumber.class, JsTypes.NUMBER.getJsClass());
+ assertEquals(JsString.class, JsTypes.STRING.getJsClass());
+ assertEquals(JsBoolean.class, JsTypes.BOOLEAN.getJsClass());
+ assertEquals(JsArray.class, JsTypes.ARRAY.getJsClass());
+ assertEquals(JsObject.class, JsTypes.OBJECT.getJsClass());
+ assertEquals(JsNull.class, JsTypes.NULL.getJsClass());
+
+ return;
+ }
+
+ /**
+ * Test of isComposition method, of class JsTypes.
+ */
+ @Test
+ public void testIsComposition(){
+ System.out.println("isComposition");
+
+ assertTrue(JsTypes.OBJECT.isComposition());
+ assertTrue(JsTypes.ARRAY.isComposition());
+
+ assertFalse(JsTypes.NUMBER.isComposition());
+ assertFalse(JsTypes.STRING.isComposition());
+ assertFalse(JsTypes.BOOLEAN.isComposition());
+ assertFalse(JsTypes.NULL.isComposition());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsVisitExceptionTest.java b/src/test/java/jp/sourceforge/jovsonz/JsVisitExceptionTest.java
new file mode 100644
index 0000000..6e89b1c
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsVisitExceptionTest.java
@@ -0,0 +1,85 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsVisitExceptionTest {
+
+ public JsVisitExceptionTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testConstructor(){
+ System.out.println("constructor");
+
+ JsVisitException ex;
+
+ ex = new JsVisitException();
+ assertNull(ex.getMessage());
+ assertNull(ex.getCause());
+
+ ex = new JsVisitException((String)null);
+ assertNull(ex.getMessage());
+
+ ex = new JsVisitException("");
+ assertEquals("", ex.getMessage());
+
+ ex = new JsVisitException("abc");
+ assertEquals("abc", ex.getMessage());
+
+ Throwable cause = new Throwable("cause");
+
+ ex = new JsVisitException((Throwable)null);
+ assertNull(ex.getMessage());
+
+ ex = new JsVisitException(cause);
+ assertEquals(cause, ex.getCause());
+
+ ex = new JsVisitException(null, null);
+ assertNull(ex.getMessage());
+ assertNull(ex.getCause());
+
+ ex = new JsVisitException("abc", null);
+ assertEquals("abc", ex.getMessage());
+ assertNull(ex.getCause());
+
+ ex = new JsVisitException(null, cause);
+ assertNull(ex.getMessage());
+ assertEquals(cause, ex.getCause());
+
+ ex = new JsVisitException("abc", cause);
+ assertEquals("abc", ex.getMessage());
+ assertEquals(cause, ex.getCause());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsonAppenderTest.java b/src/test/java/jp/sourceforge/jovsonz/JsonAppenderTest.java
new file mode 100644
index 0000000..68543de
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsonAppenderTest.java
@@ -0,0 +1,264 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.EmptyStackException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsonAppenderTest {
+
+ public JsonAppenderTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of Constructor, of class JsonAppender.
+ */
+ @Test
+ public void testConstructor(){
+ System.out.println("constructor");
+
+ JsonAppender appender;
+
+ try{
+ appender = new JsonAppender(null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ appender = new JsonAppender(new StringBuilder());
+ assertFalse(appender.hasIOException());
+ assertNull(appender.getIOException());
+
+ return;
+ }
+
+ /**
+ * Test of pushComposition method, of class JsonAppender.
+ */
+ @Test
+ public void testPushPopComposition(){
+ System.out.println("pushComposition");
+
+ JsonAppender appender = new JsonAppender(new StringBuilder());
+
+ try{
+ appender.popComposition();
+ fail();
+ }catch(EmptyStackException e){
+ //GOOD
+ }
+ assertEquals(0, appender.nestDepth());
+ assertTrue(appender.isNestEmpty());
+
+ JsObject obj1 = new JsObject();
+ JsObject obj2 = new JsObject();
+ JsArray array1 = new JsArray();
+ JsArray array2 = new JsArray();
+
+ appender.pushComposition(obj1);
+ appender.pushComposition(array1);
+ appender.pushComposition(obj2);
+ appender.pushComposition(array2);
+
+ assertEquals(4, appender.nestDepth());
+ assertFalse(appender.isNestEmpty());
+
+ assertEquals(array2, appender.popComposition());
+ assertEquals(obj2, appender.popComposition());
+ assertEquals(array1, appender.popComposition());
+ assertEquals(obj1, appender.popComposition());
+
+ try{
+ appender.popComposition();
+ fail();
+ }catch(EmptyStackException e){
+ //GOOD
+ }
+ assertEquals(0, appender.nestDepth());
+ assertTrue(appender.isNestEmpty());
+
+ return;
+ }
+
+ /**
+ * Test of hasChildDumped setChildDumped method, of class JsonAppender.
+ */
+ @Test
+ public void testHasSetChildDumped(){
+ System.out.println("hasChildDumped");
+
+ JsonAppender appender;
+
+ appender = new JsonAppender(new StringBuilder());
+ assertFalse(appender.hasChildDumped());
+ appender.setChildDumped();
+ assertFalse(appender.hasChildDumped());
+
+ appender.pushComposition(new JsObject());
+ assertFalse(appender.hasChildDumped());
+ appender.setChildDumped();
+ assertTrue(appender.hasChildDumped());
+
+ appender.pushComposition(new JsObject());
+ assertFalse(appender.hasChildDumped());
+
+ appender.popComposition();
+ assertTrue(appender.hasChildDumped());
+
+ return;
+ }
+
+ /**
+ * Test of isArrayContext method, of class JsonAppender.
+ */
+ @Test
+ public void testIsArrayContext(){
+ System.out.println("isArrayContext");
+ return;
+ }
+
+ /**
+ * Test of getIOException method, of class JsonAppender.
+ */
+ @Test
+ public void testGetIOException() throws Exception{
+ System.out.println("getIOException");
+
+ Reader reader = new StringReader("[1,2,3,4,5]");
+ JsComposition root = Json.parseJson(reader);
+
+ Appendable app = new TroubleAppender(3);
+ JsonAppender appender = new JsonAppender(app);
+
+ assertFalse(appender.hasIOException());
+ assertNull(appender.getIOException());
+
+ try{
+ appender.append("abcde");
+ fail();
+ }catch(JsVisitException e){
+ assertTrue(appender.hasIOException());
+ assertEquals(e.getCause(), appender.getIOException());
+ }
+
+ return;
+ }
+
+ /**
+ * Test of putPairName method, of class JsonAppender.
+ */
+ @Test
+ public void testPutPairName() throws Exception{
+ System.out.println("putPairName");
+
+ Appendable app;
+ JsonAppender appender;
+
+ app = new TroubleAppender(1);
+ appender = new JsonAppender(app);
+
+ try{
+ appender.putPairName("A");
+ }catch(JsVisitException e){
+ assertTrue(appender.hasIOException());
+ assertEquals(e.getCause(), appender.getIOException());
+ }
+
+ return;
+ }
+
+ /**
+ * Test of append method, of class JsonAppender.
+ */
+ @Test
+ public void testAppend() throws Exception{
+ System.out.println("append");
+
+ Appendable app;
+ JsonAppender appender;
+
+ app = new TroubleAppender(3);
+ appender = new JsonAppender(app);
+ appender.append('0');
+ appender.append('1');
+ appender.append('2');
+ try{
+ appender.append('3');
+ }catch(JsVisitException e){
+ assertTrue(appender.hasIOException());
+ assertEquals(e.getCause(), appender.getIOException());
+ }
+
+ app = new TroubleAppender(3);
+ appender = new JsonAppender(app);
+ try{
+ appender.append("1234");
+ }catch(JsVisitException e){
+ assertTrue(appender.hasIOException());
+ assertEquals(e.getCause(), appender.getIOException());
+ }
+
+ return;
+ }
+
+ /**
+ * Test of flush method, of class JsonAppender.
+ */
+ @Test
+ public void testFlush() throws Exception{
+ System.out.println("flush");
+
+ Appendable app = new TroubleAppender(3);
+ JsonAppender appender = new JsonAppender(app);
+
+ try{
+ appender.flush();
+ fail();
+ }catch(JsVisitException e){
+ assertTrue(appender.hasIOException());
+ assertEquals(e.getCause(), appender.getIOException());
+ }
+
+ return;
+ }
+
+ /**
+ * Test of hasIOException method, of class JsonAppender.
+ */
+ @Test
+ public void testHasIOException(){
+ System.out.println("hasIOException");
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsonSourceTest.java b/src/test/java/jp/sourceforge/jovsonz/JsonSourceTest.java
new file mode 100644
index 0000000..79b34c4
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsonSourceTest.java
@@ -0,0 +1,616 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsonSourceTest {
+
+ public JsonSourceTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of constructor, of class JsonSource.
+ */
+ @Test
+ public void testConstructor() throws Exception{
+ System.out.println("constructor");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.read());
+ assertEquals('b', source.read());
+ assertEquals('c', source.read());
+ assertEquals(-1, source.read());
+
+ source = new JsonSource("abc");
+ assertEquals('a', source.read());
+ assertEquals('b', source.read());
+ assertEquals('c', source.read());
+ assertEquals(-1, source.read());
+
+ try{
+ source = new JsonSource((Reader)null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ try{
+ source = new JsonSource((String)null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of getLineNumber method, of class JsonSource.
+ */
+ @Test
+ public void testGetLineNumber() throws Exception{
+ System.out.println("getLineNumber");
+
+ JsonSource source;
+
+ source = new JsonSource("a\nbc\r\nd\n\n");
+ assertEquals(1, source.getLineNumber());
+ assertEquals('a', source.read());
+ assertEquals(1, source.getLineNumber());
+ assertEquals('\n', source.read());
+ assertEquals(2, source.getLineNumber());
+ assertEquals('b', source.read());
+ assertEquals(2, source.getLineNumber());
+ assertEquals('c', source.read());
+ assertEquals(2, source.getLineNumber());
+ assertEquals('\r', source.read());
+ assertEquals(2, source.getLineNumber());
+ assertEquals('\n', source.read());
+ assertEquals(3, source.getLineNumber());
+ assertEquals('d', source.read());
+ assertEquals(3, source.getLineNumber());
+ assertEquals('\n', source.read());
+ assertEquals(4, source.getLineNumber());
+ assertEquals('\n', source.read());
+ assertEquals(5, source.getLineNumber());
+ assertEquals(-1, source.read());
+ assertEquals(5, source.getLineNumber());
+
+ source = new JsonSource("\nX");
+ assertEquals(1, source.getLineNumber());
+ assertEquals('\n', source.read());
+ assertEquals(2, source.getLineNumber());
+ assertEquals('X', source.read());
+ assertEquals(2, source.getLineNumber());
+ assertEquals(-1, source.read());
+ assertEquals(2, source.getLineNumber());
+
+ source = new JsonSource("");
+ assertEquals(1, source.getLineNumber());
+ assertEquals(-1, source.read());
+
+ return;
+ }
+
+ /**
+ * Test of read method, of class JsonSource.
+ */
+ @Test
+ public void testRead() throws Exception{
+ System.out.println("read");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.read());
+ assertEquals('b', source.read());
+ assertEquals('c', source.read());
+ assertEquals(-1, source.read());
+
+ source = new JsonSource("abc");
+ assertEquals('a', source.read());
+ assertEquals('b', source.read());
+ assertEquals('c', source.read());
+ assertEquals(-1, source.read());
+
+ source = new JsonSource("X\u0000\u3000\uffffZ");
+ assertEquals('X', source.read());
+ assertEquals('\u0000', source.read());
+ assertEquals('\u3000', source.read());
+ assertEquals('\uffff', source.read());
+ assertEquals('Z', source.read());
+ assertEquals(-1, source.read());
+
+ // CJK UNIFIED IDEOGRAPH-2000B ð
+ source = new JsonSource("X\ud840\udc0bZ");
+ assertEquals('X', source.read());
+ assertEquals('\ud840', source.read());
+ assertEquals('\udc0b', source.read());
+ assertEquals('Z', source.read());
+ assertEquals(-1, source.read());
+
+ source = new JsonSource("");
+ assertEquals(-1, source.read());
+
+ reader = new TroubleReader("abc", 1);
+ source = new JsonSource(reader);
+ assertEquals('a', source.read());
+ try{
+ source.read();
+ fail();
+ }catch(IOException e){
+ // GOOD!
+ }catch(Throwable e){
+ fail();
+ }
+
+ return;
+ }
+
+ /**
+ * Test of readOrDie method, of class JsonSource.
+ */
+ @Test
+ public void testReadOrDie() throws Exception{
+ System.out.println("readOrDie");
+
+ JsonSource source;
+
+ source = new JsonSource("ab\nc");
+ assertEquals('a', source.readOrDie());
+ assertEquals('b', source.readOrDie());
+ assertEquals('\n', source.readOrDie());
+ assertEquals('c', source.readOrDie());
+ try{
+ source.readOrDie();
+ fail();
+ }catch(JsParseException e){
+ assertEquals(2, e.getLineNumber());
+ assertEquals("We need but no more JSON data [line:2]",
+ e.getMessage());
+ }catch(Throwable e){
+ fail();
+ }
+
+ Reader reader = new TroubleReader("abc", 1);
+ source = new JsonSource(reader);
+ assertEquals('a', source.readOrDie());
+ try{
+ source.readOrDie();
+ fail();
+ }catch(IOException e){
+ // GOOD!
+ }catch(Throwable e){
+ fail();
+ }
+
+ return;
+ }
+
+ /**
+ * Test of matchOrDie method, of class JsonSource.
+ */
+ @Test
+ public void testMatchOrDie() throws Exception{
+ System.out.println("matchOrDie");
+
+ JsonSource source;
+
+ source = new JsonSource("ABC");
+ assertTrue(source.matchOrDie("ABC"));
+
+ source = new JsonSource("ABC");
+ assertFalse(source.matchOrDie("XYZ"));
+
+ source = new JsonSource("ABC");
+ assertTrue(source.matchOrDie("A"));
+
+ source = new JsonSource("ABC");
+ assertTrue(source.matchOrDie(""));
+
+ source = new JsonSource("ABC");
+ try{
+ source.matchOrDie("ABCD");
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of unread method, of class JsonSource.
+ */
+ @Test
+ public void testUnread() throws Exception{
+ System.out.println("unread");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.read());
+ assertEquals('b', source.read());
+ source.unread('X');
+ source.unread('Y');
+ assertEquals('Y', source.read());
+ assertEquals('X', source.read());
+ assertEquals('c', source.read());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("a\nb\nc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.read());
+ assertEquals('\n', source.read());
+ assertEquals('b', source.read());
+ assertEquals('\n', source.read());
+ assertEquals(3, source.getLineNumber());
+ source.unread('\n');
+ assertEquals(2, source.getLineNumber());
+ assertEquals('\n', source.read());
+ assertEquals(3, source.getLineNumber());
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.read());
+ assertEquals('b', source.read());
+ source.unread(-1);
+ assertEquals((char)-1, source.read());
+ assertEquals('c', source.read());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("X");
+ source = new JsonSource(reader);
+ source.unread('Y');
+ assertEquals('Y', source.read());
+ assertEquals('X', source.read());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("X");
+ source = new JsonSource(reader);
+ int spared = source.getPushBackSpared();
+ for(int ct = 1; ct <= spared; ct++){
+ source.unread('Y');
+ }
+ for(int ct = 1; ct <= spared; ct++){
+ assertEquals('Y', source.read());
+ }
+ assertEquals('X', source.read());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("X");
+ source = new JsonSource(reader);
+ while(source.getPushBackSpared() > 0){
+ source.unread('Y');
+ }
+ try{
+ source.unread('Y');
+ fail();
+ }catch(IOException e){
+ assertEquals("Pushback buffer overflow", e.getMessage());
+ }catch(Throwable e){
+ fail();
+ }
+
+ return;
+ }
+
+ /**
+ * Test of unread method, of class JsonSource.
+ */
+ @Test
+ public void testUnread_int() throws Exception{
+ System.out.println("unread");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.readOrDie());
+ assertEquals('b', source.readOrDie());
+ source.unread((int) 'X');
+ assertEquals('X', source.readOrDie());
+ assertEquals('c', source.readOrDie());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("");
+ source = new JsonSource(reader);
+ assertEquals(-1, source.read());
+ source.unread((int) 'X');
+ assertEquals('X', source.readOrDie());
+
+ reader = new StringReader("ab");
+ source = new JsonSource(reader);
+ assertEquals('a', source.readOrDie());
+ source.unread((int) 'X');
+ source.unread((int) 'Y');
+ assertEquals('Y', source.readOrDie());
+ assertEquals('X', source.readOrDie());
+ assertEquals('b', source.readOrDie());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("");
+ source = new JsonSource(reader);
+ source.unread((int) '\0');
+ assertEquals('\0', source.readOrDie());
+ source.unread(0xffff);
+ assertEquals('\uffff', source.readOrDie());
+ source.unread(0x1ffff);
+ assertEquals('\uffff', source.readOrDie());
+ source.unread(0x1ffff);
+ assertEquals(0xffff, source.read());
+ source.unread(0xffffffff);
+ assertEquals(0xffff, source.read());
+ source.unread(-1);
+ assertEquals(0xffff, source.read());
+
+ source.unread(-1);
+ assertEquals(0xffff, source.readOrDie());
+
+ return;
+ }
+
+ /**
+ * Test of unread method, of class JsonSource.
+ */
+ @Test
+ public void testUnread_char() throws Exception{
+ System.out.println("unread");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertEquals('a', source.readOrDie());
+ assertEquals('b', source.readOrDie());
+ source.unread('X');
+ assertEquals('X', source.readOrDie());
+ assertEquals('c', source.readOrDie());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("");
+ source = new JsonSource(reader);
+ assertEquals(-1, source.read());
+ source.unread('X');
+ assertEquals('X', source.readOrDie());
+
+ reader = new StringReader("ab");
+ source = new JsonSource(reader);
+ assertEquals('a', source.readOrDie());
+ source.unread('X');
+ source.unread('Y');
+ assertEquals('Y', source.readOrDie());
+ assertEquals('X', source.readOrDie());
+ assertEquals('b', source.readOrDie());
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("");
+ source = new JsonSource(reader);
+ source.unread('\0');
+ assertEquals('\0', source.readOrDie());
+ source.unread((char) 0xffff);
+ assertEquals('\uffff', source.readOrDie());
+
+ return;
+ }
+
+ /**
+ * Test of close method, of class JsonSource.
+ */
+ @Test
+ public void testClose() throws Exception{
+ System.out.println("close");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ source.close();
+
+ try{
+ source.read();
+ fail();
+ }catch(IOException e){
+ assertEquals("Stream closed", e.getMessage());
+ }
+
+ try{
+ source.unread('X');
+ fail();
+ }catch(IOException e){
+ assertEquals("Stream closed", e.getMessage());
+ }
+
+ return;
+ }
+
+ /**
+ * Test of getPushBackSpared method, of class JsonSource.
+ */
+ @Test
+ public void testGetPushBackSpared() throws Exception{
+ System.out.println("getPushBackSpared");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+
+ assertTrue(source.getPushBackSpared() > 0);
+
+ while(source.getPushBackSpared() > 0){
+ source.unread('X');
+ }
+
+ try{
+ source.unread('X');
+ fail();
+ }catch(IOException e){
+ //NOTHING
+ }
+
+ assertEquals(0, source.getPushBackSpared());
+ source.close();
+ assertTrue(source.getPushBackSpared() > 0);
+
+ return;
+ }
+
+ /**
+ * Test of isWhitespace method, of class JsonSource.
+ */
+ @Test
+ public void testIsWhitespace_char(){
+ System.out.println("isWhitespace");
+
+ assertTrue(JsonSource.isWhitespace('\t'));
+ assertTrue(JsonSource.isWhitespace('\r'));
+ assertTrue(JsonSource.isWhitespace('\n'));
+ assertTrue(JsonSource.isWhitespace('\u0020'));
+
+ assertFalse(JsonSource.isWhitespace('A'));
+ assertFalse(JsonSource.isWhitespace('\u3000'));
+ assertFalse(JsonSource.isWhitespace('\0'));
+ assertFalse(JsonSource.isWhitespace((char) -1));
+
+ return;
+ }
+
+ /**
+ * Test of isWhitespace method, of class JsonSource.
+ */
+ @Test
+ public void testIsWhitespace_int(){
+ System.out.println("isWhitespace");
+
+ assertTrue(JsonSource.isWhitespace((int) '\t'));
+ assertTrue(JsonSource.isWhitespace((int) '\r'));
+ assertTrue(JsonSource.isWhitespace((int) '\n'));
+ assertTrue(JsonSource.isWhitespace((int) '\u0020'));
+ assertTrue(JsonSource.isWhitespace(0x0020));
+
+ assertFalse(JsonSource.isWhitespace((int) 'A'));
+ assertFalse(JsonSource.isWhitespace((int) '\u3000'));
+ assertFalse(JsonSource.isWhitespace((int) '\0'));
+ assertFalse(JsonSource.isWhitespace(-1));
+
+ assertFalse(JsonSource.isWhitespace(0xffff));
+ assertFalse(JsonSource.isWhitespace(0x1ffff));
+ assertFalse(JsonSource.isWhitespace(0xffff0020));
+
+ return;
+ }
+
+ /**
+ * Test of skipWhiteSpace method, of class JsonSource.
+ */
+ @Test
+ public void testSkipWhiteSpace() throws Exception{
+ System.out.println("skipWhiteSpace");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ source.skipWhiteSpace();
+ assertEquals('a', source.read());
+
+ reader = new StringReader(" abc");
+ source = new JsonSource(reader);
+ source.skipWhiteSpace();
+ assertEquals('a', source.read());
+
+ reader = new StringReader("\t\r\n\u0020abc");
+ source = new JsonSource(reader);
+ source.skipWhiteSpace();
+ assertEquals('a', source.read());
+
+ reader = new StringReader(" ");
+ source = new JsonSource(reader);
+ source.skipWhiteSpace();
+ assertEquals(-1, source.read());
+
+ reader = new StringReader("");
+ source = new JsonSource(reader);
+ source.skipWhiteSpace();
+ assertEquals(-1, source.read());
+
+ return;
+ }
+
+ /**
+ * Test of hasMore method, of class JsonSource.
+ */
+ @Test
+ public void testHasMore() throws Exception{
+ System.out.println("hasMore");
+
+ JsonSource source;
+ Reader reader;
+
+ reader = new StringReader("abc");
+ source = new JsonSource(reader);
+ assertTrue(source.hasMore());
+ assertEquals('a', source.read());
+ assertTrue(source.hasMore());
+ assertEquals('b', source.read());
+ assertTrue(source.hasMore());
+ assertEquals('c', source.read());
+ assertFalse(source.hasMore());
+ source.unread('X');
+ assertTrue(source.hasMore());
+ assertEquals('X', source.read());
+ assertFalse(source.hasMore());
+
+ reader = new StringReader("");
+ source = new JsonSource(reader);
+ assertFalse(source.hasMore());
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/JsonTest.java b/src/test/java/jp/sourceforge/jovsonz/JsonTest.java
new file mode 100644
index 0000000..709e0f9
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/JsonTest.java
@@ -0,0 +1,386 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.io.StringReader;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class JsonTest {
+
+ public JsonTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of dumpJson method, of class Json.
+ */
+ @Test
+ public void testDumpJson() throws Exception{
+ System.out.println("dumpJson");
+
+ String SP2 = "\u0020\u0020";
+ String SP4 = SP2 + SP2;
+ String HASHSEP = "\u0020:\u0020";
+
+ Reader reader;
+ JsComposition root;
+ StringBuilder dump = new StringBuilder();
+
+ reader = new StringReader("{}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{ }\n", dump.toString());
+
+ reader = new StringReader("[]");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("[ ]\n", dump.toString());
+
+ reader = new StringReader("[1]");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("[\n"
+ + SP2+"1\n"
+ + "]\n", dump.toString());
+
+ reader = new StringReader("[1,2]");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("[\n"
+ + SP2+"1 ,\n"
+ + SP2+"2\n"
+ + "]\n", dump.toString());
+
+ reader = new StringReader("[1,[2],3]");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("[\n"
+ + SP2+"1 ,\n"
+ + SP2+"[\n"
+ + SP4+"2\n"
+ + SP2+"] ,\n"
+ + SP2+"3\n"
+ + "]\n", dump.toString());
+
+ reader = new StringReader("[1,{\"A\":\"a\"}]");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("[\n"
+ + SP2+"1 ,\n"
+ + SP2+"{\n"
+ + SP4+"\"A\""+HASHSEP+"\"a\"\n"
+ + SP2+"}\n"
+ + "]\n", dump.toString());
+
+ reader = new StringReader("{\"A\":\"a\"}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{\n"
+ + SP2+"\"A\""+HASHSEP+"\"a\"\n"
+ + "}\n", dump.toString());
+
+ reader = new StringReader("{\"A\":\"a\",\"B\":\"b\"}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{\n"
+ + SP2+"\"A\""+HASHSEP+"\"a\" ,\n"
+ + SP2+"\"B\""+HASHSEP+"\"b\"\n"
+ + "}\n", dump.toString());
+
+ reader = new StringReader("{\"A\":{}}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{\n"
+ + SP2+"\"A\""+HASHSEP+"{\u0020}\n"
+ + "}\n", dump.toString());
+
+ reader = new StringReader("{\"A\":{\"B\":\"b\"}}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{\n"
+ + SP2+"\"A\""+HASHSEP+"{\n"
+ + SP4+"\"B\""+HASHSEP+"\"b\"\n"
+ + SP2+"}\n"
+ + "}\n", dump.toString());
+
+ reader = new StringReader("{\"A\":[]}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{\n"
+ + SP2+"\"A\""+HASHSEP+"[\u0020]\n"
+ + "}\n", dump.toString());
+
+ reader = new StringReader("{\"A\":[1,2]}");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("{\n"
+ + SP2+"\"A\""+HASHSEP+"[\n"
+ + SP4+"1 ,\n"
+ + SP4+"2\n"
+ + SP2+"]\n"
+ + "}\n", dump.toString());
+
+ reader = new StringReader("["
+ + "true,false,null,\"string\",-0.5"
+ + "]");
+ root = Json.parseJson(reader);
+ dump.setLength(0);
+ Json.dumpJson(dump, root);
+ assertEquals("[\n"
+ + SP2+"true ,\n"
+ + SP2+"false ,\n"
+ + SP2+"null ,\n"
+ + SP2+"\"string\" ,\n"
+ + SP2+"-0.5\n"
+ + "]\n", dump.toString());
+
+ try{
+ Json.dumpJson(null, new JsObject());
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ try{
+ Json.dumpJson(new StringBuilder(), null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ reader = new StringReader("[1,2,3]");
+ root = Json.parseJson(reader);
+ TroubleAppender app = new TroubleAppender(3);
+ try{
+ Json.dumpJson(app, root);
+ fail();
+ }catch(IOException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of parseValue method, of class Json.
+ */
+ @Test
+ public void testParseValue() throws Exception{
+ System.out.println("parseValue");
+
+ JsonSource source;
+ JsValue value;
+
+ source = new JsonSource("true");
+ value = Json.parseValue(source);
+ assertEquals(JsBoolean.TRUE, value);
+
+ source = new JsonSource("false");
+ value = Json.parseValue(source);
+ assertEquals(JsBoolean.FALSE, value);
+
+ source = new JsonSource("null");
+ value = Json.parseValue(source);
+ assertEquals(JsNull.NULL, value);
+
+ source = new JsonSource("-0.5");
+ value = Json.parseValue(source);
+ assertEquals(JsTypes.NUMBER, value.getJsTypes());
+ assertEquals(-0.5, ((JsNumber)value).doubleValue(), 0.0);
+
+ source = new JsonSource("\"ABC\"");
+ value = Json.parseValue(source);
+ assertEquals(JsTypes.STRING, value.getJsTypes());
+ assertEquals("ABC", ((JsString)value).toRawString());
+
+ source = new JsonSource("[1,2,3]");
+ value = Json.parseValue(source);
+ assertEquals(JsTypes.ARRAY, value.getJsTypes());
+ assertEquals(3, ((JsArray)value).size());
+
+ source = new JsonSource("{\"A\":1,\"B\":2,\"C\":3}");
+ value = Json.parseValue(source);
+ assertEquals(JsTypes.OBJECT, value.getJsTypes());
+ assertEquals(3, ((JsObject)value).size());
+
+ source = new JsonSource("");
+ value = Json.parseValue(source);
+ assertNull(value);
+
+ source = new JsonSource(" ");
+ value = Json.parseValue(source);
+ assertNull(value);
+
+ try{
+ source = new JsonSource("#");
+ value = Json.parseValue(source);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of parseJson method, of class Json.
+ */
+ @Test
+ public void testParseJson() throws Exception{
+ System.out.println("parseJson");
+
+ Reader reader;
+ JsComposition root;
+
+ reader = new StringReader("{}");
+ root = Json.parseJson(reader);
+ assertNotNull(root);
+ assertEquals(JsTypes.OBJECT, root.getJsTypes());
+ assertEquals(0, root.size());
+
+ reader = new StringReader("{\"name\":\"value\"}");
+ root = Json.parseJson(reader);
+ assertNotNull(root);
+ assertEquals(JsTypes.OBJECT, root.getJsTypes());
+ assertEquals(1, root.size());
+
+ reader = new StringReader(" { \"name\" : \"value\" } ");
+ root = Json.parseJson(reader);
+ assertNotNull(root);
+ assertEquals(JsTypes.OBJECT, root.getJsTypes());
+ assertEquals(1, root.size());
+
+ reader = new StringReader("[]");
+ root = Json.parseJson(reader);
+ assertNotNull(root);
+ assertEquals(JsTypes.ARRAY, root.getJsTypes());
+ assertEquals(0, root.size());
+
+ reader = new StringReader("[1,2,3]");
+ root = Json.parseJson(reader);
+ assertNotNull(root);
+ assertEquals(JsTypes.ARRAY, root.getJsTypes());
+ assertEquals(3, root.size());
+
+ reader = new StringReader(" [ 1 , 2 , 3 ] ");
+ root = Json.parseJson(reader);
+ assertNotNull(root);
+ assertEquals(JsTypes.ARRAY, root.getJsTypes());
+ assertEquals(3, root.size());
+
+ reader = new StringReader("");
+ root = Json.parseJson(reader);
+ assertNull(root);
+
+ reader = new StringReader(" ");
+ root = Json.parseJson(reader);
+ assertNull(root);
+
+ try{
+ reader = new StringReader("true");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new StringReader("false");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new StringReader("null");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new StringReader("\"ABC\"");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new StringReader("-0.5");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new StringReader("#");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new StringReader(" [ 1 , 2 , 3 ");
+ root = Json.parseJson(reader);
+ fail();
+ }catch(JsParseException e){
+ //GOOD
+ }
+
+ try{
+ reader = new TroubleReader(" [ 1 , 2 , 3 ] ", 3);
+ root = Json.parseJson(reader);
+ fail();
+ }catch(IOException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/TroubleAppender.java b/src/test/java/jp/sourceforge/jovsonz/TroubleAppender.java
new file mode 100644
index 0000000..57fd5d4
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/TroubleAppender.java
@@ -0,0 +1,60 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.Flushable;
+import java.io.IOException;
+
+/**
+ *
+ */
+public class TroubleAppender implements Appendable, Flushable {
+
+ private final StringBuilder content = new StringBuilder();
+ private final long limit;
+
+ public TroubleAppender(long limit){
+ super();
+ this.limit = limit;
+ return;
+ }
+
+ private void checkLimit() throws IOException{
+ if(this.limit < this.content.length()) throw new IOException();
+ return;
+ }
+
+ public Appendable append(CharSequence csq)
+ throws IOException{
+ this.content.append(csq);
+ checkLimit();
+ return this;
+ }
+
+ public Appendable append(CharSequence csq, int start, int end)
+ throws IOException{
+ this.content.append(csq, start, end);
+ checkLimit();
+ return this;
+ }
+
+ public Appendable append(char c)
+ throws IOException{
+ this.content.append(c);
+ checkLimit();
+ return this;
+ }
+
+ public void flush() throws IOException{
+ throw new IOException();
+ }
+
+ @Override
+ public String toString(){
+ return this.content.toString();
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/TroubleReader.java b/src/test/java/jp/sourceforge/jovsonz/TroubleReader.java
new file mode 100644
index 0000000..1b475ba
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/TroubleReader.java
@@ -0,0 +1,54 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.CharBuffer;
+
+/**
+ * limitæåã¾ã§æ£å¸¸ã«èªã¿è¾¼ãã
+ * 以éã®èªã¿åºãã§èªåçã«IOExceptionãæããStringReaderã
+ */
+public class TroubleReader extends StringReader{
+
+ private final int limit;
+ private int ct = 0;
+
+ public TroubleReader(String text, int limit){
+ super(text);
+ this.limit = limit;
+ return;
+ }
+
+ @Override
+ public int read() throws IOException{
+ if(this.ct >= this.limit) throw new IOException();
+ this.ct++;
+ return super.read();
+ }
+
+ @Override
+ public int read(char[] cbuf){
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int read(char[] cbuf, int off, int len){
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int read(CharBuffer target){
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long skip(long ns){
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/test/java/jp/sourceforge/jovsonz/UnmodIteratorTest.java b/src/test/java/jp/sourceforge/jovsonz/UnmodIteratorTest.java
new file mode 100644
index 0000000..80f7044
--- /dev/null
+++ b/src/test/java/jp/sourceforge/jovsonz/UnmodIteratorTest.java
@@ -0,0 +1,217 @@
+/*
+ * License : The MIT License
+ * Copyright(c) 2009 olyutorskii
+ */
+
+package jp.sourceforge.jovsonz;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class UnmodIteratorTest {
+
+ public UnmodIteratorTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception{
+ }
+
+ @AfterClass
+ public static void tearDownClass() throws Exception{
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ private void assert3ListAndIterator(List list, Iterator unmod){
+ assertEquals(3, list.size());
+
+ assertTrue(unmod.hasNext());
+ assertEquals(list.get(0), unmod.next());
+
+ assertTrue(unmod.hasNext());
+ assertEquals(list.get(1), unmod.next());
+
+ try{
+ unmod.remove();
+ fail();
+ }catch(UnsupportedOperationException e){
+ //NOTHING
+ }
+
+ assertTrue(unmod.hasNext());
+ assertEquals(list.get(2), unmod.next());
+
+ assertFalse(unmod.hasNext());
+
+ try{
+ unmod.next();
+ fail();
+ }catch(NoSuchElementException e){
+ //NOTHING
+ }
+
+ return;
+ }
+
+ /**
+ * Test of Constructor, of class UnmodIterator.
+ */
+ @Test
+ public void testConstructor(){
+ System.out.println("constructor");
+
+ List list;
+ Iterator it;
+
+ list = new LinkedList();
+ list.add("A");
+ list.add("B");
+ list.add("C");
+
+ it = list.iterator();
+ UnmodIterator unmod = new UnmodIterator(it);
+
+ assert3ListAndIterator(list, unmod);
+
+ try{
+ unmod = new UnmodIterator(null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of wrapUnmod method, of class UnmodIterator.
+ */
+ @Test
+ public void testWrapUnmod_Iterator(){
+ System.out.println("wrapUnmod");
+
+ List list;
+ Iterator it;
+
+ list = new LinkedList();
+ list.add("A");
+ list.add("B");
+ list.add("C");
+
+ it = list.iterator();
+ Iterator unmod = UnmodIterator.wrapUnmod(it);
+
+ assert3ListAndIterator(list, unmod);
+
+ try{
+ unmod = UnmodIterator.wrapUnmod((Iterator)null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of wrapUnmod method, of class UnmodIterator.
+ */
+ @Test
+ public void testWrapUnmod_Iterable(){
+ System.out.println("wrapUnmod");
+
+ List list;
+
+ list = new LinkedList();
+ list.add("A");
+ list.add("B");
+ list.add("C");
+
+ Iterable unmod = UnmodIterator.wrapUnmod(list);
+
+ assert3ListAndIterator(list, unmod.iterator());
+
+ try{
+ unmod = UnmodIterator.wrapUnmod((Iterable)null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of unmodIterator method, of class UnmodIterator.
+ */
+ @Test
+ public void testUnmodIterator(){
+ System.out.println("unmodIterator");
+
+ List list;
+
+ list = new LinkedList();
+ list.add("A");
+ list.add("B");
+ list.add("C");
+
+ Iterator unmod = UnmodIterator.unmodIterator(list);
+
+ assert3ListAndIterator(list, unmod);
+
+ try{
+ unmod = UnmodIterator.unmodIterator(null);
+ fail();
+ }catch(NullPointerException e){
+ //GOOD
+ }
+
+ return;
+ }
+
+ /**
+ * Test of hasNext method, of class UnmodIterator.
+ */
+ @Test
+ public void testHasNext(){
+ System.out.println("hasNext");
+ return;
+ }
+
+ /**
+ * Test of next method, of class UnmodIterator.
+ */
+ @Test
+ public void testNext(){
+ System.out.println("next");
+ return;
+ }
+
+ /**
+ * Test of remove method, of class UnmodIterator.
+ */
+ @Test
+ public void testRemove(){
+ System.out.println("remove");
+ return;
+ }
+
+}
--
2.11.0