From a2439ec51114ba834d5f450f93ce280c4132e7b9 Mon Sep 17 00:00:00 2001 From: Patrick Simon Date: Tue, 26 May 2020 21:29:27 -0700 Subject: [PATCH 1/4] Use double for metadata numbers --- src/main/java/com/box/sdk/BoxFile.java | 2 +- src/main/java/com/box/sdk/BoxFolder.java | 2 +- src/main/java/com/box/sdk/Metadata.java | 40 ++++++++++ .../BoxFile/UpdateMetadataOnFile200.json | 8 +- .../BoxFolder/UpdateMetadataOnFolder200.json | 8 +- src/test/java/com/box/sdk/BoxFileTest.java | 50 +++++++++---- src/test/java/com/box/sdk/BoxFolderTest.java | 48 ++++++++---- src/test/java/com/box/sdk/MetadataTest.java | 74 ++++++++++++++++++- 8 files changed, 196 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/box/sdk/BoxFile.java b/src/main/java/com/box/sdk/BoxFile.java index 9a05c88e8..f2bea06d4 100644 --- a/src/main/java/com/box/sdk/BoxFile.java +++ b/src/main/java/com/box/sdk/BoxFile.java @@ -1078,7 +1078,7 @@ public Metadata setMetadata(String templateName, String scope, Metadata metadata for (JsonValue value : metadata.getOperations()) { if (value.asObject().get("value").isNumber()) { metadataToUpdate.add(value.asObject().get("path").asString(), - value.asObject().get("value").asFloat()); + value.asObject().get("value").asDouble()); } else if (value.asObject().get("value").isString()) { metadataToUpdate.add(value.asObject().get("path").asString(), value.asObject().get("value").asString()); diff --git a/src/main/java/com/box/sdk/BoxFolder.java b/src/main/java/com/box/sdk/BoxFolder.java index ace8505b5..151e5ff67 100644 --- a/src/main/java/com/box/sdk/BoxFolder.java +++ b/src/main/java/com/box/sdk/BoxFolder.java @@ -876,7 +876,7 @@ public Metadata setMetadata(String templateName, String scope, Metadata metadata for (JsonValue value : metadata.getOperations()) { if (value.asObject().get("value").isNumber()) { metadataToUpdate.add(value.asObject().get("path").asString(), - value.asObject().get("value").asFloat()); + value.asObject().get("value").asDouble()); } else if (value.asObject().get("value").isString()) { metadataToUpdate.add(value.asObject().get("path").asString(), value.asObject().get("value").asString()); diff --git a/src/main/java/com/box/sdk/Metadata.java b/src/main/java/com/box/sdk/Metadata.java index ef8403d1a..b34e73405 100644 --- a/src/main/java/com/box/sdk/Metadata.java +++ b/src/main/java/com/box/sdk/Metadata.java @@ -185,6 +185,18 @@ public Metadata add(String path, float value) { return this; } + /** + * Adds a new metadata value. + * @param path the path that designates the key. Must be prefixed with a "/". + * @param value the value. + * @return this metadata object. + */ + public Metadata add(String path, double value) { + this.values.add(this.pathToProperty(path), value); + this.addOp("add", path, value); + return this; + } + /** * Adds a new metadata value of array type. * @param path the path to the field. @@ -225,6 +237,18 @@ public Metadata replace(String path, float value) { return this; } + /** + * Replaces an existing metadata value. + * @param path the path that designates the key. Must be prefixed with a "/". + * @param value the value. + * @return this metadata object. + */ + public Metadata replace(String path, double value) { + this.values.set(this.pathToProperty(path), value); + this.addOp("replace", path, value); + return this; + } + /** * Replaces an existing metadata value of array type. * @param path the path that designates the key. Must be prefixed with a "/". @@ -452,6 +476,22 @@ private void addOp(String op, String path, float value) { .add("value", value)); } + /** + * Adds a patch operation. + * @param op the operation type. Must be add, replace, remove, or test. + * @param path the path that designates the key. Must be prefixed with a "/". + * @param value the value to be set. + */ + private void addOp(String op, String path, double value) { + if (this.operations == null) { + this.operations = new JsonArray(); + } + + this.operations.add(new JsonObject() + .add("op", op) + .add("path", path) + .add("value", value)); + } /** * Adds a new patch operation for array values. * @param op the operation type. Must be add, replace, remove, or test. diff --git a/src/test/Fixtures/BoxFile/UpdateMetadataOnFile200.json b/src/test/Fixtures/BoxFile/UpdateMetadataOnFile200.json index 309f0801b..83c681975 100644 --- a/src/test/Fixtures/BoxFile/UpdateMetadataOnFile200.json +++ b/src/test/Fixtures/BoxFile/UpdateMetadataOnFile200.json @@ -1,7 +1,9 @@ { - "test":"text", - "test2":2, - "test3":["first", "second", "third"], + "test1":"text", + "test2":["first", "second", "third"], + "test3":2, + "test4":1.23456794E9, + "test5":2.33333333333333344E17, "$type":"account-e68798f0-347f-4882-a1ae-f65b032780ac", "$parent":"file_12345", "$id":"0db91053-c355-4fc7-b69c-9d511974bbc4", diff --git a/src/test/Fixtures/BoxFolder/UpdateMetadataOnFolder200.json b/src/test/Fixtures/BoxFolder/UpdateMetadataOnFolder200.json index f2808ecb6..667dad0c9 100644 --- a/src/test/Fixtures/BoxFolder/UpdateMetadataOnFolder200.json +++ b/src/test/Fixtures/BoxFolder/UpdateMetadataOnFolder200.json @@ -1,7 +1,9 @@ { - "test":"text", - "test2":2, - "test3":["first", "second", "third"], + "test1":"text", + "test2":["first", "second", "third"], + "test3":2, + "test4":1.23456794E9, + "test5":2.33333333333333344E17, "$type":"account-e68798f0-347f-4882-a1ae-f65b032780ac", "$parent":"folder_12345", "$id":"0db91053-c355-4fc7-b69c-9d511974bbc4", diff --git a/src/test/java/com/box/sdk/BoxFileTest.java b/src/test/java/com/box/sdk/BoxFileTest.java index 648e59df7..7a427babb 100644 --- a/src/test/java/com/box/sdk/BoxFileTest.java +++ b/src/test/java/com/box/sdk/BoxFileTest.java @@ -1832,38 +1832,54 @@ public void testSetMetadataReturnsCorrectly() throws IOException { String putResult = ""; final String fileID = "12345"; final String metadataURL = "/files/" + fileID + "/metadata/enterprise/testtemplate"; - ArrayList values = new ArrayList(); - values.add("first"); - values.add("second"); - values.add("third"); + ArrayList secondValueArray = new ArrayList(); + secondValueArray.add("first"); + secondValueArray.add("second"); + secondValueArray.add("third"); postResult = TestConfig.getFixture("/BoxException/BoxResponseException409"); putResult = TestConfig.getFixture("/BoxFile/UpdateMetadataOnFile200"); - JsonArray array = new JsonArray() + final String firstValue = "text"; + JsonArray secondValueJson = new JsonArray() .add("first") .add("second") .add("third"); + final int thirdValue = 2; + final float fourthValue = 1234567890f; + final double fifthValue = 233333333333333340.0; JsonObject firstAttribute = new JsonObject() .add("op", "add") - .add("path", "/test") - .add("value", "text"); + .add("path", "/test1") + .add("value", firstValue); JsonObject secondAttribute = new JsonObject() .add("op", "add") .add("path", "/test2") - .add("value", 2); + .add("value", secondValueJson); JsonObject thirdAttribute = new JsonObject() .add("op", "add") .add("path", "/test3") - .add("value", array); + .add("value", thirdValue); + + JsonObject fourthAttribute = new JsonObject() + .add("op", "add") + .add("path", "/test4") + .add("value", fourthValue); + + JsonObject fifthAttribute = new JsonObject() + .add("op", "add") + .add("path", "/test5") + .add("value", fifthValue); JsonArray jsonArray = new JsonArray() .add(firstAttribute) .add(secondAttribute) - .add(thirdAttribute); + .add(thirdAttribute) + .add(fourthAttribute) + .add(fifthAttribute); WIRE_MOCK_CLASS_RULE.stubFor(WireMock.post(WireMock.urlPathEqualTo(metadataURL)) .willReturn(WireMock.aResponse() @@ -1882,16 +1898,22 @@ public void testSetMetadataReturnsCorrectly() throws IOException { BoxFile file = new BoxFile(this.api, "12345"); Metadata metadata = new Metadata() - .add("/test", "text") - .add("/test2", 2) - .add("/test3", values); + .add("/test1", firstValue) + .add("/test2", secondValueArray) + .add("/test3", thirdValue) + .add("/test4", fourthValue) + .add("/test5", fifthValue); Metadata metadataValues = file.setMetadata("testtemplate", "enterprise", metadata); Assert.assertEquals("file_12345", metadataValues.getParentID()); Assert.assertEquals("testtemplate", metadataValues.getTemplateName()); Assert.assertEquals("enterprise_11111", metadataValues.getScope()); - Assert.assertEquals("text", metadataValues.getString("/test")); + Assert.assertEquals(firstValue, metadataValues.getString("/test1")); + Assert.assertEquals(secondValueJson, metadataValues.getValue("/test2")); + Assert.assertEquals((double) thirdValue, metadataValues.getFloat("/test3"), 0); + Assert.assertEquals((double) fourthValue, metadataValues.getFloat("/test4"), 4); + Assert.assertEquals((double) fifthValue, metadataValues.getFloat("/test5"), 0); } @Test diff --git a/src/test/java/com/box/sdk/BoxFolderTest.java b/src/test/java/com/box/sdk/BoxFolderTest.java index cee765962..d605149d1 100644 --- a/src/test/java/com/box/sdk/BoxFolderTest.java +++ b/src/test/java/com/box/sdk/BoxFolderTest.java @@ -1841,38 +1841,54 @@ public void testSetMetadataReturnsCorrectly() throws IOException { String putResult = ""; final String folderID = "12345"; final String metadataURL = "/folders/" + folderID + "/metadata/enterprise/testtemplate"; - ArrayList values = new ArrayList(); - values.add("first"); - values.add("second"); - values.add("third"); + ArrayList secondValueArray = new ArrayList(); + secondValueArray.add("first"); + secondValueArray.add("second"); + secondValueArray.add("third"); postResult = TestConfig.getFixture("/BoxException/BoxResponseException409"); putResult = TestConfig.getFixture("/BoxFolder/UpdateMetadataOnFolder200"); - JsonArray array = new JsonArray() + final String firstValue = "text"; + JsonArray secondValueJson = new JsonArray() .add("first") .add("second") .add("third"); + final int thirdValue = 2; + final float fourthValue = 1234567890f; + final double fifthValue = 233333333333333340.0; JsonObject firstAttribute = new JsonObject() .add("op", "add") - .add("path", "/test") + .add("path", "/test1") .add("value", "text"); JsonObject secondAttribute = new JsonObject() .add("op", "add") .add("path", "/test2") - .add("value", 2); + .add("value", secondValueJson); JsonObject thirdAttribute = new JsonObject() .add("op", "add") .add("path", "/test3") - .add("value", array); + .add("value", thirdValue); + + JsonObject fourthAttribute = new JsonObject() + .add("op", "add") + .add("path", "/test4") + .add("value", fourthValue); + + JsonObject fifthAttribute = new JsonObject() + .add("op", "add") + .add("path", "/test5") + .add("value", fifthValue); JsonArray jsonArray = new JsonArray() .add(firstAttribute) .add(secondAttribute) - .add(thirdAttribute); + .add(thirdAttribute) + .add(fourthAttribute) + .add(fifthAttribute); WIRE_MOCK_CLASS_RULE.stubFor(WireMock.post(WireMock.urlPathEqualTo(metadataURL)) .willReturn(WireMock.aResponse() @@ -1891,16 +1907,22 @@ public void testSetMetadataReturnsCorrectly() throws IOException { BoxFolder folder = new BoxFolder(this.api, "12345"); Metadata metadata = new Metadata() - .add("/test", "text") - .add("/test2", 2) - .add("/test3", values); + .add("/test1", firstValue) + .add("/test2", secondValueArray) + .add("/test3", thirdValue) + .add("/test4", fourthValue) + .add("/test5", fifthValue); Metadata metadataValues = folder.setMetadata("testtemplate", "enterprise", metadata); Assert.assertEquals("folder_12345", metadataValues.getParentID()); Assert.assertEquals("testtemplate", metadataValues.getTemplateName()); Assert.assertEquals("enterprise_11111", metadataValues.getScope()); - Assert.assertEquals("text", metadataValues.getString("/test")); + Assert.assertEquals(firstValue, metadataValues.getString("/test1")); + Assert.assertEquals(secondValueJson, metadataValues.getValue("/test2")); + Assert.assertEquals((double) thirdValue, metadataValues.getFloat("/test3"), 0); + Assert.assertEquals((double) fourthValue, metadataValues.getFloat("/test4"), 4); + Assert.assertEquals((double) fifthValue, metadataValues.getFloat("/test5"), 0); } @Test(expected = BoxDeserializationException.class) diff --git a/src/test/java/com/box/sdk/MetadataTest.java b/src/test/java/com/box/sdk/MetadataTest.java index 23f2485cb..f9f82278a 100644 --- a/src/test/java/com/box/sdk/MetadataTest.java +++ b/src/test/java/com/box/sdk/MetadataTest.java @@ -194,6 +194,78 @@ public void testMetadataDate(String dateString, Long dateLong) { } } + @Test + @Category(IntegrationTest.class) + public void testMetadataPrecisionFloat() { + final float expectedValueFloat = 1234567890f; + BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken()); + + long timestamp = Calendar.getInstance().getTimeInMillis(); + String templateKey = "precision" + timestamp; + String fieldKey = "testPrecision"; + + List fields = new ArrayList(); + MetadataTemplate.Field valueField = new MetadataTemplate.Field(); + valueField.setKey(fieldKey); + valueField.setType("float"); + valueField.setDisplayName("Value Field"); + fields.add(valueField); + + MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise", + templateKey, "Precision " + timestamp, false, fields); + + Assert.assertEquals("float", template.getFields().get(0).getType()); + + // Add template to item + Metadata mdValues = new Metadata(); + mdValues.add("/" + fieldKey, expectedValueFloat); + BoxFolder.Info folder = BoxFolder.getRootFolder(api).createFolder("Metadata Precision Test " + timestamp); + Metadata actualMD = folder.getResource().createMetadata(templateKey, mdValues); + + Assert.assertEquals(templateKey, actualMD.getTemplateName()); + + final double actualValueDouble = actualMD.getFloat("/" + fieldKey); + + // Instead of "hard-coding" the delta to 4.0, let's calculate it and then validate it + final double delta = actualValueDouble - (double) expectedValueFloat; + Assert.assertEquals(4.0, delta, 0); + + // Now that we know delta is 4.0, when can use it for this validation + Assert.assertEquals((double) expectedValueFloat, actualValueDouble, delta); + } + + @Test + @Category(IntegrationTest.class) + public void testMetadataPrecisionDouble() { + final double valueDouble = 233333333333333340.0; + BoxAPIConnection api = new BoxAPIConnection(TestConfig.getAccessToken()); + + long timestamp = Calendar.getInstance().getTimeInMillis(); + String templateKey = "precision" + timestamp; + String fieldKey = "testPrecision"; + + List fields = new ArrayList(); + MetadataTemplate.Field valueField = new MetadataTemplate.Field(); + valueField.setKey(fieldKey); + valueField.setType("float"); + valueField.setDisplayName("Value Field"); + fields.add(valueField); + + MetadataTemplate template = MetadataTemplate.createMetadataTemplate(api, "enterprise", + templateKey, "Precision " + timestamp, false, fields); + + Assert.assertEquals("float", template.getFields().get(0).getType()); + + // Add template to item + Metadata mdValues = new Metadata(); + mdValues.add("/" + fieldKey, valueDouble); + BoxFolder.Info folder = BoxFolder.getRootFolder(api).createFolder("Metadata Precision Test " + timestamp); + Metadata actualMD = folder.getResource().createMetadata(templateKey, mdValues); + + Assert.assertEquals(templateKey, actualMD.getTemplateName()); + Assert.assertEquals(valueDouble, actualMD.getFloat("/" + fieldKey), 0); + } + @Test @Category(IntegrationTest.class) public void testMultiSelectMetadataCRUD() { @@ -384,7 +456,7 @@ public void getValues(String dateString, Long dateLong) { Assert.assertEquals(stringValue, md.getString("/documentType")); Assert.assertEquals(intValue, md.getValue("/capacity").asInt()); - Assert.assertEquals((float) intValue, md.getFloat("/capacity"), 0); + Assert.assertEquals((double) intValue, md.getFloat("/capacity"), 0); try { Assert.assertEquals(dateValue, md.getDate("/deadline")); From cc5fadea4aba154059e1fba67c0a7d21b9e02653 Mon Sep 17 00:00:00 2001 From: Patrick Simon Date: Thu, 4 Jun 2020 16:26:28 -0700 Subject: [PATCH 2/4] Deprecate get and set for float values --- src/main/java/com/box/sdk/Metadata.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/box/sdk/Metadata.java b/src/main/java/com/box/sdk/Metadata.java index b34e73405..35e80aa54 100644 --- a/src/main/java/com/box/sdk/Metadata.java +++ b/src/main/java/com/box/sdk/Metadata.java @@ -178,7 +178,10 @@ public Metadata add(String path, String value) { * @param path the path that designates the key. Must be prefixed with a "/". * @param value the value. * @return this metadata object. + * @deprecated add(String, double) is preferred as it avoids errors when converting a + * float to the underlying data type used by Metadata (double) */ + @Deprecated public Metadata add(String path, float value) { this.values.add(this.pathToProperty(path), value); this.addOp("add", path, value); @@ -340,15 +343,26 @@ public String getString(String path) { } /** - * Get a value from a float metadata field. + * Get a value from a double metadata field. * @param path the key path in the metadata object. Must be prefixed with a "/". - * @return the metadata value as a floating point number. + * @return the metadata value as a double floating point number. + * @deprecated getDouble() is preferred as it more clearly describes the return type (double) */ + @Deprecated public double getFloat(String path) { // @NOTE(mwiller) 2018-02-05: JS number are all 64-bit floating point, so double is the correct type to use here return this.getValue(path).asDouble(); } + /** + * Get a value from a double metadata field. + * @param path the key path in the metadata object. Must be prefixed with a "/". + * @return the metadata value as a floating point number. + */ + public double getDouble(String path) { + return this.getValue(path).asDouble(); + } + /** * Get a value from a date metadata field. * @param path the key path in the metadata object. Must be prefixed with a "/". From 03fad7a66f23bc9efb2b9a00669b16fdda75b2a2 Mon Sep 17 00:00:00 2001 From: Patrick Simon Date: Thu, 4 Jun 2020 16:46:25 -0700 Subject: [PATCH 3/4] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f2dbea02..8ecddf3b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix issue for `getIsExternallyOwned()` for Files and Folders ([#808](https://github.com/box/box-java-sdk/pull/808)) - Add support for the classification field for Files and Folders ([#809](https://github.com/box/box-java-sdk/pull/809)) - Add ability to set the filename when uploading a new version of a file ([#810](https://github.com/box/box-java-sdk/pull/810)) +- Deprecate the use of float for Metadata values, in preference of the underlying value (double) ([#811](https://github.com/box/box-java-sdk/pull/811)) ## 2.47.0 [2020-04-23] - Add support for the uploader display name field for Files and File Versions ([#791](https://github.com/box/box-java-sdk/pull/791)) From 2ce9f40d0969b3d1d7f875f01830d13db2e66ec8 Mon Sep 17 00:00:00 2001 From: Patrick Simon Date: Thu, 4 Jun 2020 16:48:16 -0700 Subject: [PATCH 4/4] Update CHANGELOG --- CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ecddf3b9..d70504822 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,11 @@ # Changelog -## Next Release -- Add support for setting Tracking Codes ([#766](https://github.com/box/box-java-sdk/pull/766)) -- Fix issue for `getIsExternallyOwned()` for Files and Folders ([#808](https://github.com/box/box-java-sdk/pull/808)) -- Add support for the classification field for Files and Folders ([#809](https://github.com/box/box-java-sdk/pull/809)) -- Add ability to set the filename when uploading a new version of a file ([#810](https://github.com/box/box-java-sdk/pull/810)) -- Deprecate the use of float for Metadata values, in preference of the underlying value (double) ([#811](https://github.com/box/box-java-sdk/pull/811)) +## Next Release [MINOR] +- [MINOR] Add support for setting Tracking Codes ([#766](https://github.com/box/box-java-sdk/pull/766)) +- [PATCH] Fix issue for `getIsExternallyOwned()` for Files and Folders ([#808](https://github.com/box/box-java-sdk/pull/808)) +- [MINOR] Add support for the classification field for Files and Folders ([#809](https://github.com/box/box-java-sdk/pull/809)) +- [MINOR] Add ability to set the filename when uploading a new version of a file ([#810](https://github.com/box/box-java-sdk/pull/810)) +- [MINOR] Deprecate the use of float for Metadata values, in preference of the underlying value (double) ([#811](https://github.com/box/box-java-sdk/pull/811)) ## 2.47.0 [2020-04-23] - Add support for the uploader display name field for Files and File Versions ([#791](https://github.com/box/box-java-sdk/pull/791))