Skip to content

Commit ab5615e

Browse files
committed
Added thread safety; custom JSON formatting
1 parent 0a99b84 commit ab5615e

File tree

7 files changed

+211
-196
lines changed

7 files changed

+211
-196
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66
<groupId>de.arraying</groupId>
77
<artifactId>Kotys</artifactId>
8-
<version>0.5.2</version>
8+
<version>0.6.0</version>
99
<build>
1010
<plugins>
1111
<plugin>

src/main/java/de/arraying/kotys/JSON.java

+46-26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.io.IOException;
55
import java.io.StringReader;
66
import java.util.*;
7+
import java.util.concurrent.ConcurrentHashMap;
78

89
/**
910
* Copyright 2017 Arraying
@@ -23,10 +24,10 @@
2324
@SuppressWarnings({"WeakerAccess", "unused", "UnusedReturnValue"})
2425
public class JSON {
2526

26-
private final Map<String, Object> rawContent = new LinkedHashMap<>();
2727
private static final JSONUtil util = new JSONUtil();
28-
29-
private JSONMarshalFormat format = null;
28+
private final Object writeLock = new Object();
29+
private Map<String, Object> rawContent = new HashMap<>();
30+
private JSONFormatter formatter = new JSONFormatter.DefaultImplementation();
3031

3132
/**
3233
* Creates an empty JSON object.
@@ -118,6 +119,39 @@ public JSON(File file)
118119
this(util.getFileContent(file, true));
119120
}
120121

122+
/**
123+
* Specifies the map type to use for internal storage.
124+
* This is so that when marshalling some specific ordering is retained.
125+
* This map will get cleared.
126+
* Note that a {@link java.util.concurrent.ConcurrentHashMap} is not allowed.
127+
* @param map The map.
128+
*/
129+
public void use(Map<String, Object> map) {
130+
if(map == null) {
131+
throw new IllegalArgumentException("Provided map is null");
132+
}
133+
if(map instanceof ConcurrentHashMap) {
134+
throw new IllegalArgumentException("ConcurrentHashMap not allowed");
135+
}
136+
Map<String, Object> cache = new HashMap<>(rawContent);
137+
map.clear();
138+
synchronized(writeLock) {
139+
rawContent = map;
140+
rawContent.putAll(cache);
141+
}
142+
}
143+
144+
/**
145+
* Specifies the formatter to use when marshalling to a string.
146+
* @param formatter A formatter instance.
147+
*/
148+
public void use(JSONFormatter formatter) {
149+
if(formatter == null) {
150+
throw new IllegalArgumentException("Formatter is null");
151+
}
152+
this.formatter = formatter;
153+
}
154+
121155
/**
122156
* Adds an entry to the current JSON object.
123157
* This entry can either be a raw JSON data type, or a custom object.
@@ -132,7 +166,9 @@ public JSON put(String key, Object entry)
132166
if(key == null) {
133167
throw new IllegalArgumentException("Provided key is null");
134168
}
135-
rawContent.put(key, util.getFinalValue(entry));
169+
synchronized(writeLock) {
170+
rawContent.put(key, util.getFinalValue(entry));
171+
}
136172
return this;
137173
}
138174

@@ -147,7 +183,9 @@ public JSON remove(String key)
147183
if(key == null) {
148184
throw new IllegalArgumentException("Provided key is null");
149185
}
150-
rawContent.remove(key);
186+
synchronized(writeLock) {
187+
rawContent.remove(key);
188+
}
151189
return this;
152190
}
153191

@@ -286,27 +324,19 @@ public final int length() {
286324
* @return A string representation of the JSON object.
287325
*/
288326
public final String marshal() {
289-
JSONFormatter formatter = new JSONFormatter()
290-
.startObject();
327+
formatter.startObject();
291328
Iterator<Map.Entry<String, Object>> iterator = rawContent.entrySet().iterator();
292329
while(iterator.hasNext()) {
293330
Map.Entry<String, Object> entry = iterator.next();
294331
formatter.objectKey(entry.getKey());
295332
Object valueRaw = entry.getValue();
296-
if(valueRaw instanceof JSON) {
297-
formatter.object(((JSON) valueRaw).marshal());
298-
} else if(valueRaw instanceof JSONArray) {
299-
formatter.array(((JSONArray) valueRaw).marshal());
300-
} else {
301-
formatter.value(valueRaw);
302-
}
333+
util.format(formatter, valueRaw);
303334
if(iterator.hasNext()) {
304335
formatter.comma();
305336
}
306337
}
307338
formatter.endObject();
308-
309-
return format != null ? format.format(formatter.result()) : formatter.result();
339+
return formatter.result();
310340
}
311341

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

