import java.util.*;
class Ideone {
Json v = Json.dict()
.put("name", "John Lennon")
.put("email", "foobar@gmail.com")
.put("phone", "+81-90-0000-0000")
.put("occupation", Json.array("Programmer", "System Engineer"))
.put("language", Json.array("Japanese", "English", "Spanish", "Chinease"))
.put("hobby", Json.array("Photography", "Traveling", "Fishing", "Onsen"))
;
System.
out.
println("--property-------------------"); System.
out.
println( "v[language][2] = " + v.
get("language").
get(2) );
System.
out.
println("--for------------------------"); for(Map.
Entry<Json,Json
> et
: v.
eachDict()){ System.
out.
println(et.
getKey() + "=" + et.
getValue()); }
System.
out.
println("--toString-------------------"); }
}
class Json {
static JsonDict dict(){return new JsonDict();}
static JsonArray array
(Object...
args){return new JsonArray
(args
);} static Json toJson
(Object v
){ return v
instanceof Json
? (Json
)v
: new JsonValue
(v
); }
}
class JsonValue extends Json {
JsonValue
(Object v
){this.
v=v
;} @Override
Object raw
(){return v
;} @Override
public String toString
(){ if(v == null){return "null";}
return "\""+vs.replace("\\","\\\\").replace("\"","\\\"")+"\"";
}
@Override public int hashCode(){return v==null ? 0 : v.hashCode();}
@Override
public boolean equals
(Object o
){ if(o == null || o.getClass() != JsonValue.class){return false;}
Object v2
= ((JsonValue
)o
).
raw(); return v==null ? v==v2 : v.equals(v2);
}
}
class JsonDict extends Json {
private Map<Json,Json> m = new HashMap<Json,Json>();
m.put(toJson(k),toJson(v));
return this;
}
@Override
boolean containsKey
(Object k
){ return m.
containsKey(toJson
(k
)); } Json r = m.get(toJson(k));
return r;
}
@Override Iterable
<Map.
Entry<Json,Json
>> eachDict
(){return m.
entrySet();} @Override
public String toString
(){ StringBuilder sb = new StringBuilder();
sb.append("{");
int i=0;
for(Map.
Entry<Json,Json
> et
: m.
entrySet()){ sb.append(i++ != 0 ? ", " : "").append(et.getKey()+":"+et.getValue());
}
sb.append("}");
return sb.toString();
}
}
class JsonArray extends Json {
private List<Json> l = new ArrayList<Json>();
for(Object et
: v
){ l.
add(toJson
(et
)); } }
@Override Json get(int index){ return l.get(index); }
@Override Iterable<Json> each(){return l;}
@Override
public String toString
(){return l.
toString();}}
aW1wb3J0IGphdmEudXRpbC4qOwoKY2xhc3MgSWRlb25lIHsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlKc29uIHYgPSBKc29uLmRpY3QoKQoJCQkucHV0KCJuYW1lIiwgIkpvaG4gTGVubm9uIikKCQkJLnB1dCgiZW1haWwiLCAiZm9vYmFyQGdtYWlsLmNvbSIpCgkJCS5wdXQoInBob25lIiwgIis4MS05MC0wMDAwLTAwMDAiKQoJCQkucHV0KCJvY2N1cGF0aW9uIiwgSnNvbi5hcnJheSgiUHJvZ3JhbW1lciIsICJTeXN0ZW0gRW5naW5lZXIiKSkKCQkJLnB1dCgibGFuZ3VhZ2UiLCBKc29uLmFycmF5KCJKYXBhbmVzZSIsICJFbmdsaXNoIiwgIlNwYW5pc2giLCAiQ2hpbmVhc2UiKSkKCQkJLnB1dCgiaG9iYnkiLCBKc29uLmFycmF5KCJQaG90b2dyYXBoeSIsICJUcmF2ZWxpbmciLCAiRmlzaGluZyIsICJPbnNlbiIpKQoJCTsKCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oIi0tcHJvcGVydHktLS0tLS0tLS0tLS0tLS0tLS0tIik7CgkJU3lzdGVtLm91dC5wcmludGxuKCAidltsYW5ndWFnZV1bMl0gPSAiICsgdi5nZXQoImxhbmd1YWdlIikuZ2V0KDIpICk7CgkJCgkJU3lzdGVtLm91dC5wcmludGxuKCItLWZvci0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwoJCWZvcihNYXAuRW50cnk8SnNvbixKc29uPiBldCA6IHYuZWFjaERpY3QoKSl7CgkJCVN5c3RlbS5vdXQucHJpbnRsbihldC5nZXRLZXkoKSArICI9IiArIGV0LmdldFZhbHVlKCkpOwoJCX0KCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oIi0tdG9TdHJpbmctLS0tLS0tLS0tLS0tLS0tLS0tIik7CgkJU3lzdGVtLm91dC5wcmludGxuKHYpOwoJfQp9CgoKCgpjbGFzcyBKc29uIHsKCXN0YXRpYyBKc29uRGljdCAgZGljdCgpe3JldHVybiBuZXcgSnNvbkRpY3QoKTt9CglzdGF0aWMgSnNvbkFycmF5IGFycmF5KE9iamVjdC4uLiBhcmdzKXtyZXR1cm4gbmV3IEpzb25BcnJheShhcmdzKTt9CglzdGF0aWMgSnNvbiB0b0pzb24oT2JqZWN0IHYpeyByZXR1cm4gdiBpbnN0YW5jZW9mIEpzb24gPyAoSnNvbil2IDogbmV3IEpzb25WYWx1ZSh2KTsgfQoJCglJdGVyYWJsZTxNYXAuRW50cnk8SnNvbixKc29uPj4gZWFjaERpY3QoKXt0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTt9CglJdGVyYWJsZTxKc29uPiBlYWNoKCl7dGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7fQoJSnNvbiBrZXkoKXt0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTt9CglKc29uIHZhbCgpe3Rocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpO30KCWJvb2xlYW4gY29udGFpbnNLZXkoT2JqZWN0IGspe3Rocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpO30KCUpzb24gZ2V0KE9iamVjdCBrKXt0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTt9CglKc29uIGdldChpbnQgaW5kZXgpe3Rocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpO30KCU9iamVjdCByYXcoKXt0aHJvdyBuZXcgVW5zdXBwb3J0ZWRPcGVyYXRpb25FeGNlcHRpb24oKTt9Cn0KY2xhc3MgSnNvblZhbHVlIGV4dGVuZHMgSnNvbiB7Cglwcml2YXRlIE9iamVjdCB2OwoJSnNvblZhbHVlKE9iamVjdCB2KXt0aGlzLnY9djt9CglAT3ZlcnJpZGUgT2JqZWN0IHJhdygpe3JldHVybiB2O30KCUBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCl7CgkJaWYodiA9PSBudWxsKXtyZXR1cm4gIm51bGwiO30KCQlpZih2IGluc3RhbmNlb2YgTnVtYmVyKXtyZXR1cm4gU3RyaW5nLnZhbHVlT2Yodik7fQoJCVN0cmluZyB2cyA9IFN0cmluZy52YWx1ZU9mKHYpOwoJCXJldHVybiAiXCIiK3ZzLnJlcGxhY2UoIlxcIiwiXFxcXCIpLnJlcGxhY2UoIlwiIiwiXFxcIiIpKyJcIiI7Cgl9CglAT3ZlcnJpZGUgcHVibGljIGludCBoYXNoQ29kZSgpe3JldHVybiB2PT1udWxsID8gMCA6IHYuaGFzaENvZGUoKTt9CglAT3ZlcnJpZGUgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKXsKCQlpZihvID09IG51bGwgfHwgby5nZXRDbGFzcygpICE9IEpzb25WYWx1ZS5jbGFzcyl7cmV0dXJuIGZhbHNlO30KCQlPYmplY3QgdjIgPSAoKEpzb25WYWx1ZSlvKS5yYXcoKTsKCQlyZXR1cm4gdj09bnVsbCA/IHY9PXYyIDogdi5lcXVhbHModjIpOwoJfQp9CmNsYXNzIEpzb25EaWN0IGV4dGVuZHMgSnNvbiB7Cglwcml2YXRlIE1hcDxKc29uLEpzb24+IG0gPSBuZXcgSGFzaE1hcDxKc29uLEpzb24+KCk7CglKc29uRGljdCBwdXQoT2JqZWN0IGssIE9iamVjdCB2KXsKCQltLnB1dCh0b0pzb24oayksdG9Kc29uKHYpKTsKCQlyZXR1cm4gdGhpczsKCX0KCUBPdmVycmlkZSBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrKXsgcmV0dXJuIG0uY29udGFpbnNLZXkodG9Kc29uKGspKTsgfQoJQE92ZXJyaWRlIEpzb24gZ2V0KE9iamVjdCBrKXsKCQlKc29uIHIgPSBtLmdldCh0b0pzb24oaykpOwoJCWlmKHIgPT0gbnVsbCl7dGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigidW5kZWZpbmVkIFsiK2srIl0iKTt9CgkJcmV0dXJuIHI7Cgl9CglAT3ZlcnJpZGUgSXRlcmFibGU8TWFwLkVudHJ5PEpzb24sSnNvbj4+IGVhY2hEaWN0KCl7cmV0dXJuIG0uZW50cnlTZXQoKTt9CglAT3ZlcnJpZGUgcHVibGljIFN0cmluZyB0b1N0cmluZygpewoJCVN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwoJCXNiLmFwcGVuZCgieyIpOwoJCWludCBpPTA7CgkJZm9yKE1hcC5FbnRyeTxKc29uLEpzb24+IGV0IDogbS5lbnRyeVNldCgpKXsKCQkJc2IuYXBwZW5kKGkrKyAhPSAwID8gIiwgIiA6ICIiKS5hcHBlbmQoZXQuZ2V0S2V5KCkrIjoiK2V0LmdldFZhbHVlKCkpOwoJCX0KCQlzYi5hcHBlbmQoIn0iKTsKCQlyZXR1cm4gc2IudG9TdHJpbmcoKTsKCX0KfQpjbGFzcyBKc29uQXJyYXkgZXh0ZW5kcyBKc29uIHsKCXByaXZhdGUgTGlzdDxKc29uPiBsID0gbmV3IEFycmF5TGlzdDxKc29uPigpOwoJSnNvbkFycmF5KE9iamVjdFtdIHYpewoJCWZvcihPYmplY3QgZXQgOiB2KXsgbC5hZGQodG9Kc29uKGV0KSk7IH0KCX0KCUBPdmVycmlkZSBKc29uIGdldChpbnQgaW5kZXgpeyByZXR1cm4gbC5nZXQoaW5kZXgpOyB9CglAT3ZlcnJpZGUgSXRlcmFibGU8SnNvbj4gZWFjaCgpe3JldHVybiBsO30KCUBPdmVycmlkZSBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCl7cmV0dXJuIGwudG9TdHJpbmcoKTt9Cn0K
--property-------------------
v[language][2] = "Spanish"
--for------------------------
"occupation"=["Programmer", "System Engineer"]
"phone"="+81-90-0000-0000"
"name"="John Lennon"
"language"=["Japanese", "English", "Spanish", "Chinease"]
"email"="foobar@gmail.com"
"hobby"=["Photography", "Traveling", "Fishing", "Onsen"]
--toString-------------------
{"occupation":["Programmer", "System Engineer"], "phone":"+81-90-0000-0000", "name":"John Lennon", "language":["Japanese", "English", "Spanish", "Chinease"], "email":"foobar@gmail.com", "hobby":["Photography", "Traveling", "Fishing", "Onsen"]}