Skip to content

Commit 7852810

Browse files
authored
Merge pull request #543 from johnjaylward/RefactorXmlConfiguration
Refactor XMLConfiguration to use Builder Pattern
2 parents 0e34d8d + 4f1c8b2 commit 7852810

File tree

5 files changed

+179
-38
lines changed

5 files changed

+179
-38
lines changed

src/main/java/org/json/XML.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
286286
if (x.next() == '[') {
287287
string = x.nextCDATA();
288288
if (string.length() > 0) {
289-
context.accumulate(config.cDataTagName, string);
289+
context.accumulate(config.getcDataTagName(), string);
290290
}
291291
return false;
292292
}
@@ -350,13 +350,13 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
350350
throw x.syntaxError("Missing value");
351351
}
352352

353-
if (config.convertNilAttributeToNull
353+
if (config.isConvertNilAttributeToNull()
354354
&& NULL_ATTR.equals(string)
355355
&& Boolean.parseBoolean((String) token)) {
356356
nilAttributeFound = true;
357357
} else if (!nilAttributeFound) {
358358
jsonObject.accumulate(string,
359-
config.keepStrings
359+
config.isKeepStrings()
360360
? ((String) token)
361361
: stringToValue((String) token));
362362
}
@@ -392,8 +392,8 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
392392
} else if (token instanceof String) {
393393
string = (String) token;
394394
if (string.length() > 0) {
395-
jsonObject.accumulate(config.cDataTagName,
396-
config.keepStrings ? string : stringToValue(string));
395+
jsonObject.accumulate(config.getcDataTagName(),
396+
config.isKeepStrings() ? string : stringToValue(string));
397397
}
398398

399399
} else if (token == LT) {
@@ -402,8 +402,8 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
402402
if (jsonObject.length() == 0) {
403403
context.accumulate(tagName, "");
404404
} else if (jsonObject.length() == 1
405-
&& jsonObject.opt(config.cDataTagName) != null) {
406-
context.accumulate(tagName, jsonObject.opt(config.cDataTagName));
405+
&& jsonObject.opt(config.getcDataTagName()) != null) {
406+
context.accumulate(tagName, jsonObject.opt(config.getcDataTagName()));
407407
} else {
408408
context.accumulate(tagName, jsonObject);
409409
}
@@ -748,7 +748,7 @@ public static String toString(final Object object, final String tagName, final X
748748
}
749749

750750
// Emit content in body
751-
if (key.equals(config.cDataTagName)) {
751+
if (key.equals(config.getcDataTagName())) {
752752
if (value instanceof JSONArray) {
753753
ja = (JSONArray) value;
754754
int jaLength = ja.length();

src/main/java/org/json/XMLParserConfiguration.java

Lines changed: 132 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,57 @@ of this software and associated documentation files (the "Software"), to deal
2424
*/
2525

2626
/**
27-
* Configuration object for the XML parser.
27+
* Configuration object for the XML parser. The configuration is immutable.
2828
* @author AylwardJ
29-
*
3029
*/
30+
@SuppressWarnings({""})
3131
public class XMLParserConfiguration {
3232
/** Original Configuration of the XML Parser. */
33-
public static final XMLParserConfiguration ORIGINAL = new XMLParserConfiguration();
33+
public static final XMLParserConfiguration ORIGINAL
34+
= new XMLParserConfiguration();
3435
/** Original configuration of the XML Parser except that values are kept as strings. */
35-
public static final XMLParserConfiguration KEEP_STRINGS = new XMLParserConfiguration(true);
36+
public static final XMLParserConfiguration KEEP_STRINGS
37+
= new XMLParserConfiguration().withKeepStrings(true);
38+
3639
/**
37-
* When parsing the XML into JSON, specifies if values should be kept as strings (true), or if
40+
* When parsing the XML into JSON, specifies if values should be kept as strings (<code>true</code>), or if
3841
* they should try to be guessed into JSON values (numeric, boolean, string)
3942
*/
40-
public final boolean keepStrings;
43+
private boolean keepStrings;
44+
4145
/**
4246
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
4347
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
4448
* processing.
4549
*/
46-
public final String cDataTagName;
50+
private String cDataTagName;
51+
4752
/**
4853
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
49-
* should be kept as attribute(false), or they should be converted to null(true)
54+
* should be kept as attribute(<code>false</code>), or they should be converted to
55+
* <code>null</code>(<code>true</code>)
5056
*/
51-
public final boolean convertNilAttributeToNull;
57+
private boolean convertNilAttributeToNull;
5258

5359
/**
54-
* Default parser configuration. Does not keep strings, and the CDATA Tag Name is "content".
60+
* Default parser configuration. Does not keep strings (tries to implicitly convert
61+
* values), and the CDATA Tag Name is "content".
5562
*/
5663
public XMLParserConfiguration () {
57-
this(false, "content", false);
64+
this.keepStrings = false;
65+
this.cDataTagName = "content";
66+
this.convertNilAttributeToNull = false;
5867
}
5968

6069
/**
6170
* Configure the parser string processing and use the default CDATA Tag Name as "content".
6271
* @param keepStrings <code>true</code> to parse all values as string.
6372
* <code>false</code> to try and convert XML string values into a JSON value.
73+
* @deprecated This constructor has been deprecated in favor of using the new builder
74+
* pattern for the configuration.
75+
* This constructor may be removed in a future release.
6476
*/
77+
@Deprecated
6578
public XMLParserConfiguration (final boolean keepStrings) {
6679
this(keepStrings, "content", false);
6780
}
@@ -72,7 +85,11 @@ public XMLParserConfiguration (final boolean keepStrings) {
7285
* disable CDATA processing
7386
* @param cDataTagName<code>null</code> to disable CDATA processing. Any other value
7487
* to use that value as the JSONObject key name to process as CDATA.
88+
* @deprecated This constructor has been deprecated in favor of using the new builder
89+
* pattern for the configuration.
90+
* This constructor may be removed in a future release.
7591
*/
92+
@Deprecated
7693
public XMLParserConfiguration (final String cDataTagName) {
7794
this(false, cDataTagName, false);
7895
}
@@ -83,7 +100,11 @@ public XMLParserConfiguration (final String cDataTagName) {
83100
* <code>false</code> to try and convert XML string values into a JSON value.
84101
* @param cDataTagName<code>null</code> to disable CDATA processing. Any other value
85102
* to use that value as the JSONObject key name to process as CDATA.
103+
* @deprecated This constructor has been deprecated in favor of using the new builder
104+
* pattern for the configuration.
105+
* This constructor may be removed in a future release.
86106
*/
107+
@Deprecated
87108
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) {
88109
this.keepStrings = keepStrings;
89110
this.cDataTagName = cDataTagName;
@@ -98,10 +119,110 @@ public XMLParserConfiguration (final boolean keepStrings, final String cDataTagN
98119
* to use that value as the JSONObject key name to process as CDATA.
99120
* @param convertNilAttributeToNull <code>true</code> to parse values with attribute xsi:nil="true" as null.
100121
* <code>false</code> to parse values with attribute xsi:nil="true" as {"xsi:nil":true}.
122+
* @deprecated This constructor has been deprecated in favor of using the new builder
123+
* pattern for the configuration.
124+
* This constructor may be removed or marked private in a future release.
101125
*/
126+
@Deprecated
102127
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) {
103128
this.keepStrings = keepStrings;
104129
this.cDataTagName = cDataTagName;
105130
this.convertNilAttributeToNull = convertNilAttributeToNull;
106131
}
132+
133+
/**
134+
* Provides a new instance of the same configuration.
135+
*/
136+
@Override
137+
protected XMLParserConfiguration clone() {
138+
// future modifications to this method should always ensure a "deep"
139+
// clone in the case of collections. i.e. if a Map is added as a configuration
140+
// item, a new map instance should be created and if possible each value in the
141+
// map should be cloned as well. If the values of the map are known to also
142+
// be immutable, then a shallow clone of the map is acceptable.
143+
return new XMLParserConfiguration(
144+
this.keepStrings,
145+
this.cDataTagName,
146+
this.convertNilAttributeToNull
147+
);
148+
}
149+
150+
/**
151+
* When parsing the XML into JSON, specifies if values should be kept as strings (<code>true</code>), or if
152+
* they should try to be guessed into JSON values (numeric, boolean, string)
153+
*
154+
* @return The {@link #keepStrings} configuration value.
155+
*/
156+
public boolean isKeepStrings() {
157+
return this.keepStrings;
158+
}
159+
160+
/**
161+
* When parsing the XML into JSON, specifies if values should be kept as strings (<code>true</code>), or if
162+
* they should try to be guessed into JSON values (numeric, boolean, string)
163+
*
164+
* @param newVal
165+
* new value to use for the {@link #keepStrings} configuration option.
166+
*
167+
* @return The existing configuration will not be modified. A new configuration is returned.
168+
*/
169+
public XMLParserConfiguration withKeepStrings(final boolean newVal) {
170+
XMLParserConfiguration newConfig = this.clone();
171+
newConfig.keepStrings = newVal;
172+
return newConfig;
173+
}
174+
175+
/**
176+
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
177+
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
178+
* processing.
179+
*
180+
* @return The {@link #cDataTagName} configuration value.
181+
*/
182+
public String getcDataTagName() {
183+
return this.cDataTagName;
184+
}
185+
186+
/**
187+
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
188+
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
189+
* processing.
190+
*
191+
* @param newVal
192+
* new value to use for the {@link #cDataTagName} configuration option.
193+
*
194+
* @return The existing configuration will not be modified. A new configuration is returned.
195+
*/
196+
public XMLParserConfiguration withcDataTagName(final String newVal) {
197+
XMLParserConfiguration newConfig = this.clone();
198+
newConfig.cDataTagName = newVal;
199+
return newConfig;
200+
}
201+
202+
/**
203+
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
204+
* should be kept as attribute(<code>false</code>), or they should be converted to
205+
* <code>null</code>(<code>true</code>)
206+
*
207+
* @return The {@link #convertNilAttributeToNull} configuration value.
208+
*/
209+
public boolean isConvertNilAttributeToNull() {
210+
return this.convertNilAttributeToNull;
211+
}
212+
213+
/**
214+
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
215+
* should be kept as attribute(<code>false</code>), or they should be converted to
216+
* <code>null</code>(<code>true</code>)
217+
*
218+
* @param newVal
219+
* new value to use for the {@link #convertNilAttributeToNull} configuration option.
220+
*
221+
* @return The existing configuration will not be modified. A new configuration is returned.
222+
*/
223+
public XMLParserConfiguration withConvertNilAttributeToNull(final boolean newVal) {
224+
XMLParserConfiguration newConfig = this.clone();
225+
newConfig.convertNilAttributeToNull = newVal;
226+
return newConfig;
227+
}
107228
}

src/test/java/org/json/junit/JSONArrayTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ public void testJSONArrayInt() {
11401140
assertNotNull(new JSONArray(5));
11411141
// Check Size -> Even though the capacity of the JSONArray can be specified using a positive
11421142
// integer but the length of JSONArray always reflects upon the items added into it.
1143-
assertEquals(0l, (long)new JSONArray(10).length());
1143+
assertEquals(0l, new JSONArray(10).length());
11441144
try {
11451145
assertNotNull("Should throw an exception", new JSONArray(-1));
11461146
} catch (JSONException e) {

0 commit comments

Comments
 (0)