339-
/**
340-
* Set formatting to be applied for String marshal()
341-
* @param format - Format to be applied to String marshal()
342-
*/
343-
344-
public JSON setFormat(JSONMarshalFormat format) {
345-
this.format = format;
346-
return this;
347-
}
348-
349369
/**
350370
* Converts the JSON object to a string.
351371
* This method invokes the {@link #marshal()} method.

src/main/java/de/arraying/kotys/JSONArray.java

+22-13
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
@SuppressWarnings({"WeakerAccess", "unused", "UnusedReturnValue"})
2525
public class JSONArray implements Iterator<Object> {
2626

27-
private final List<Object> rawContent = new ArrayList<>();
2827
private static final JSONUtil util = new JSONUtil();
28+
private final Object writeLock = new Object();
29+
private final List<Object> rawContent = new ArrayList<>();
30+
private JSONFormatter formatter = new JSONFormatter.DefaultImplementation();
2931

3032
/**
3133
* Creates an empty JSON array.
@@ -88,6 +90,16 @@ public JSONArray(File file)
8890
throws IOException, IllegalStateException {
8991
this(util.getFileContent(file, false));
9092
}
93+
/**
94+
* Specifies the formatter to use when marshalling to a string.
95+
* @param formatter A formatter instance.
96+
*/
97+
public void use(JSONFormatter formatter) {
98+
if(formatter == null) {
99+
throw new IllegalArgumentException("Formatter is null");
100+
}
101+
this.formatter = formatter;
102+
}
91103

92104
/**
93105
* Appends a value to the array.
@@ -98,8 +110,10 @@ public JSONArray(File file)
98110
*/
99111
public JSONArray append(Object... values)
100112
throws IllegalArgumentException {
101-
for(Object object : values) {
102-
rawContent.add(util.getFinalValue(object));
113+
synchronized(writeLock) {
114+
for(Object object : values) {
115+
rawContent.add(util.getFinalValue(object));
116+
}
103117
}
104118
return this;
105119
}
@@ -110,7 +124,9 @@ public JSONArray append(Object... values)
110124
* @return The object that was removed from the Array.
111125
*/
112126
public Object delete(int index) {
113-
return rawContent.remove(index);
127+
synchronized(writeLock) {
128+
return rawContent.remove(index);
129+
}
114130
}
115131

116132
/**
@@ -243,17 +259,10 @@ public final Object[] toArray() {
243259
* @return A string representation of the JSON array.
244260
*/
245261
public final String marshal() {
246-
JSONFormatter formatter = new JSONFormatter()
247-
.startArray();
262+
formatter.startArray();
248263
for(int i = 0; i < length(); i++) {
249264
Object valueRaw = rawContent.get(i);
250-
if(valueRaw instanceof JSON) {
251-
formatter.object(((JSON) valueRaw).marshal());
252-
} else if(valueRaw instanceof JSONArray) {
253-
formatter.array(((JSONArray) valueRaw).marshal());
254-
} else {
255-
formatter.value(valueRaw);
256-
}
265+
util.format(formatter, valueRaw);
257266
if(i + 1 < length()) {
258267
formatter.comma();
259268
}

src/main/java/de/arraying/kotys/JSONDefaultMarshalFormat.java

-85
This file was deleted.

0 commit comments

Comments
 (0)