mirror of
https://github.com/stleary/JSON-java.git
synced 2026-01-24 00:03:17 -05:00
Updating to work with java 1.6
This commit is contained in:
16
src/main/java/org/json/InstanceCreator.java
Normal file
16
src/main/java/org/json/InstanceCreator.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package org.json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface defining a creator that produces new instances of type {@code T}.
|
||||||
|
*
|
||||||
|
* @param <T> the type of instances created
|
||||||
|
*/
|
||||||
|
public interface InstanceCreator<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of type {@code T}.
|
||||||
|
*
|
||||||
|
* @return a new instance of {@code T}
|
||||||
|
*/
|
||||||
|
T create();
|
||||||
|
}
|
||||||
@@ -7,8 +7,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code JSONBuilder} class provides a configurable mechanism for
|
* The {@code JSONBuilder} class provides a configurable mechanism for
|
||||||
@@ -42,38 +40,88 @@ public class JSONBuilder {
|
|||||||
* <li>{@code String.class} -> Identity function</li>
|
* <li>{@code String.class} -> Identity function</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
private static final Map<Class<?>, Function<Object, ?>> classMapping = new HashMap<>();
|
private static final Map<Class<?>, TypeConverter<?>> classMapping = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapping from collection interface types to suppliers that produce
|
* A mapping from collection interface types to suppliers that produce
|
||||||
* instances of concrete collection implementations.
|
* instances of concrete collection implementations.
|
||||||
*
|
*
|
||||||
* <p>Examples of default mappings:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code List.class} -> {@code ArrayList::new}</li>
|
|
||||||
* <li>{@code Set.class} -> {@code HashSet::new}</li>
|
|
||||||
* <li>{@code Map.class} -> {@code HashMap::new}</li>
|
|
||||||
* </ul>
|
|
||||||
*/
|
*/
|
||||||
private static final Map<Class<?>, Supplier<?>> collectionMapping = new HashMap<>();
|
private static final Map<Class<?>, InstanceCreator<?>> collectionMapping = new HashMap<>();
|
||||||
|
|
||||||
// Static initializer block to populate default mappings
|
// Static initializer block to populate default mappings
|
||||||
static {
|
static {
|
||||||
classMapping.put(int.class, s -> ((Number) s).intValue());
|
classMapping.put(int.class, new TypeConverter<Integer>() {
|
||||||
classMapping.put(Integer.class, s -> ((Number) s).intValue());
|
public Integer convert(Object input) {
|
||||||
classMapping.put(double.class, s -> ((Number) s).doubleValue());
|
return ((Number) input).intValue();
|
||||||
classMapping.put(Double.class, s -> ((Number) s).doubleValue());
|
}
|
||||||
classMapping.put(float.class, s -> ((Number) s).floatValue());
|
});
|
||||||
classMapping.put(Float.class, s -> ((Number) s).floatValue());
|
classMapping.put(Integer.class, new TypeConverter<Integer>() {
|
||||||
classMapping.put(long.class, s -> ((Number) s).longValue());
|
public Integer convert(Object input) {
|
||||||
classMapping.put(Long.class, s -> ((Number) s).longValue());
|
return ((Number) input).intValue();
|
||||||
classMapping.put(boolean.class, s -> s);
|
}
|
||||||
classMapping.put(Boolean.class, s -> s);
|
});
|
||||||
classMapping.put(String.class, s -> s);
|
classMapping.put(double.class, new TypeConverter<Double>() {
|
||||||
|
public Double convert(Object input) {
|
||||||
|
return ((Number) input).doubleValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(Double.class, new TypeConverter<Double>() {
|
||||||
|
public Double convert(Object input) {
|
||||||
|
return ((Number) input).doubleValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(float.class, new TypeConverter<Float>() {
|
||||||
|
public Float convert(Object input) {
|
||||||
|
return ((Number) input).floatValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(Float.class, new TypeConverter<Float>() {
|
||||||
|
public Float convert(Object input) {
|
||||||
|
return ((Number) input).floatValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(long.class, new TypeConverter<Long>() {
|
||||||
|
public Long convert(Object input) {
|
||||||
|
return ((Number) input).longValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(Long.class, new TypeConverter<Long>() {
|
||||||
|
public Long convert(Object input) {
|
||||||
|
return ((Number) input).longValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(boolean.class, new TypeConverter<Boolean>() {
|
||||||
|
public Boolean convert(Object input) {
|
||||||
|
return (Boolean) input;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(Boolean.class, new TypeConverter<Boolean>() {
|
||||||
|
public Boolean convert(Object input) {
|
||||||
|
return (Boolean) input;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
classMapping.put(String.class, new TypeConverter<String>() {
|
||||||
|
public String convert(Object input) {
|
||||||
|
return (String) input;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
collectionMapping.put(List.class, ArrayList::new);
|
collectionMapping.put(List.class, new InstanceCreator<List>() {
|
||||||
collectionMapping.put(Set.class, HashSet::new);
|
public List create() {
|
||||||
collectionMapping.put(Map.class, HashMap::new);
|
return new ArrayList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
collectionMapping.put(Set.class, new InstanceCreator<Set>() {
|
||||||
|
public Set create() {
|
||||||
|
return new HashSet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
collectionMapping.put(Map.class, new InstanceCreator<Map>() {
|
||||||
|
public Map create() {
|
||||||
|
return new HashMap();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,7 +129,7 @@ public class JSONBuilder {
|
|||||||
*
|
*
|
||||||
* @return a map of classes to functions that convert an {@code Object} to that class
|
* @return a map of classes to functions that convert an {@code Object} to that class
|
||||||
*/
|
*/
|
||||||
public Map<Class<?>, Function<Object, ?>> getClassMapping() {
|
public Map<Class<?>, TypeConverter<?>> getClassMapping() {
|
||||||
return this.classMapping;
|
return this.classMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +138,7 @@ public class JSONBuilder {
|
|||||||
*
|
*
|
||||||
* @return a map of collection interface types to suppliers of concrete implementations
|
* @return a map of collection interface types to suppliers of concrete implementations
|
||||||
*/
|
*/
|
||||||
public Map<Class<?>, Supplier<?>> getCollectionMapping() {
|
public Map<Class<?>, InstanceCreator<?>> getCollectionMapping() {
|
||||||
return this.collectionMapping;
|
return this.collectionMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +151,7 @@ public class JSONBuilder {
|
|||||||
* @param clazz the target class for which the conversion function is to be set
|
* @param clazz the target class for which the conversion function is to be set
|
||||||
* @param function a function that takes an {@code Object} and returns an instance of {@code clazz}
|
* @param function a function that takes an {@code Object} and returns an instance of {@code clazz}
|
||||||
*/
|
*/
|
||||||
public void setClassMapping(Class<?> clazz, Function<Object, ?> function) {
|
public void setClassMapping(Class<?> clazz, TypeConverter<?> function) {
|
||||||
classMapping.put(clazz, function);
|
classMapping.put(clazz, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +164,7 @@ public class JSONBuilder {
|
|||||||
* @param clazz the collection interface class (e.g., {@code List.class})
|
* @param clazz the collection interface class (e.g., {@code List.class})
|
||||||
* @param function a supplier that creates a new instance of a concrete implementation
|
* @param function a supplier that creates a new instance of a concrete implementation
|
||||||
*/
|
*/
|
||||||
public void setCollectionMapping(Class<?> clazz, Supplier<?> function) {
|
public void setCollectionMapping(Class<?> clazz, InstanceCreator<?> function) {
|
||||||
collectionMapping.put(clazz, function);
|
collectionMapping.put(clazz, function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3256,7 +3256,7 @@ public class JSONObject {
|
|||||||
if (this.builder == null) {
|
if (this.builder == null) {
|
||||||
this.builder = new JSONBuilder();
|
this.builder = new JSONBuilder();
|
||||||
}
|
}
|
||||||
Map<Class<?>, Function<Object, ?>> classMapping = this.builder.getClassMapping();
|
Map<Class<?>, TypeConverter<?>> classMapping = this.builder.getClassMapping();
|
||||||
|
|
||||||
for (Field field: clazz.getDeclaredFields()) {
|
for (Field field: clazz.getDeclaredFields()) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
@@ -3265,7 +3265,7 @@ public class JSONObject {
|
|||||||
Object value = this.get(fieldName);
|
Object value = this.get(fieldName);
|
||||||
Class<?> pojoClass = field.getType();
|
Class<?> pojoClass = field.getType();
|
||||||
if (classMapping.containsKey(pojoClass)) {
|
if (classMapping.containsKey(pojoClass)) {
|
||||||
field.set(obj, classMapping.get(pojoClass).apply(value));
|
field.set(obj, classMapping.get(pojoClass).convert(value));
|
||||||
} else {
|
} else {
|
||||||
if (value.getClass() == JSONObject.class) {
|
if (value.getClass() == JSONObject.class) {
|
||||||
field.set(obj, fromJson((JSONObject) value, pojoClass));
|
field.set(obj, fromJson((JSONObject) value, pojoClass));
|
||||||
@@ -3290,10 +3290,10 @@ public class JSONObject {
|
|||||||
|
|
||||||
private <T> Collection<T> fromJsonArray(JSONArray jsonArray, Class<?> collectionType, Type elementType) throws JSONException {
|
private <T> Collection<T> fromJsonArray(JSONArray jsonArray, Class<?> collectionType, Type elementType) throws JSONException {
|
||||||
try {
|
try {
|
||||||
Map<Class<?>, Function<Object, ?>> classMapping = this.builder.getClassMapping();
|
Map<Class<?>, TypeConverter<?>> classMapping = this.builder.getClassMapping();
|
||||||
Map<Class<?>, Supplier<?>> collectionMapping = this.builder.getCollectionMapping();
|
Map<Class<?>, InstanceCreator<?>> collectionMapping = this.builder.getCollectionMapping();
|
||||||
Collection<T> collection = (Collection<T>) (collectionMapping.containsKey(collectionType) ?
|
Collection<T> collection = (Collection<T>) (collectionMapping.containsKey(collectionType) ?
|
||||||
collectionMapping.get(collectionType).get()
|
collectionMapping.get(collectionType).create()
|
||||||
: collectionType.getDeclaredConstructor().newInstance());
|
: collectionType.getDeclaredConstructor().newInstance());
|
||||||
|
|
||||||
|
|
||||||
@@ -3312,7 +3312,7 @@ public class JSONObject {
|
|||||||
for (int i = 0; i < jsonArray.length(); i++) {
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
Object jsonElement = jsonArray.get(i);
|
Object jsonElement = jsonArray.get(i);
|
||||||
if (classMapping.containsKey(innerElementClass)) {
|
if (classMapping.containsKey(innerElementClass)) {
|
||||||
collection.add((T) classMapping.get(innerElementClass).apply(jsonElement));
|
collection.add((T) classMapping.get(innerElementClass).convert(jsonElement));
|
||||||
} else if (jsonElement.getClass() == JSONObject.class) {
|
} else if (jsonElement.getClass() == JSONObject.class) {
|
||||||
collection.add((T) ((JSONObject) jsonElement).fromJson(innerElementClass));
|
collection.add((T) ((JSONObject) jsonElement).fromJson(innerElementClass));
|
||||||
} else if (jsonElement.getClass() == JSONArray.class) {
|
} else if (jsonElement.getClass() == JSONArray.class) {
|
||||||
|
|||||||
18
src/main/java/org/json/TypeConverter.java
Normal file
18
src/main/java/org/json/TypeConverter.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package org.json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface defining a converter that converts an input {@code Object}
|
||||||
|
* into an instance of a specific type {@code T}.
|
||||||
|
*
|
||||||
|
* @param <T> the target type to convert to
|
||||||
|
*/
|
||||||
|
public interface TypeConverter<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the given input object to an instance of type {@code T}.
|
||||||
|
*
|
||||||
|
* @param input the object to convert
|
||||||
|
* @return the converted instance of type {@code T}
|
||||||
|
*/
|
||||||
|
T convert(Object input);
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ import org.json.JSONBuilder;
|
|||||||
import org.json.JSONTokener;
|
import org.json.JSONTokener;
|
||||||
import org.json.ParserConfiguration;
|
import org.json.ParserConfiguration;
|
||||||
import org.json.XML;
|
import org.json.XML;
|
||||||
|
import org.json.TypeConverter;
|
||||||
import org.json.junit.data.BrokenToString;
|
import org.json.junit.data.BrokenToString;
|
||||||
import org.json.junit.data.ExceptionalBean;
|
import org.json.junit.data.ExceptionalBean;
|
||||||
import org.json.junit.data.Fraction;
|
import org.json.junit.data.Fraction;
|
||||||
@@ -4133,7 +4134,11 @@ public class JSONObjectTest {
|
|||||||
@Test
|
@Test
|
||||||
public void jsonObjectParseFromJson_1() {
|
public void jsonObjectParseFromJson_1() {
|
||||||
JSONBuilder builder = new JSONBuilder();
|
JSONBuilder builder = new JSONBuilder();
|
||||||
builder.setClassMapping(java.time.LocalDateTime.class, s -> java.time.LocalDateTime.parse((String)s));
|
builder.setClassMapping(java.time.LocalDateTime.class, new TypeConverter<java.time.LocalDateTime>() {
|
||||||
|
public java.time.LocalDateTime convert(Object input) {
|
||||||
|
return java.time.LocalDateTime.parse((String) input);
|
||||||
|
}
|
||||||
|
});
|
||||||
JSONObject object = new JSONObject(builder);
|
JSONObject object = new JSONObject(builder);
|
||||||
java.time.LocalDateTime localDateTime = java.time.LocalDateTime.now();
|
java.time.LocalDateTime localDateTime = java.time.LocalDateTime.now();
|
||||||
object.put("localDate", localDateTime.toString());
|
object.put("localDate", localDateTime.toString());
|
||||||
|
|||||||
Reference in New Issue
Block a user