Skip to content

Commit

Permalink
Added thread safety; custom JSON formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
Arraying committed Dec 22, 2019
1 parent 0a99b84 commit ab5615e
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 196 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.arraying</groupId>
<artifactId>Kotys</artifactId>
<version>0.5.2</version>
<version>0.6.0</version>
<build>
<plugins>
<plugin>
Expand Down
72 changes: 46 additions & 26 deletions src/main/java/de/arraying/kotys/JSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* Copyright 2017 Arraying
Expand All @@ -23,10 +24,10 @@
@SuppressWarnings({"WeakerAccess", "unused", "UnusedReturnValue"})
public class JSON {

private final Map<String, Object> rawContent = new LinkedHashMap<>();
private static final JSONUtil util = new JSONUtil();

private JSONMarshalFormat format = null;
private final Object writeLock = new Object();
private Map<String, Object> rawContent = new HashMap<>();
private JSONFormatter formatter = new JSONFormatter.DefaultImplementation();

/**
* Creates an empty JSON object.
Expand Down Expand Up @@ -118,6 +119,39 @@ public JSON(File file)
this(util.getFileContent(file, true));
}

/**
* Specifies the map type to use for internal storage.
* This is so that when marshalling some specific ordering is retained.
* This map will get cleared.
* Note that a {@link java.util.concurrent.ConcurrentHashMap} is not allowed.
* @param map The map.
*/
public void use(Map<String, Object> map) {
if(map == null) {
throw new IllegalArgumentException("Provided map is null");
}
if(map instanceof ConcurrentHashMap) {
throw new IllegalArgumentException("ConcurrentHashMap not allowed");
}
Map<String, Object> cache = new HashMap<>(rawContent);
map.clear();
synchronized(writeLock) {
rawContent = map;
rawContent.putAll(cache);
}
}

/**
* Specifies the formatter to use when marshalling to a string.
* @param formatter A formatter instance.
*/
public void use(JSONFormatter formatter) {
if(formatter == null) {
throw new IllegalArgumentException("Formatter is null");
}
this.formatter = formatter;
}

/**
* Adds an entry to the current JSON object.
* This entry can either be a raw JSON data type, or a custom object.
Expand All @@ -132,7 +166,9 @@ public JSON put(String key, Object entry)
if(key == null) {
throw new IllegalArgumentException("Provided key is null");
}
rawContent.put(key, util.getFinalValue(entry));
synchronized(writeLock) {
rawContent.put(key, util.getFinalValue(entry));
}
return this;
}

Expand All @@ -147,7 +183,9 @@ public JSON remove(String key)
if(key == null) {
throw new IllegalArgumentException("Provided key is null");
}
rawContent.remove(key);
synchronized(writeLock) {
rawContent.remove(key);
}
return this;
}

Expand Down Expand Up @@ -286,27 +324,19 @@ public final int length() {
* @return A string representation of the JSON object.
*/
public final String marshal() {
JSONFormatter formatter = new JSONFormatter()
.startObject();
formatter.startObject();
Iterator<Map.Entry<String, Object>> iterator = rawContent.entrySet().iterator();
while(iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
formatter.objectKey(entry.getKey());
Object valueRaw = entry.getValue();
if(valueRaw instanceof JSON) {
formatter.object(((JSON) valueRaw).marshal());
} else if(valueRaw instanceof JSONArray) {
formatter.array(((JSONArray) valueRaw).marshal());
} else {
formatter.value(valueRaw);
}
util.format(formatter, valueRaw);
if(iterator.hasNext()) {
formatter.comma();
}
}
formatter.endObject();

return format != null ? format.format(formatter.result()) : formatter.result();
return formatter.result();
}

/**
Expand Down Expand Up @@ -336,16 +366,6 @@ public final <T> T marshal(Class<T> clazz, String... ignoredKeys)
return new JSONORM<>(clazz).mapTo(this, ignoredKeys);
}

/**
* Set formatting to be applied for String marshal()
* @param format - Format to be applied to String marshal()
*/

public JSON setFormat(JSONMarshalFormat format) {
this.format = format;
return this;
}

/**
* Converts the JSON object to a string.
* This method invokes the {@link #marshal()} method.
Expand Down
35 changes: 22 additions & 13 deletions src/main/java/de/arraying/kotys/JSONArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
@SuppressWarnings({"WeakerAccess", "unused", "UnusedReturnValue"})
public class JSONArray implements Iterator<Object> {

private final List<Object> rawContent = new ArrayList<>();
private static final JSONUtil util = new JSONUtil();
private final Object writeLock = new Object();
private final List<Object> rawContent = new ArrayList<>();
private JSONFormatter formatter = new JSONFormatter.DefaultImplementation();

/**
* Creates an empty JSON array.
Expand Down Expand Up @@ -88,6 +90,16 @@ public JSONArray(File file)
throws IOException, IllegalStateException {
this(util.getFileContent(file, false));
}
/**
* Specifies the formatter to use when marshalling to a string.
* @param formatter A formatter instance.
*/
public void use(JSONFormatter formatter) {
if(formatter == null) {
throw new IllegalArgumentException("Formatter is null");
}
this.formatter = formatter;
}

/**
* Appends a value to the array.
Expand All @@ -98,8 +110,10 @@ public JSONArray(File file)
*/
public JSONArray append(Object... values)
throws IllegalArgumentException {
for(Object object : values) {
rawContent.add(util.getFinalValue(object));
synchronized(writeLock) {
for(Object object : values) {
rawContent.add(util.getFinalValue(object));
}
}
return this;
}
Expand All @@ -110,7 +124,9 @@ public JSONArray append(Object... values)
* @return The object that was removed from the Array.
*/
public Object delete(int index) {
return rawContent.remove(index);
synchronized(writeLock) {
return rawContent.remove(index);
}
}

/**
Expand Down Expand Up @@ -243,17 +259,10 @@ public final Object[] toArray() {
* @return A string representation of the JSON array.
*/
public final String marshal() {
JSONFormatter formatter = new JSONFormatter()
.startArray();
formatter.startArray();
for(int i = 0; i < length(); i++) {
Object valueRaw = rawContent.get(i);
if(valueRaw instanceof JSON) {
formatter.object(((JSON) valueRaw).marshal());
} else if(valueRaw instanceof JSONArray) {
formatter.array(((JSONArray) valueRaw).marshal());
} else {
formatter.value(valueRaw);
}
util.format(formatter, valueRaw);
if(i + 1 < length()) {
formatter.comma();
}
Expand Down
85 changes: 0 additions & 85 deletions src/main/java/de/arraying/kotys/JSONDefaultMarshalFormat.java

This file was deleted.

Loading

0 comments on commit ab5615e

Please sign in to comment.