import java.util.Collection; | |
import java.util.HashMap; | |
import java.util.Map.Entry; | |
import java.util.Set; | |
/** | |
* <h2> | |
* JsonMaker.java <br/> | |
* </h2><br/><br/> | |
* | |
* @author beom (ice3x2@gmail.com) | |
* @Synce 2015. 11. 20. | |
* @Version 1 | |
*/ | |
public class JsonMaker { | |
public static ObjectMaker<ObjectMaker<?>> openObject(String key) { | |
ObjectMaker<JsonObjectAlreadyRoot> objectMaker = new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()); | |
return objectMaker.openObject(key); | |
} | |
public static <T> ObjectMaker<JsonObjectAlreadyRoot> put(String key,T value ) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).put(key, value); | |
} | |
public static <T> ObjectMaker<JsonObjectAlreadyRoot> putString(String key,T value ) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).putString(key, value); | |
} | |
public static <T> ObjectMaker<JsonObjectAlreadyRoot> putBoolean(String key,T value ) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).putBoolean(key, value); | |
} | |
public static <T extends Number> ObjectMaker<JsonObjectAlreadyRoot> putInteger(String key, T value) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).putInteger(key, value); | |
} | |
public static <T> ObjectMaker<JsonObjectAlreadyRoot> putInteger(String key,T value) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).putInteger(key, value); | |
} | |
public static <T extends Number> ObjectMaker<JsonObjectAlreadyRoot> putFloat(String key, T value) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).putFloat(key, value); | |
} | |
public static <T> ObjectMaker<JsonObjectAlreadyRoot> putFloat(String key,T value) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).putFloat(key, value); | |
} | |
public static ArrayElementMaker<ObjectMaker<JsonObjectAlreadyRoot>> openArray(String key) { | |
return new ObjectMaker<JsonObjectAlreadyRoot>(JsonObjectAlreadyRoot.ontain()).openArray(key); | |
} | |
public static class JsonObjectAlreadyRoot { | |
private JsonObjectAlreadyRoot() {} | |
private static JsonObjectAlreadyRoot ontain() { | |
return new JsonObjectAlreadyRoot(); | |
} | |
} | |
public static class ObjectMaker<E> { | |
protected HashMap<String, Object> mStoreMap = new HashMap<String, Object>(); | |
private E mObjectMakerParents = null; | |
public ObjectMaker(E parent) { | |
mObjectMakerParents = parent; | |
} | |
public ObjectMaker<ObjectMaker<?>> openObject(String key) { | |
ObjectMaker<ObjectMaker<?>> objectMaker = null; | |
Object object = mStoreMap.get(key); | |
if(object == null || object.getClass().equals(ObjectMaker.class)) { | |
object = null; | |
mStoreMap.remove(key); | |
objectMaker = new ObjectMaker<ObjectMaker<?>>(this); | |
mStoreMap.put(key, objectMaker); | |
} | |
return objectMaker; | |
} | |
public E closeObject() { | |
return mObjectMakerParents; | |
} | |
public <T> ObjectMaker<E> put(String key,T value ) { | |
if(value instanceof Float || value instanceof Double) { | |
return putFloat(key, value); | |
} else if(value instanceof Number) { | |
return putInteger(key, value); | |
} else if(isBooleanType(value)) { | |
return putBoolean(key, value); | |
} | |
return putString(key, value); | |
} | |
public <T> ObjectMaker<E> putString(String key,T value ) { | |
String str = value == null?"null":value.toString(); | |
mStoreMap.put(key,str); | |
return this; | |
} | |
public <T extends Number> ObjectMaker<E> putInteger(String key, T value) { | |
mStoreMap.put(key,value.longValue()); | |
return this; | |
} | |
public <T> ObjectMaker<E> putInteger(String key,T value) { | |
String str = value == null?"null":value.toString(); | |
long number = 0; | |
try { | |
number = Long.parseLong(str); | |
} catch(NumberFormatException e) {} | |
mStoreMap.put(key,number); | |
return this; | |
} | |
public <T> ObjectMaker<E> putBoolean(String key,T value) { | |
String str = value == null?"null":value.toString().toLowerCase().trim(); | |
mStoreMap.put(key,str.equals("true")); | |
return this; | |
} | |
public <T extends Number> ObjectMaker<E> putFloat(String key, T value) { | |
mStoreMap.put(key,value.doubleValue()); | |
return this; | |
} | |
public <T> ObjectMaker<E> putFloat(String key,T value) { | |
String str = value == null?"null":value.toString(); | |
double number = 0; | |
try { | |
number = Double.parseDouble(str); | |
} catch(NumberFormatException e) {} | |
mStoreMap.put(key,number); | |
return this; | |
} | |
public <T> ObjectMaker<E> putArray(String key,Collection<T> arrayValues) { | |
if(arrayValues == null) { | |
return putString(key, null); | |
} | |
ArrayElementMaker<ObjectMaker<E>> arrayElementMaker = openArray(key); | |
for(T value : arrayValues) { | |
arrayElementMaker = arrayElementMaker.next(value); | |
} | |
return arrayElementMaker.closeArray(); | |
} | |
public ArrayElementMaker<ObjectMaker<E>> openArray(String key) { | |
ArrayElementMaker<ObjectMaker<E>> arrayObjectMaker = null; | |
Object object = mStoreMap.get(key); | |
if(object == null || object.getClass().equals(ArrayElementMaker.class)) { | |
object = null; | |
mStoreMap.remove(key); | |
arrayObjectMaker = new ArrayElementMaker<ObjectMaker<E>>(this); | |
mStoreMap.put(key, arrayObjectMaker); | |
} | |
return arrayObjectMaker; | |
} | |
private void make(StringBuffer buffer) { | |
buffer.append("{"); | |
Set<Entry<String, Object>> keyValueSet = mStoreMap.entrySet(); | |
int count = 0, endIndex = keyValueSet.size() - 1; | |
for(Entry<String, Object> entry : keyValueSet) { | |
Object value = entry.getValue(); | |
Object key = entry.getKey(); | |
buffer.append('"').append(key).append('"').append(':'); | |
appendValueToString(buffer, value); | |
if(count != endIndex) { | |
buffer.append(","); | |
} | |
++count; | |
} | |
buffer.append("}"); | |
} | |
@Override | |
public String toString() { | |
ObjectMaker<?> rootObj = findRoot(this, mObjectMakerParents); | |
if(rootObj == this) { | |
StringBuffer stringBuffer = new StringBuffer(); | |
make(stringBuffer); | |
releaseRef(); | |
return stringBuffer.toString(); | |
} else { | |
return rootObj.toString(); | |
} | |
} | |
private void releaseRef() { | |
Collection<Object> values = mStoreMap.values(); | |
for(Object value : values) { | |
if(value instanceof ObjectMaker<?>) { | |
((ObjectMaker<?>)value).releaseRef(); | |
((ObjectMaker<?>)value).mObjectMakerParents = null; | |
} else if(value instanceof ArrayElementMaker<?>) { | |
((ArrayElementMaker<?>)value).releaseRef(); | |
} | |
} | |
mStoreMap.clear(); | |
} | |
} | |
public static class ArrayElementMaker<E> { | |
private Object mValue; | |
protected E mUpper = null; | |
private ArrayElementMaker<?> mNext; | |
private ArrayElementMaker<?> mPrev; | |
ArrayElementMaker(E upper) { | |
mUpper = upper; | |
} | |
public ObjectMaker<ArrayElementMaker<E>> nextObject() { | |
ArrayElementMaker<E> arrayObjectMaker = new ArrayElementMaker<E>(mUpper); | |
ObjectMaker<ArrayElementMaker<E>> objectMaker = new ObjectMaker<ArrayElementMaker<E>>(arrayObjectMaker); | |
arrayObjectMaker.mValue = objectMaker; | |
mNext = arrayObjectMaker; | |
arrayObjectMaker.mPrev = this; | |
return objectMaker; | |
} | |
public <T> ArrayElementMaker<E> next(T value) { | |
if(value instanceof Float || value instanceof Double) { | |
return nextFloat((Number)value); | |
} else if(value instanceof Number) { | |
return nextInteger((Number)value); | |
} else if(isBooleanType(value)) { | |
return nextBoolean(value); | |
} | |
return nextString(value.toString()); | |
} | |
public <T> ArrayElementMaker<E> nextString(T value) { | |
String str = value == null?"null":value.toString(); | |
ArrayElementMaker<E> arrayElementMaker = new ArrayElementMaker<E>(mUpper); | |
return link(arrayElementMaker, str); | |
} | |
public <T> ArrayElementMaker<E> nextBoolean(T value) { | |
ArrayElementMaker<E> arrayElementMaker = new ArrayElementMaker<E>(mUpper); | |
String str = value == null?"null":value.toString().toLowerCase().trim(); | |
return link(arrayElementMaker, str.equals("true")); | |
} | |
public <T extends Number> ArrayElementMaker<E> nextInteger(T value) { | |
ArrayElementMaker<E> arrayElementMaker = new ArrayElementMaker<E>(mUpper); | |
return link(arrayElementMaker, value.longValue()); | |
} | |
public <T> ArrayElementMaker<E> nextInteger(T value) { | |
ArrayElementMaker<E> arrayElementMaker = new ArrayElementMaker<E>(mUpper); | |
String str = value == null?"null":value.toString(); | |
long number = 0; | |
try { | |
number = Long.parseLong(str); | |
} catch(NumberFormatException e) {} | |
return link(arrayElementMaker, number); | |
} | |
public <T extends Number> ArrayElementMaker<E> nextFloat(T value) { | |
ArrayElementMaker<E> arrayElementMaker = new ArrayElementMaker<E>(mUpper); | |
return link(arrayElementMaker, value.doubleValue()); | |
} | |
private ArrayElementMaker<E> link(ArrayElementMaker<E> arrayElementMaker,Object value) { | |
arrayElementMaker.mValue = value; | |
mNext = arrayElementMaker; | |
arrayElementMaker.mPrev = this; | |
return arrayElementMaker; | |
} | |
public <T> ArrayElementMaker<E> nextFloat(String value) { | |
ArrayElementMaker<E> arrayObjectMaker = new ArrayElementMaker<E>(mUpper); | |
String str = value == null?"null":value.toString(); | |
double number = 0; | |
try { | |
number = Double.parseDouble(str); | |
} catch(NumberFormatException e) {} | |
arrayObjectMaker.mValue = number; | |
mNext = arrayObjectMaker; | |
arrayObjectMaker.mPrev = this; | |
return arrayObjectMaker; | |
} | |
public E closeArray() { | |
return mUpper; | |
} | |
private ArrayElementMaker<?> toHead() { | |
ArrayElementMaker<?> node = this; | |
while(node.mPrev != null) { | |
node = node.mPrev; | |
} | |
return node; | |
} | |
private void make(StringBuffer buffer) { | |
ArrayElementMaker<?> node, headNode = toHead(); | |
node = headNode; | |
buffer.append("["); | |
while(node != null) { | |
Object value = node.mValue; | |
if(value == null) { | |
node = node.mNext; | |
continue; | |
} | |
else { | |
appendValueToString(buffer, value); | |
} | |
buffer.append(","); | |
node = node.mNext; | |
} | |
if(buffer.charAt(buffer.length() - 1) == ',') { | |
buffer.replace(buffer.length() - 1, buffer.length(), "]"); | |
} else { | |
buffer.append("]"); | |
} | |
} | |
protected void releaseRef() { | |
ArrayElementMaker<?> node, headNode = toHead(); | |
node = headNode; | |
while(node.mNext != null) { | |
ArrayElementMaker<?> nextNode = node.mNext; | |
node.mNext = null; | |
node.mPrev = null; | |
node.mUpper = null; | |
if(node.mValue instanceof ArrayElementMaker<?>) { | |
((ArrayElementMaker<?>)node.mValue).releaseRef(); | |
} else if(node.mValue instanceof ObjectMaker<?>) { | |
((ObjectMaker<?>)node.mValue).releaseRef(); | |
} | |
node = nextNode; | |
} | |
} | |
@Override | |
public String toString() { | |
ObjectMaker<?> rootObj = findRoot(this, mUpper); | |
return rootObj.toString(); | |
} | |
} | |
private static <T> boolean isBooleanType(T value) { | |
if(value == null) return false; | |
String str = value.toString(); | |
str = str.toString().toLowerCase().trim(); | |
return str.equals("true") || str.equals("false"); | |
} | |
private static void appendValueToString(StringBuffer buffer, Object value) { | |
if(value instanceof CharSequence) { | |
if(value.equals("null")) { | |
buffer.append(value); | |
} else { | |
buffer.append('"').append(value).append('"'); | |
} | |
} else if(value instanceof ObjectMaker) { | |
((ObjectMaker<?>)value).make(buffer); | |
} else if(value instanceof ArrayElementMaker) { | |
((ArrayElementMaker<?>)value).make(buffer); | |
} else { | |
buffer.append(value.toString()); | |
} | |
} | |
private static ObjectMaker<?> findRoot(Object startObj, Object parent) { | |
Object node = parent; | |
Object prevNode = startObj; | |
while(!(node instanceof JsonObjectAlreadyRoot)) { | |
prevNode = node; | |
if(node instanceof ArrayElementMaker) { | |
node = ((ArrayElementMaker<?>)node).mUpper; | |
} else if(node instanceof ObjectMaker) { | |
node = ((ObjectMaker<?>)node).mObjectMakerParents; | |
} | |
} | |
return (ObjectMaker<?>)prevNode; | |
} | |
} | |
/*Copyright (c) 2015 Beom ice3x2@gmail.com | |
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.*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Description
How to use
jsonValue