[ldap-sdk-commits] SF.net SVN: ldap-sdk:[1574] trunk
A Java-based LDAP API
Brought to you by:
dirmgr,
kennethleo
From: <di...@us...> - 2022-10-20 21:55:33
|
Revision: 1574 http://sourceforge.net/p/ldap-sdk/code/1574 Author: dirmgr Date: 2022-10-20 21:55:30 +0000 (Thu, 20 Oct 2022) Log Message: ----------- Allow getting JSON fields case insensitively Added JSONObject methods for retrieving fields by name using case-insensitive matching. By default, JSON field names are treated in a case-sensitive manner, but new methods allow them to be retrieved in a case-insensitive manner. Because a JSON object may have multiple fields with names differing only by case, there are a few options for handling the possibility of conflicts, including returning only the first match found and ignoring subsequent matches, throwing an exception if multiple matches are found, or returning a map containing all matching name-value pairs. Modified Paths: -------------- trunk/docs/release-notes.html trunk/messages/unboundid-ldapsdk-json.properties trunk/src/com/unboundid/util/json/JSONObject.java trunk/tests/unit/src/com/unboundid/util/json/JSONObjectTestCase.java Modified: trunk/docs/release-notes.html =================================================================== --- trunk/docs/release-notes.html 2022-10-19 19:00:36 UTC (rev 1573) +++ trunk/docs/release-notes.html 2022-10-20 21:55:30 UTC (rev 1574) @@ -21,6 +21,18 @@ </li> <li> + Added JSONObject methods for retrieving fields by name using case-insensitive + matching. By default, JSON field names are treated in a case-sensitive manner, + but new methods allow them to be retrieved in a case-insensitive manner. + Because a JSON object may have multiple fields with names differing only by + case, there are a few options for handling the possibility of conflicts, + including returning only the first match found and ignoring subsequent matches, + throwing an exception if multiple matches are found, or returning a map + containing all matching name-value pairs. + <br><br> + </li> + + <li> Updated the set of LDAP-related specifications to include the latest version of draft-schmaus-kitten-sasl-ht. <br><br> Modified: trunk/messages/unboundid-ldapsdk-json.properties =================================================================== --- trunk/messages/unboundid-ldapsdk-json.properties 2022-10-19 19:00:36 UTC (rev 1573) +++ trunk/messages/unboundid-ldapsdk-json.properties 2022-10-20 21:55:30 UTC (rev 1574) @@ -114,6 +114,9 @@ ''{0}'' cannot be parsed as a JSON object because it contains an array \ with unexpected token ''{1}'' at position {2,number,0} when a comma or \ closing square bracket was expected. +ERR_OBJECT_MULTIPLE_FIELDS_WITH_CASE_INSENSITIVE_NAME=The JSON object has \ + multiple fields with name ''{0}'' when treating field names in a \ + case-insensitive manner. ERR_LDAP_SPEC_ERROR_PROCESSING_FIELD=Unable to parse the JSON object as an \ LDAP connection details specification because an error was encountered \ while attempting to process the value of field ''{0}'': {1} Modified: trunk/src/com/unboundid/util/json/JSONObject.java =================================================================== --- trunk/src/com/unboundid/util/json/JSONObject.java 2022-10-19 19:00:36 UTC (rev 1573) +++ trunk/src/com/unboundid/util/json/JSONObject.java 2022-10-20 21:55:30 UTC (rev 1574) @@ -929,6 +929,103 @@ /** + * Retrieves the value for the specified field, treating the field name as + * case-insensitive. If the object has multiple fields with different + * capitalizations of the specified name, then only the first one found will + * be returned and any subsequent fields will be ignored. + * + * @param name The name of the field for which to retrieve the value. It + * will be treated in a case-insensitive manner. + * + * @return The value for the specified field, or {@code null} if the + * requested field is not present in the JSON object. + */ + @Nullable() + public JSONValue getFieldIgnoreCaseIgnoreConflict(@NotNull final String name) + { + final String lowerName = StaticUtils.toLowerCase(name); + for (final Map.Entry<String,JSONValue> e : fields.entrySet()) + { + if (lowerName.equals(StaticUtils.toLowerCase(e.getKey()))) + { + return e.getValue(); + } + } + + return null; + } + + + + /** + * Retrieves the value for the specified field, treating the field name as + * case-insensitive. If the object has multiple fields with different + * capitalizations of the first name, then an exception will be thrown. + * + * @param name The name of the field for which to retrieve the value. It + * will be treated in a case-insensitive manner. + * + * @return The value for the specified field, or {@code null} if the + * requested field is not present in the JSON object. + * + * @throws JSONException If the object has multiple fields with different + * capitalizations of the provided name. + */ + @Nullable() + public JSONValue getFieldIgnoreCaseThrowOnConflict(@NotNull final String name) + throws JSONException + { + JSONValue fieldValue = null; + final String lowerName = StaticUtils.toLowerCase(name); + for (final Map.Entry<String,JSONValue> e : fields.entrySet()) + { + if (lowerName.equals(StaticUtils.toLowerCase(e.getKey()))) + { + if (fieldValue != null) + { + throw new JSONException( + ERR_OBJECT_MULTIPLE_FIELDS_WITH_CASE_INSENSITIVE_NAME.get(name)); + } + + fieldValue = e.getValue(); + } + } + + return fieldValue; + } + + + + /** + * Retrieves a map of all fields with the specified name, treating the name as + * case-insensitive. + * + * @param name The name of the field for which to retrieve the values. It + * will be treated in a case-insensitive manner. + * + * @return A map of all fields with the specified name, or an empty map if + * there are no fields with the specified name. + */ + @NotNull() + public Map<String,JSONValue> getFieldsIgnoreCase(@NotNull final String name) + { + final Map<String,JSONValue> matchingFields = new LinkedHashMap<>(); + final String lowerName = StaticUtils.toLowerCase(name); + for (final Map.Entry<String,JSONValue> e : fields.entrySet()) + { + final String fieldName = e.getKey(); + if (lowerName.equals(StaticUtils.toLowerCase(fieldName))) + { + matchingFields.put(fieldName, e.getValue()); + } + } + + return Collections.unmodifiableMap(matchingFields); + } + + + + /** * Retrieves the value of the specified field as a string. * * @param name The name of the field for which to retrieve the string value. Modified: trunk/tests/unit/src/com/unboundid/util/json/JSONObjectTestCase.java =================================================================== --- trunk/tests/unit/src/com/unboundid/util/json/JSONObjectTestCase.java 2022-10-19 19:00:36 UTC (rev 1573) +++ trunk/tests/unit/src/com/unboundid/util/json/JSONObjectTestCase.java 2022-10-20 21:55:30 UTC (rev 1574) @@ -47,6 +47,7 @@ import org.testng.annotations.Test; import com.unboundid.ldap.sdk.LDAPSDKTestCase; +import com.unboundid.util.StaticUtils; @@ -1513,4 +1514,139 @@ }, }; } + + + + /** + * Tests the behavior when trying to retrieve JSON fields when treating the + * field name in a case-insensitive manner. + * + * @throws Exception If an unexpected problem occurs. + */ + @Test() + public void testGetFieldIgnoreCase() + throws Exception + { + final JSONObject o = new JSONObject( + new JSONField("fieldName", "fieldValue"), + new JSONField("FieldName", "FieldValue"), + new JSONField("fieldname", "fieldvalue"), + new JSONField("FIELDNAME", "FIELDVALUE"), + new JSONField("anotherName", "anotherValue")); + + // Test with the getField method, which uses case-sensitive matching. + assertEquals(o.getField("fieldName"), new JSONString("fieldValue")); + assertEquals(o.getField("FieldName"), new JSONString("FieldValue")); + assertEquals(o.getField("fieldname"), new JSONString("fieldvalue")); + assertEquals(o.getField("FIELDNAME"), new JSONString("FIELDVALUE")); + assertNull(o.getField("FiElDnAmE")); + assertEquals(o.getField("anotherName"), new JSONString("anotherValue")); + assertNull(o.getField("AnotherName")); + assertNull(o.getField("missingName")); + + + // Test with the getFieldIgnoreCaseIgnoreConflict method, which returns the + // first field found. + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("fieldName"), + new JSONString("fieldValue")); + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("FieldName"), + new JSONString("fieldValue")); + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("fieldname"), + new JSONString("fieldValue")); + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("FIELDNAME"), + new JSONString("fieldValue")); + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("FiElDnAmE"), + new JSONString("fieldValue")); + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("anotherName"), + new JSONString("anotherValue")); + assertEquals(o.getFieldIgnoreCaseIgnoreConflict("AnotherName"), + new JSONString("anotherValue")); + assertNull(o.getFieldIgnoreCaseIgnoreConflict("missingName")); + + + // Test with the getFieldIgnoreCaseThrowOnConflict method, which will return + // a field only if there are no conflicts. + try + { + o.getFieldIgnoreCaseThrowOnConflict("fieldName"); + fail("Expected an exception for a fieldName conflict"); + } + catch (final JSONException e) + { + // This was expected. + } + + try + { + o.getFieldIgnoreCaseThrowOnConflict("FieldName"); + fail("Expected an exception for a fieldName conflict"); + } + catch (final JSONException e) + { + // This was expected. + } + + assertEquals(o.getFieldIgnoreCaseThrowOnConflict("anotherName"), + new JSONString("anotherValue")); + assertEquals(o.getFieldIgnoreCaseThrowOnConflict("AnotherName"), + new JSONString("anotherValue")); + assertEquals(o.getFieldIgnoreCaseThrowOnConflict("anothername"), + new JSONString("anotherValue")); + assertEquals(o.getFieldIgnoreCaseThrowOnConflict("ANOTHERNAME"), + new JSONString("anotherValue")); + assertEquals(o.getFieldIgnoreCaseThrowOnConflict("aNoThErNaMe"), + new JSONString("anotherValue")); + + assertNull(o.getFieldIgnoreCaseThrowOnConflict("missingName")); + + + // Tests with the getFieldsIgnoreCase method, which returns a map of + // matching field names and values. + assertEquals(o.getFieldsIgnoreCase("fieldName"), + StaticUtils.mapOf( + "fieldName", new JSONString("fieldValue"), + "FieldName", new JSONString("FieldValue"), + "fieldname", new JSONString("fieldvalue"), + "FIELDNAME", new JSONString("FIELDVALUE"))); + assertEquals(o.getFieldsIgnoreCase("FieldName"), + StaticUtils.mapOf( + "fieldName", new JSONString("fieldValue"), + "FieldName", new JSONString("FieldValue"), + "fieldname", new JSONString("fieldvalue"), + "FIELDNAME", new JSONString("FIELDVALUE"))); + assertEquals(o.getFieldsIgnoreCase("fieldname"), + StaticUtils.mapOf( + "fieldName", new JSONString("fieldValue"), + "FieldName", new JSONString("FieldValue"), + "fieldname", new JSONString("fieldvalue"), + "FIELDNAME", new JSONString("FIELDVALUE"))); + assertEquals(o.getFieldsIgnoreCase("FIELDNAME"), + StaticUtils.mapOf( + "fieldName", new JSONString("fieldValue"), + "FieldName", new JSONString("FieldValue"), + "fieldname", new JSONString("fieldvalue"), + "FIELDNAME", new JSONString("FIELDVALUE"))); + assertEquals(o.getFieldsIgnoreCase("FiElDnAmE"), + StaticUtils.mapOf( + "fieldName", new JSONString("fieldValue"), + "FieldName", new JSONString("FieldValue"), + "fieldname", new JSONString("fieldvalue"), + "FIELDNAME", new JSONString("FIELDVALUE"))); + + assertEquals(o.getFieldsIgnoreCase("anotherName"), + StaticUtils.mapOf( + "anotherName", new JSONString("anotherValue"))); + assertEquals(o.getFieldsIgnoreCase("AnotherName"), + StaticUtils.mapOf( + "anotherName", new JSONString("anotherValue"))); + assertEquals(o.getFieldsIgnoreCase("anothername"), + StaticUtils.mapOf( + "anotherName", new JSONString("anotherValue"))); + assertEquals(o.getFieldsIgnoreCase("ANOTHERNAME"), + StaticUtils.mapOf( + "anotherName", new JSONString("anotherValue"))); + + assertEquals(o.getFieldsIgnoreCase("missingName"), + Collections.emptyMap()); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |