From 98c3ca08ed207e929fdca8dfdfcff774540c4250 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 14 Jul 2017 10:56:32 -0400 Subject: [PATCH 001/243] MPH supports additional validation and throws a 400 error --- .../imsweb/seerapi/client/mph/MphOutput.java | 21 +++++++++---------- .../imsweb/seerapi/client/mph/MphTest.java | 17 +++++++++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java index 3d4f8a3..fdcf615 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java @@ -6,16 +6,6 @@ public class MphOutput { - // The possible results of determining if two tumors are single or multiple primaries. - public enum Result { - // indicates the two tumors are the same primary - SINGLE_PRIMARY, - // indicates the two tumors are different primaries - MULTIPLE_PRIMARIES, - // indicates there is not enough information to make a proper determination - QUESTIONABLE - } - @JsonProperty("result") private Result _result; @JsonProperty("reason") @@ -26,7 +16,6 @@ public enum Result { private String _groupId; @JsonProperty("step") private String _step; - public MphOutput() { } @@ -69,4 +58,14 @@ public String getStep() { public void setStep(String step) { _step = step; } + + // The possible results of determining if two tumors are single or multiple primaries. + public enum Result { + // indicates the two tumors are the same primary + SINGLE_PRIMARY, + // indicates the two tumors are different primaries + MULTIPLE_PRIMARIES, + // indicates there is not enough information to make a proper determination + QUESTIONABLE + } } diff --git a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java index 8b4f9a6..79a873d 100644 --- a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java @@ -143,4 +143,21 @@ public void testLenientMode() throws IOException { assertEquals("M13", result.getStep()); } + @Test(expected = BadRequestException.class) + public void testInvalidInput() throws IOException { + MphInput i1 = new MphInput(); + MphInput i2 = new MphInput(); + + // invalid primary site + i1.setPrimarySite("C080"); + i2.setPrimarySite("D080"); + i1.setHistologyIcdO3("8000"); + i1.setBehaviorIcdO3("3"); + i2.setHistologyIcdO3("8100"); + i2.setBehaviorIcdO3("3"); + i1.setDateOfDiagnosisYear("2015"); + i2.setDateOfDiagnosisYear("2015"); + _MPH.mph(new MphInputPair(i1, i2)).execute().body(); + } + } \ No newline at end of file From 9efe2c1e636abc0b953f865223c4e0bebd3bbfdc Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 18 Aug 2017 14:16:26 -0400 Subject: [PATCH 002/243] Fixed error response and cleaned up failing tests --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 54706 -> 54708 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- .../imsweb/seerapi/client/ErrorResponse.java | 58 +++++++++++++----- .../imsweb/seerapi/client/mph/MphTest.java | 6 +- .../imsweb/seerapi/client/ndc/NdcTest.java | 10 +-- .../client/siterecode/SiteRecodeTest.java | 6 +- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/build.gradle b/build.gradle index e30142f..76fd6cd 100644 --- a/build.gradle +++ b/build.gradle @@ -65,7 +65,7 @@ findbugs { // Gradle wrapper, this allows to build the project without having to install Gradle! task wrapper(type: Wrapper) { - gradleVersion = '4.0' + gradleVersion = '4.1' } modifyPom { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 60786f81a31e54e85e84f0fd8d7e20266a5e6b46..7a3265ee94c0ab25cf079ac8ccdf87f41d455d42 100644 GIT binary patch delta 759 zcmYk4T}V@57{|~1X!ArX*HOmsI?)CJ`^kZHjL81i=d03(FYY) zx<4XXB1Lxw<*17;QfqVO=H}PDD6hN`B`Ecx+j{pp#RG@){C>~>dEaw5uYVxr<3LJB z^|qSMMVGzPRxdB*ueGhVF{wix^xFcdlH`!E7C4ZdDtX*#vTIbM ze0>&Af(@(}3&DMC2!_!bwv5+>MqD1%$iz@onF}{l@r7f(E`h!=8P9YwGC~?1OxrLG zp~LiY`v!duS!sFaIyvb_UZTQtU{8gj=kJ%ic2)3z z5p@+A7!E1$eOD>1lB;5oEvwp^EvVuR6V!1l-F1p}-#PVY8P`a03$(jS@M}UrY2DT_ zwJzCAN6MTL)nS#6o)W4#e2kUiL--8QIShtPutaKDCN4!htQG!dFF=GR?o6qa`(j;n>o7D` zOR{eh-9AOEb9`DQW7npBK7EJ`-AT;$&1m$uCrNtPdlNGnO}!E-y)TRJt6+XcrLumm z90HxQDmA^~XvU*iD=D9#kDKvx*2iu z5Sm+V9Ylpc7t*{=oJPicsknuEQYPx>6_Q1WfeciMGG>^qk)n2B;TV-B$5aX~Eu5sG zl$cZD!@?oj%G!16#pCqV71pS4oeGT&{7-^vx_-ATdd_fyB+cHp@YMB4h@<=DWr2U zn}=$rkzc`FrQfrAVL>ns1TIiz4d2ihI8FQOxcnHXB;hib`N0a(Ho)3YfM-EPY=Spv z7f0|jcttz_*V1hYHsMWcF1{?CpzC+J{2MW$CM45bGq*jVBjmZyWInb+Mbz2KWI1Y= z70Pa7(u}KZT1+vkZRbhV?K%9f4u@qr-@!uz9R;}aS&z42S^R;ya3dLdIB>0;qO?8~ z^;ICm_~wc%vZ=1tQ~C=Qw4i^rj0_$w-5w1un>ZZbtnDEV%Z4-A0SYa@;$>4`8(2Ms z3P!ojU31WlF?5WX(YwYvItg8bb#zkV1%FS+cXSilNF9BjfqK@C-X%S}5m}r?IC7KV k!-Q`i-0K=s^fgDHa2gwhfi2_zkudcQo$FSq+#e1812!-cN&o-= diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44c1e4a..521fd9a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 16 16:42:51 EDT 2017 +#Fri Aug 18 11:34:44 EDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java b/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java index 68c6bf7..8c38e17 100644 --- a/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java +++ b/src/main/java/com/imsweb/seerapi/client/ErrorResponse.java @@ -4,30 +4,54 @@ public class ErrorResponse { - @JsonProperty("code") - protected Integer _id; + @JsonProperty("timestamp") + private String _timestamp; + @JsonProperty("status") + private Integer _status; + @JsonProperty("error") + private String _error; @JsonProperty("message") - protected String _message; + private String _message; + @JsonProperty("path") + private String _path; - /** - * Default constructor - */ - public ErrorResponse() { + public String getTimestamp() { + return _timestamp; } - /** - * Return the error identifier - * @return an error identifier - */ - public Integer getId() { - return _id; + public void setTimestamp(String timestamp) { + _timestamp = timestamp; + } + + public Integer getStatus() { + return _status; + } + + public void setStatus(Integer status) { + _status = status; + } + + public String getError() { + return _error; + } + + public void setError(String error) { + _error = error; } - /** - * Return the error message - * @return an error message - */ public String getMessage() { return _message; } + + public void setMessage(String message) { + _message = message; + } + + public String getPath() { + return _path; + } + + public void setPath(String path) { + _path = path; + } } diff --git a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java index 79a873d..57b5e0c 100644 --- a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java @@ -26,7 +26,7 @@ public void testMissingAllInput() throws IOException { _MPH.mph(new MphInputPair()).execute(); } - @Test + @Test(expected = BadRequestException.class) public void testMissingSite() throws IOException { MphInput input1 = new MphInput(); // site is missing @@ -43,10 +43,6 @@ public void testMissingSite() throws IOException { input2.setLaterality("1"); MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); - assertEquals(MphOutput.Result.QUESTIONABLE, result.getResult()); - assertEquals( - "Unable to identify cancer group for first set of parameters. Valid primary site (C000-C999 excluding C809), histology (8000-9999), behavior (0-3, 6) and diagnosis year are required.", - result.getReason()); } @Test diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index a03106a..6feabcc 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -56,11 +56,9 @@ public void testNdcByCode() throws IOException { assertEquals(Arrays.asList("Norepinephrine Reuptake Inhibitor [EPC]", "Norepinephrine Uptake Inhibitors [MoA]"), product.getPharmClass()); - assertEquals(2, product.getPackages().size()); - assertEquals("07", product.getPackages().get(0).getCode()); - assertEquals("7 CAPSULE in 1 BOTTLE (0002-3227-07)", product.getPackages().get(0).getDescription()); - assertEquals("30", product.getPackages().get(1).getCode()); - assertEquals("30 CAPSULE in 1 BOTTLE (0002-3227-30)", product.getPackages().get(1).getDescription()); + assertEquals(1, product.getPackages().size()); + assertEquals("30", product.getPackages().get(0).getCode()); + assertEquals("30 CAPSULE in 1 BOTTLE (0002-3227-30)", product.getPackages().get(0).getDescription()); assertNotNull(product.getDateAdded()); assertNotNull(product.getDateModified()); @@ -78,8 +76,6 @@ public void testNdcSearch() throws IOException { Integer totalIncludingRemoved = Integer.valueOf(response.headers().get("X-Total-Count")); assertTrue(totalIncludingRemoved > 100000); - assertEquals(3, response.headers().values("Link").size()); - List products = response.body(); assertEquals(25, products.size()); diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index a056702..652273c 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -28,7 +28,7 @@ public static void setup() { } @Test(expected = BadRequestException.class) - public void testBadRequestExceptiion() throws IOException { + public void testBadRequestException() throws IOException { _SITE_RECODE.siteGroup("C379", null).execute(); } @@ -45,9 +45,7 @@ public void testExceptionMessages() throws IOException { // the API call works out to: // https://api.seer.cancer.gov/rest/recode/sitegroup?site=C379 - // and the full message returned should be - // {"code":400,"message":"Site and histology must be supplied"} - assertEquals("Site and histology must be supplied", message); + assertEquals("Required String parameter 'hist' is not present", message); } @Test From 1ecdcde0d5829b167635061ad30786c8dcf985d7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 18 Aug 2017 14:22:44 -0400 Subject: [PATCH 003/243] Preparing for 3.6 release --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 76fd6cd..2243ddf 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.5' +version = '3.6' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From a4e4efecff8b3058547667a101505be253ca20df Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 18 Aug 2017 14:23:12 -0400 Subject: [PATCH 004/243] Preparing for 3.6 release --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e73167c..c402789 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.5 + 3.6 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.5' +compile 'com.imsweb:seerapi-client-java:3.6' ``` ## Usage From a9461af81a77a3c7638cfaaa59e61bbce5f53a44 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 18 Aug 2017 14:32:13 -0400 Subject: [PATCH 005/243] Updated Retrofit dependency --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 2243ddf..983f1ed 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.6' +version = '3.7-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -28,8 +28,8 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.2.0' - compile 'com.squareup.retrofit2:converter-jackson:2.1.0' + compile 'com.squareup.retrofit2:retrofit:2.3.0' + compile 'com.squareup.retrofit2:converter-jackson:2.3.0' testCompile 'junit:junit:4.11' } From 7da267b55149627655b3d87e1702870804430aa1 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 3 Jan 2018 12:17:38 -0500 Subject: [PATCH 006/243] Added support for start and end marketing date to NDC package Also updated build.gradle to prepare for release. --- README.md | 4 ++-- build.gradle | 2 +- .../imsweb/seerapi/client/ndc/NdcPackage.java | 20 +++++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c402789..2844af8 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.6 + 3.7 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.6' +compile 'com.imsweb:seerapi-client-java:3.7' ``` ## Usage diff --git a/build.gradle b/build.gradle index 983f1ed..8774ce2 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.7-SNAPSHOT' +version = '3.7' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java index 2f8673d..3acf01e 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java @@ -13,6 +13,10 @@ public class NdcPackage { private String _code; @JsonProperty("description") private String _description; + @JsonProperty("start_marketing_date") + private String _startMarketingDate; + @JsonProperty("end_marketing_date") + private String _endMarketingDate; public String getCode() { return _code; @@ -29,4 +33,20 @@ public String getDescription() { public void setDescription(String description) { _description = description; } + + public String getStartMarketingDate() { + return _startMarketingDate; + } + + public void setStartMarketingDate(String startMarketingDate) { + _startMarketingDate = startMarketingDate; + } + + public String getEndMarketingDate() { + return _endMarketingDate; + } + + public void setEndMarketingDate(String endMarketingDate) { + _endMarketingDate = endMarketingDate; + } } From cf310274b472cb86ddd2c8af1a1f317a8f20ba74 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 3 Jan 2018 12:21:06 -0500 Subject: [PATCH 007/243] Fixed failing unit test --- src/test/java/com/imsweb/seerapi/client/rx/RxTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index ae73f2a..b33a499 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -107,8 +107,8 @@ public void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(8, results.getTotal().longValue()); - assertEquals(8, results.getResults().size()); + assertEquals(9, results.getTotal().longValue()); + assertEquals(9, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); From 998b68fca33ee899da42703abff7289db91b9dc2 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 16 Mar 2018 09:29:42 -0400 Subject: [PATCH 008/243] Test cleanup. --- build.gradle | 3 +- .../seerapi/client/staging/StagingTest.java | 138 +++++++++--------- 2 files changed, 71 insertions(+), 70 deletions(-) diff --git a/build.gradle b/build.gradle index 8774ce2..153a9f9 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.7' +version = '3.8' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -32,6 +32,7 @@ dependencies { compile 'com.squareup.retrofit2:converter-jackson:2.3.0' testCompile 'junit:junit:4.11' + testCompile 'org.assertj:assertj-core:3.9.0' } jar { diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 87d80fa..8698560 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -12,8 +12,7 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.staging.cs.CsSchemaLookup; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; public class StagingTest { @@ -31,90 +30,89 @@ public static void setup() { public void testGetAlgorithms() throws IOException { List algorithms = _STAGING.algorithms().execute().body(); - assertTrue(algorithms.size() > 0); + assertThat(algorithms).isNotEmpty().extracting("algorithm").contains("cs", "tnm", "eod_public"); } @Test public void testGetAlgorithmVersions() throws IOException { List versions = _STAGING.versions(_ALGORITHM).execute().body(); - assertTrue(versions.size() > 0); + assertThat(versions).isNotEmpty(); } @Test public void testListSchemas() throws IOException { List schemaInfos = _STAGING.schemas(_ALGORITHM, _VERSION).execute().body(); - assertTrue(schemaInfos.size() > 0); + assertThat(schemaInfos).isNotEmpty(); schemaInfos = _STAGING.schemas(_ALGORITHM, _VERSION, "skin").execute().body(); - assertTrue(schemaInfos.size() > 0); + assertThat(schemaInfos).isNotEmpty(); } @Test public void testSchemaLookup() throws IOException { // first test simple lookup that returns a single schema with site/hist only List schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new CsSchemaLookup("C509", "8000").getInputs()).execute().body(); - assertEquals(1, schemas.size()); - assertEquals("breast", schemas.get(0).getId()); + assertThat(schemas).hasSize(1).extracting("id").contains("breast"); // now test just site SchemaLookup data = new SchemaLookup(); data.setInput(StagingData.PRIMARY_SITE_KEY, "C111"); - assertEquals(7, _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body().size()); + assertThat(_STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body()).hasSize(7); // add histology data.setInput(StagingData.HISTOLOGY_KEY, "8000"); - assertEquals(2, _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body().size()); + assertThat(_STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body()).hasSize(2); // add discriminator data.setInput("ssf25", "010"); schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body(); - assertEquals(1, schemas.size()); - assertEquals("nasopharynx", schemas.get(0).getId()); + assertThat(schemas).hasSize(1).extracting("id").contains("nasopharynx"); // test with the CsStaging class schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new CsSchemaLookup("C111", "8000", "010").getInputs()).execute().body(); - assertEquals(1, schemas.size()); - assertEquals("nasopharynx", schemas.get(0).getId()); + assertThat(schemas).hasSize(1).extracting("id").contains("nasopharynx"); } @Test public void testSchemaById() throws IOException { StagingSchema schema = _STAGING.schemaById(_ALGORITHM, _VERSION, "brain").execute().body(); - assertEquals("cs", schema.getAlgorithm()); - assertEquals("02.05.50", schema.getVersion()); - assertEquals("brain", schema.getId()); + assertThat(schema).isNotNull(); + assertThat(schema.getAlgorithm()).isEqualTo("cs"); + assertThat(schema.getVersion()).isEqualTo("02.05.50"); + assertThat(schema.getId()).isEqualTo("brain"); } @Test public void testSchemaInvolvedTables() throws IOException { List tables = _STAGING.involvedTables(_ALGORITHM, _VERSION, "brain").execute().body(); - assertTrue(tables.size() > 0); + assertThat(tables).isNotEmpty(); } @Test public void testListTables() throws IOException { List tables = _STAGING.tables(_ALGORITHM, _VERSION, "ssf1").execute().body(); - assertTrue(tables.size() > 0); + assertThat(tables).isNotEmpty(); } @Test public void testTableById() throws IOException { StagingTable table = _STAGING.tableById(_ALGORITHM, _VERSION, "primary_site").execute().body(); - assertEquals("cs", table.getAlgorithm()); - assertEquals("02.05.50", table.getVersion()); - assertEquals("primary_site", table.getId()); + assertThat(table).isNotNull(); + assertThat(table.getAlgorithm()).isEqualTo("cs"); + assertThat(table.getVersion()).isEqualTo("02.05.50"); + assertThat(table.getId()).isEqualTo("primary_site"); } @Test public void testTableInvoledSchemas() throws IOException { List schemas = _STAGING.involvedSchemas(_ALGORITHM, _VERSION, "extension_baa").execute().body(); - assertTrue(schemas.size() > 0); + assertThat(schemas).isNotEmpty(); } @Test @@ -143,58 +141,59 @@ public void testStaging() throws IOException { // perform the staging StagingData output = _STAGING.stage(_ALGORITHM, _VERSION, data.getInput()).execute().body(); - assertEquals(StagingData.Result.STAGED, output.getResult()); - assertEquals(0, output.getErrors().size()); - assertEquals(37, output.getPath().size()); + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getErrors()).isEmpty(); + assertThat(output.getPath()).hasSize(37); // check output - assertEquals("129", output.getOutput("schema_number")); - assertEquals("urethra", output.getSchemaId()); - assertEquals("020550", output.getOutput("csver_derived")); + assertThat(output.getOutput("schema_number")).isEqualTo("129"); + assertThat(output.getSchemaId()).isEqualTo("urethra"); + assertThat(output.getOutput("csver_derived")).isEqualTo("020550"); // AJCC 6 - assertEquals("T1", output.getOutput("ajcc6_t")); - assertEquals("10", output.getOutput("stor_ajcc6_t")); - assertEquals("c", output.getOutput("ajcc6_tdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc6_tdescriptor")); - assertEquals("N1", output.getOutput("ajcc6_n")); - assertEquals("10", output.getOutput("stor_ajcc6_n")); - assertEquals("c", output.getOutput("ajcc6_ndescriptor")); - assertEquals("c", output.getOutput("stor_ajcc6_ndescriptor")); - assertEquals("M1", output.getOutput("ajcc6_m")); - assertEquals("10", output.getOutput("stor_ajcc6_m")); - assertEquals("c", output.getOutput("ajcc6_mdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc6_mdescriptor")); - assertEquals("IV", output.getOutput("ajcc6_stage")); - assertEquals("70", output.getOutput("stor_ajcc6_stage")); + assertThat(output.getOutput("ajcc6_t")).isEqualTo("T1"); + assertThat(output.getOutput("stor_ajcc6_t")).isEqualTo("10"); + assertThat(output.getOutput("ajcc6_tdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("stor_ajcc6_tdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("ajcc6_n")).isEqualTo("N1"); + assertThat(output.getOutput("stor_ajcc6_n")).isEqualTo("10"); + assertThat(output.getOutput("ajcc6_ndescriptor")).isEqualTo("c"); + assertThat(output.getOutput("stor_ajcc6_ndescriptor")).isEqualTo("c"); + assertThat(output.getOutput("ajcc6_m")).isEqualTo("M1"); + assertThat(output.getOutput("stor_ajcc6_m")).isEqualTo("10"); + assertThat(output.getOutput("ajcc6_mdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("stor_ajcc6_mdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("ajcc6_stage")).isEqualTo("IV"); + assertThat(output.getOutput("stor_ajcc6_stage")).isEqualTo("70"); // AJCC 7 - assertEquals("T1", output.getOutput("ajcc7_t")); - assertEquals("100", output.getOutput("stor_ajcc7_t")); - assertEquals("c", output.getOutput("ajcc7_tdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc7_tdescriptor")); - assertEquals("N1", output.getOutput("ajcc7_n")); - assertEquals("100", output.getOutput("stor_ajcc7_n")); - assertEquals("c", output.getOutput("ajcc7_ndescriptor")); - assertEquals("c", output.getOutput("stor_ajcc7_ndescriptor")); - assertEquals("M1", output.getOutput("ajcc7_m")); - assertEquals("100", output.getOutput("stor_ajcc7_m")); - assertEquals("c", output.getOutput("ajcc7_mdescriptor")); - assertEquals("c", output.getOutput("stor_ajcc7_mdescriptor")); - assertEquals("IV", output.getOutput("ajcc7_stage")); - assertEquals("700", output.getOutput("stor_ajcc7_stage")); + assertThat(output.getOutput("ajcc7_t")).isEqualTo("T1"); + assertThat(output.getOutput("stor_ajcc7_t")).isEqualTo("100"); + assertThat(output.getOutput("ajcc7_tdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("stor_ajcc7_tdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("ajcc7_n")).isEqualTo("N1"); + assertThat(output.getOutput("stor_ajcc7_n")).isEqualTo("100"); + assertThat(output.getOutput("ajcc7_ndescriptor")).isEqualTo("c"); + assertThat(output.getOutput("stor_ajcc7_ndescriptor")).isEqualTo("c"); + assertThat(output.getOutput("ajcc7_m")).isEqualTo("M1"); + assertThat(output.getOutput("stor_ajcc7_m")).isEqualTo("100"); + assertThat(output.getOutput("ajcc7_mdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("stor_ajcc7_mdescriptor")).isEqualTo("c"); + assertThat(output.getOutput("ajcc7_stage")).isEqualTo("IV"); + assertThat(output.getOutput("stor_ajcc7_stage")).isEqualTo("700"); // Summary Stage - assertEquals("L", output.getOutput("t77")); - assertEquals("RN", output.getOutput("n77")); - assertEquals("D", output.getOutput("m77")); - assertEquals("D", output.getOutput("ss77")); - assertEquals("7", output.getOutput("stor_ss77")); - assertEquals("L", output.getOutput("t2000")); - assertEquals("RN", output.getOutput("n2000")); - assertEquals("D", output.getOutput("m2000")); - assertEquals("D", output.getOutput("ss2000")); - assertEquals("7", output.getOutput("stor_ss2000")); + assertThat(output.getOutput("t77")).isEqualTo("L"); + assertThat(output.getOutput("n77")).isEqualTo("RN"); + assertThat(output.getOutput("m77")).isEqualTo("D"); + assertThat(output.getOutput("ss77")).isEqualTo("D"); + assertThat(output.getOutput("stor_ss77")).isEqualTo("7"); + assertThat(output.getOutput("t2000")).isEqualTo("L"); + assertThat(output.getOutput("n2000")).isEqualTo("RN"); + assertThat(output.getOutput("m2000")).isEqualTo("D"); + assertThat(output.getOutput("ss2000")).isEqualTo("D"); + assertThat(output.getOutput("stor_ss2000")).isEqualTo("7"); } @Test @@ -208,8 +207,9 @@ public void testStagingWithErrors() throws IOException { // perform the staging StagingData output = _STAGING.stage(_ALGORITHM, _VERSION, data.getInput()).execute().body(); - assertEquals(StagingData.Result.STAGED, output.getResult()); - assertEquals(9, output.getErrors().size()); + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getErrors()).hasSize(9); } } From 0f0bd06f1c7bb92b10c12f03f4daec8dd5ef1ec2 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 16 Mar 2018 09:47:15 -0400 Subject: [PATCH 009/243] Unit test fixes. --- .../seerapi/client/naaccr/NaaccrTest.java | 56 +++++++++---------- .../imsweb/seerapi/client/ndc/NdcTest.java | 4 +- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index bfda340..84e56d6 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -11,9 +11,8 @@ import com.imsweb.seerapi.client.SeerApi; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; + public class NaaccrTest { @@ -28,13 +27,13 @@ public static void setup() { public void testNaaccrVersions() throws IOException { List versions = _NAACCR.versions().execute().body(); - assertTrue(versions.size() > 0); + assertThat(versions).isNotNull().isNotEmpty(); for (NaaccrVersion version : versions) { - assertTrue(version.getVersion().length() > 0); - assertTrue(version.getName().length() > 0); - assertEquals(22824, version.getLength().longValue()); - assertTrue(version.getDescription().length() > 0); - assertTrue(version.getStyle().length() > 0); + assertThat(version.getVersion()).isNotEmpty(); + assertThat(version.getName()).isNotEmpty(); + assertThat(version.getLength()).isGreaterThanOrEqualTo(22824); + assertThat(version.getDescription()).isNotEmpty(); + assertThat(version.getStyle()).isNotEmpty(); } } @@ -42,36 +41,35 @@ public void testNaaccrVersions() throws IOException { public void testNaaccrFieldNames() throws IOException { List names = _NAACCR.fieldNames("latest").execute().body(); - assertTrue(names.size() > 0); + assertThat(names).isNotEmpty(); for (NaaccrFieldName name : names) { - assertTrue(name.getItem() > 0); - assertTrue(name.getName().length() > 0); + assertThat(name.getItem()).isGreaterThan(0); + assertThat(name.getName()).isNotEmpty(); } } @Test public void testNaaccrField() throws IOException { - NaaccrField name = _NAACCR.field("latest", 521).execute().body(); + NaaccrField name = _NAACCR.field("16", 521).execute().body(); - assertNotNull(name); - assertEquals("Morph--Type&Behav ICD-O-3", name.getName()); - assertEquals("LEFT", name.getAlign()); - assertEquals(" ", name.getPadChar()); - assertTrue(name.getDocumentation().startsWith("")); - assertEquals(521, name.getItem().longValue()); - assertEquals(550, name.getStart().longValue()); - assertEquals(554, name.getEnd().longValue()); + assertThat(name).isNotNull(); + assertThat(name.getName()).isEqualTo("Morph--Type&Behav ICD-O-3"); + assertThat(name.getAlign()).isEqualTo("LEFT"); + assertThat(name.getPadChar()).isEqualTo(" "); + assertThat(name.getDocumentation()).startsWith("
"); + assertThat(name.getItem()).isEqualTo(521); + assertThat(name.getStart()).isEqualTo(550); + assertThat(name.getEnd()).isEqualTo(554); - assertEquals(2, name.getSubFields().size()); - assertEquals(522, name.getSubFields().get(0).getItem().longValue()); - assertEquals(523, name.getSubFields().get(1).getItem().longValue()); + assertThat(name.getSubFields()).hasSize(2); + assertThat(name.getSubFields()).extracting("item").contains(522, 523); NaaccrSubField sub = name.getSubFields().get(0); - assertEquals("Histologic Type ICD-O-3", sub.getName()); - assertEquals(550, sub.getStart().longValue()); - assertEquals(553, sub.getEnd().longValue()); - assertEquals("LEFT", sub.getAlign()); - assertEquals(" ", sub.getPadChar()); + assertThat(sub.getName()).isEqualTo("Histologic Type ICD-O-3"); + assertThat(sub.getStart()).isEqualTo(550); + assertThat(sub.getEnd()).isEqualTo(553); + assertThat(sub.getAlign()).isEqualTo("LEFT"); + assertThat(sub.getPadChar()).isEqualTo(" "); } } diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 6feabcc..b73b7e2 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -56,9 +56,9 @@ public void testNdcByCode() throws IOException { assertEquals(Arrays.asList("Norepinephrine Reuptake Inhibitor [EPC]", "Norepinephrine Uptake Inhibitors [MoA]"), product.getPharmClass()); - assertEquals(1, product.getPackages().size()); + assertEquals(2, product.getPackages().size()); assertEquals("30", product.getPackages().get(0).getCode()); - assertEquals("30 CAPSULE in 1 BOTTLE (0002-3227-30)", product.getPackages().get(0).getDescription()); + assertEquals("30 CAPSULE in 1 BOTTLE (0002-3227-30)", product.getPackages().get(0).getDescription().trim()); assertNotNull(product.getDateAdded()); assertNotNull(product.getDateModified()); From 43ac7cd8166040f41486d367f5fe68eff66c75f7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 18 Apr 2018 10:19:16 -0400 Subject: [PATCH 010/243] Support new NDC information This will fail unit tests until production SEER*API includes changes. --- build.gradle | 8 +- gradle/wrapper/gradle-wrapper.jar | Bin 54708 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- .../com/imsweb/seerapi/client/SeerApi.java | 8 +- .../imsweb/seerapi/client/ndc/NdcPackage.java | 15 --- .../imsweb/seerapi/client/ndc/NdcProduct.java | 5 + .../imsweb/seerapi/client/ndc/NdcSearch.java | 13 +++ .../seerapi/client/ndc/NdcSeerInfo.java | 66 +++++++++++++ .../imsweb/seerapi/client/ndc/NdcTest.java | 91 +++++++++++------- 9 files changed, 148 insertions(+), 62 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java diff --git a/build.gradle b/build.gradle index 153a9f9..8e36dc5 100644 --- a/build.gradle +++ b/build.gradle @@ -28,11 +28,11 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.3.0' - compile 'com.squareup.retrofit2:converter-jackson:2.3.0' + compile 'com.squareup.retrofit2:retrofit:2.4.0' + compile 'com.squareup.retrofit2:converter-jackson:2.4.0' testCompile 'junit:junit:4.11' - testCompile 'org.assertj:assertj-core:3.9.0' + testCompile 'org.assertj:assertj-core:3.9.1' } jar { @@ -66,7 +66,7 @@ findbugs { // Gradle wrapper, this allows to build the project without having to install Gradle! task wrapper(type: Wrapper) { - gradleVersion = '4.1' + gradleVersion = '4.7' } modifyPom { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7a3265ee94c0ab25cf079ac8ccdf87f41d455d42..91ca28c8b802289c3a438766657a5e98f20eff03 100644 GIT binary patch delta 22871 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 O4l|$OM3wFR$NE2b#S>8g diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 521fd9a..2489c8f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Aug 18 11:34:44 EDT 2017 +#Wed Apr 18 09:06:34 EDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip diff --git a/src/main/java/com/imsweb/seerapi/client/SeerApi.java b/src/main/java/com/imsweb/seerapi/client/SeerApi.java index bcbfb91..c0f47fa 100644 --- a/src/main/java/com/imsweb/seerapi/client/SeerApi.java +++ b/src/main/java/com/imsweb/seerapi/client/SeerApi.java @@ -11,7 +11,7 @@ import java.util.Properties; import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -91,15 +91,13 @@ private SeerApi(String baseUrl, final String apiKey) { /** * Return the internal ObjectMapper - * @return + * @return an Objectmapper */ static ObjectMapper getMapper() { ObjectMapper mapper = new ObjectMapper(); // do not write null values - mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); - mapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + mapper.setSerializationInclusion(Include.NON_NULL); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java index 3acf01e..f8531b1 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java @@ -22,31 +22,16 @@ public String getCode() { return _code; } - public void setCode(String code) { - _code = code; - } - public String getDescription() { return _description; } - public void setDescription(String description) { - _description = description; - } - public String getStartMarketingDate() { return _startMarketingDate; } - public void setStartMarketingDate(String startMarketingDate) { - _startMarketingDate = startMarketingDate; - } - public String getEndMarketingDate() { return _endMarketingDate; } - public void setEndMarketingDate(String endMarketingDate) { - _endMarketingDate = endMarketingDate; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java index 019315d..0a5a4ec 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java @@ -52,6 +52,8 @@ public class NdcProduct { private Date _dateModified; @JsonProperty("date_removed") private Date _dateRemoved; + @JsonProperty("seer") + private NdcSeerInfo _seerInfo; public String getNdc() { return _ndc; @@ -129,4 +131,7 @@ public Date getDateRemoved() { return _dateRemoved; } + public NdcSeerInfo getSeerInfo() { + return _seerInfo; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java index 9c750de..b663113 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java @@ -6,9 +6,12 @@ import java.util.HashMap; import java.util.Map; +import com.imsweb.seerapi.client.ndc.NdcSeerInfo.Category; + public class NdcSearch { private String _query; + private Category _category; private Boolean _includeRemoved; private String _addedSince; private String _modifiedSince; @@ -25,6 +28,14 @@ public void setQuery(String query) { _query = query; } + public Category getCategory() { + return _category; + } + + public void setCategory(Category category) { + _category = category; + } + public Boolean getIncludeRemoved() { return _includeRemoved; } @@ -90,6 +101,8 @@ public Map paramMap() { if (getQuery() != null) params.put("q", getQuery()); + if (getCategory() != null) + params.put("category", getCategory().toString()); if (getIncludeRemoved() != null) params.put("include_removed", getIncludeRemoved() ? "true" : "false"); if (getAddedSince() != null) diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java new file mode 100644 index 0000000..84c98a9 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.ndc; + +import java.util.Date; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({"seer_rx_id", "categories", "subcategory", "major_drug_class", "minor_drug_class", "orphan_drug", "date_modified"}) +public class NdcSeerInfo { + + @JsonProperty("seer_rx_id") + private String _seerRxId; + @JsonProperty("categories") + private List _categories; + @JsonProperty("subcategory") + private String _subcategory; + @JsonProperty("major_drug_class") + private String _majorDrugClass; + @JsonProperty("minor_drug_class") + private String _minorDrugClass; + @JsonProperty("orphan_drug") + private Boolean _orphanDrug; + @JsonProperty("date_modified") + private Date _dateModified; + + public String getSeerRxId() { + return _seerRxId; + } + + public List getCategories() { + return _categories; + } + + public String getSubcategory() { + return _subcategory; + } + + public String getMajorDrugClass() { + return _majorDrugClass; + } + + public String getMinorDrugClass() { + return _minorDrugClass; + } + + public Boolean getOrphanDrug() { + return _orphanDrug; + } + + public Date getDateModified() { + return _dateModified; + } + + // drug categories + public enum Category { + HORMONAL_THERAPY, + ANCILLARY, + CHEMOTHERAPY, + IMMUNOTHERAPY, + RADIOPHARMACEUTICAL + } +} diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index b73b7e2..0897143 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -4,8 +4,6 @@ package com.imsweb.seerapi.client.ndc; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import org.junit.BeforeClass; @@ -14,11 +12,9 @@ import retrofit2.Response; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.ndc.NdcSeerInfo.Category; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; public class NdcTest { @@ -33,36 +29,42 @@ public static void setup() { public void testNdcByCode() throws IOException { NdcProduct product = _NDC.getByCode("0002-3227").execute().body(); - assertNotNull(product); - assertEquals("0002-3227", product.getNdc()); - assertEquals("HUMAN PRESCRIPTION DRUG", product.getTypeName()); - assertEquals("Strattera", product.getProprietaryName()); - assertNull(product.getProprietaryNameSuffix()); - assertEquals(Collections.singletonList("Atomoxetine hydrochloride"), product.getNonProprietaryName()); - assertEquals("CAPSULE", product.getDosageFormName()); - assertEquals(Collections.singletonList("ORAL"), product.getRouteName()); - assertEquals("20021126", product.getStartMarketingDate()); - assertNull(product.getEndMarketingDate()); - assertEquals("NDA", product.getMarketingCategoryName()); - assertEquals("NDA021411", product.getApplicationNumber()); - assertEquals("Eli Lilly and Company", product.getLabelerName()); - assertNull(product.getDeaSchedule()); - assertEquals(1, product.getSubstances().size()); + assertThat(product).isNotNull(); + assertThat(product.getNdc()).isEqualTo("0002-3227"); + assertThat(product.getTypeName()).isEqualTo("HUMAN PRESCRIPTION DRUG"); + assertThat(product.getProprietaryName()).isEqualTo("Strattera"); + assertThat(product.getProprietaryNameSuffix()).isNull(); + assertThat(product.getNonProprietaryName()).containsExactly("Atomoxetine hydrochloride"); + assertThat(product.getDosageFormName()).isEqualTo("CAPSULE"); + assertThat(product.getRouteName()).containsExactly("ORAL"); + assertThat(product.getStartMarketingDate()).isEqualTo("20021126"); + assertThat(product.getEndMarketingDate()).isNull(); + assertThat(product.getMarketingCategoryName()).isEqualTo("NDA"); + assertThat(product.getApplicationNumber()).isEqualTo("NDA021411"); + assertThat(product.getLabelerName()).isEqualTo("Eli Lilly and Company"); + assertThat(product.getDeaSchedule()).isNull(); + assertThat(product.getSubstances()).hasSize(1); NdcSubstance substance = product.getSubstances().get(0); - assertEquals("ATOMOXETINE HYDROCHLORIDE", substance.getName()); - assertEquals("10", substance.getStrengthNumber()); - assertEquals("mg/1", substance.getStrengthUnit()); + assertThat(substance.getName()).isEqualTo("ATOMOXETINE HYDROCHLORIDE"); + assertThat(substance.getStrengthNumber()).isEqualTo("10"); + assertThat(substance.getStrengthUnit()).isEqualTo("mg/1"); - assertEquals(Arrays.asList("Norepinephrine Reuptake Inhibitor [EPC]", "Norepinephrine Uptake Inhibitors [MoA]"), product.getPharmClass()); + assertThat(product.getPharmClass()).containsExactly("Norepinephrine Reuptake Inhibitor [EPC]", "Norepinephrine Uptake Inhibitors [MoA]"); - assertEquals(2, product.getPackages().size()); - assertEquals("30", product.getPackages().get(0).getCode()); - assertEquals("30 CAPSULE in 1 BOTTLE (0002-3227-30)", product.getPackages().get(0).getDescription().trim()); + assertThat(product.getPackages()).isNotEmpty(); + assertThat(product.getPackages().get(0).getCode()).isEqualTo("30"); + assertThat(product.getPackages().get(0).getDescription()).isEqualToIgnoringWhitespace("30 CAPSULE in 1 BOTTLE (0002-3227-30)"); - assertNotNull(product.getDateAdded()); - assertNotNull(product.getDateModified()); - assertNull(product.getDateRemoved()); + assertThat(product.getDateAdded()).isNotNull(); + assertThat(product.getDateModified()).isNotNull(); + assertThat(product.getDateRemoved()).isNull(); + + // test one with "seer" added information (0002-4483) + product = _NDC.getByCode("0002-4483").execute().body(); + assertThat(product.getNdc()).isEqualTo("0002-4483"); + assertThat(product.getProprietaryName()).isEqualTo("Verzenio"); + assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.CHEMOTHERAPY); } @Test @@ -74,18 +76,18 @@ public void testNdcSearch() throws IOException { // hold onto total number (including "removed") Integer totalIncludingRemoved = Integer.valueOf(response.headers().get("X-Total-Count")); - assertTrue(totalIncludingRemoved > 100000); + assertThat(totalIncludingRemoved).isGreaterThan(100000); List products = response.body(); - assertEquals(25, products.size()); + assertThat(products).hasSize(25); search.setQuery("daklinza"); products = _NDC.search(search.paramMap()).execute().body(); - assertTrue(products.size() > 1); + assertThat(products.size()).isGreaterThan(1); search.setRemovedSince("2016-07-21"); products = _NDC.search(search.paramMap()).execute().body(); - assertEquals(0, products.size()); + assertThat(products).isEmpty(); // test removed search = new NdcSearch(); @@ -93,7 +95,24 @@ public void testNdcSearch() throws IOException { response = _NDC.search(search.paramMap()).execute(); Integer totalExcludingRemoved = Integer.valueOf(response.headers().get("X-Total-Count")); - assertTrue(totalIncludingRemoved > totalExcludingRemoved); + assertThat(totalIncludingRemoved).isGreaterThan(totalExcludingRemoved); + } + + @Test + public void testNdcSearchByCategory() throws IOException { + NdcSearch search = new NdcSearch(); + search.setCategory(Category.CHEMOTHERAPY); + + Response> response = _NDC.search(search.paramMap()).execute(); + + assertThat(Integer.valueOf(response.headers().get("X-Total-Count"))).isGreaterThan(0); + + List products = response.body(); + assertThat(products).isNotEmpty(); + + NdcProduct product = products.get(0); + assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); + assertThat(product.getSeerInfo().getCategories()).contains(Category.CHEMOTHERAPY); } } From a47103fdf2d665883b6279641c0144495b1a800b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 18 Apr 2018 10:22:58 -0400 Subject: [PATCH 011/243] Support new NDC information This will fail unit tests until production SEER*API includes changes. --- src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 0897143..a2ff4fa 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -64,6 +64,7 @@ public void testNdcByCode() throws IOException { product = _NDC.getByCode("0002-4483").execute().body(); assertThat(product.getNdc()).isEqualTo("0002-4483"); assertThat(product.getProprietaryName()).isEqualTo("Verzenio"); + assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.CHEMOTHERAPY); } From eb175192cdeef1557bbc07044f88b286945627b6 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 19 Apr 2018 08:36:14 -0400 Subject: [PATCH 012/243] Preparing release --- README.md | 4 ++-- build.gradle | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2844af8..467d94f 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.7 + 3.8 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.7' +compile 'com.imsweb:seerapi-client-java:3.8' ``` ## Usage diff --git a/build.gradle b/build.gradle index 8e36dc5..3df58d3 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { id 'checkstyle' id 'findbugs' id 'com.bmuschko.nexus' version '2.3.1' - id "io.codearte.nexus-staging" version "0.8.0" // logs into Sonotype OSS and does a "Close" and "Release" + id "io.codearte.nexus-staging" version "0.11.0" id 'net.ossindex.audit' version '0.1.1' } @@ -64,7 +64,6 @@ findbugs { excludeFilter = file("config/findbugs/findbugs-exclude.xml") } -// Gradle wrapper, this allows to build the project without having to install Gradle! task wrapper(type: Wrapper) { gradleVersion = '4.7' } From 088022823e4bbe320f228948e0fc506efba6966e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 19 Apr 2018 09:08:47 -0400 Subject: [PATCH 013/243] Tweak build process --- build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/build.gradle b/build.gradle index 3df58d3..40cef05 100644 --- a/build.gradle +++ b/build.gradle @@ -53,14 +53,11 @@ jar { // checkstyle plugin settings checkstyle { - ignoreFailures = true configFile = file("config/checkstyle/checkstyle.xml") } // findbugs plugin settings findbugs { - ignoreFailures = true - effort = 'max' excludeFilter = file("config/findbugs/findbugs-exclude.xml") } From 3b75f29ef093b8f15d9b428d2199cf6b98438096 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 2 May 2018 08:44:13 -0400 Subject: [PATCH 014/243] Added missing disease source (#15) --- README.md | 4 +- build.gradle | 2 +- .../seerapi/client/disease/Disease.java | 158 ++++++++++-------- .../seerapi/client/disease/DiseaseSource.java | 42 +++++ .../imsweb/seerapi/client/ndc/NdcProduct.java | 6 + .../seerapi/client/disease/DiseaseTest.java | 23 ++- 6 files changed, 148 insertions(+), 87 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java diff --git a/README.md b/README.md index 467d94f..83c34a2 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.8 + 3.9 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.8' +compile 'com.imsweb:seerapi-client-java:3.9' ``` ## Usage diff --git a/build.gradle b/build.gradle index 40cef05..90eb107 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.8' +version = '3.9' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" diff --git a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java index f3e8ef8..90ac710 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java @@ -9,109 +9,111 @@ public class Disease extends Publishable { @JsonProperty("history") - protected List _history; + private List _history; /** * Identifying information */ @JsonProperty("icdO3_morphology") - protected String _icdO3Morphology; + private String _icdO3Morphology; @JsonProperty("primary_site") - protected List _primarySite; + private List _primarySite; @JsonProperty("primary_site_text") - protected String _primarySiteText; + private String _primarySiteText; @JsonProperty("site_category") - protected String _siteCategory; + private String _siteCategory; @JsonProperty("type") - protected Type _type; + private Type _type; /** * Obsolete ranges */ @JsonProperty("valid") - protected YearRange _valid; + private YearRange _valid; @JsonProperty("obsolete_new_code") - protected List _obsoleteNewCode; + private List _obsoleteNewCode; /** * Shared disease properties */ @JsonProperty("reportable") - protected List _reportable; + private List _reportable; @JsonProperty("abstractor_note") - protected List _abstractorNote; + private List _abstractorNote; @JsonProperty("treatment") - protected List _treatment; + private List _treatment; @JsonProperty("genetics") - protected List _genetics; + private List _genetics; @JsonProperty("alternate_name") - protected List _alternateName; + private List _alternateName; @JsonProperty("definition") - protected List _definition; + private List _definition; @JsonProperty("icdO2_morphology") - protected List _icdO2Morphology; + private List _icdO2Morphology; @JsonProperty("icdO1_morphology") - protected List _icdO1Morphology; + private List _icdO1Morphology; @JsonProperty("icd_10cm_code") - protected List _icd10CmCode; + private List _icd10CmCode; @JsonProperty("icd_10_code") - protected List _icd10Code; + private List _icd10Code; @JsonProperty("icd_9_code") - protected List _icd9Code; + private List _icd9Code; @JsonProperty("signs") - protected List _signs; + private List _signs; @JsonProperty("exams") - protected List _exams; + private List _exams; @JsonProperty("mortality") - protected List _mortality; + private List _mortality; + @JsonProperty("source") + private List _source; /** * Morphology ranges */ @JsonProperty("icdO3_effective") - protected YearRange _icdO3Effective; + private YearRange _icdO3Effective; @JsonProperty("icdO2_effective") - protected YearRange _icdO2Effective; + private YearRange _icdO2Effective; @JsonProperty("icdO1_effective") - protected YearRange _icdO1Effective; + private YearRange _icdO1Effective; /** * Hemato specific */ @JsonProperty("missing_primary_site_message") - protected List _missingPrimarySiteMessage; + private List _missingPrimarySiteMessage; @JsonProperty("grade") - protected List _grade; + private List _grade; @JsonProperty("transform_to") - protected List _transformTo; + private List _transformTo; @JsonProperty("transform_to_text") - protected List _transformToText; + private List _transformToText; @JsonProperty("transform_from") - protected List _transformFrom; + private List _transformFrom; @JsonProperty("transform_from_text") - protected List _transformFromText; + private List _transformFromText; @JsonProperty("immunophenotype") - protected List _immunophenotype; + private List _immunophenotype; @JsonProperty("diagnosis_method") - protected List _diagnosisMethod; + private List _diagnosisMethod; @JsonProperty("module_id") - protected List _moduleId; + private List _moduleId; @JsonProperty("same_primary") - protected List _samePrimaries; + private List _samePrimaries; @JsonProperty("same_primaries_text") - protected List _samePrimariesText; + private List _samePrimariesText; @JsonProperty("progression") - protected List _progression; + private List _progression; /** * Solid tumor specific */ @JsonProperty("biomarkers") - protected List _biomarkers; + private List _biomarkers; @JsonProperty("treatment_text") - protected List _treatmentText; + private List _treatmentText; @JsonProperty("recurrence") - protected List _recurrence; + private List _recurrence; public List getHistory() { return _history; @@ -129,7 +131,7 @@ public void setIcdO3Morphology(String icdO3Morphology) { _icdO3Morphology = icdO3Morphology; } - public List getPrimarySite() { + List getPrimarySite() { return _primarySite; } @@ -145,7 +147,7 @@ public void setPrimarySiteText(String primarySiteText) { _primarySiteText = primarySiteText; } - public String getSiteCategory() { + String getSiteCategory() { return _siteCategory; } @@ -161,7 +163,7 @@ public void setType(Type type) { _type = type; } - public YearRange getValid() { + YearRange getValid() { return _valid; } @@ -169,7 +171,7 @@ public void setValid(YearRange valid) { _valid = valid; } - public List getObsoleteNewCode() { + List getObsoleteNewCode() { return _obsoleteNewCode; } @@ -177,7 +179,7 @@ public void setObsoleteNewCode(List obsoleteNewCode) { _obsoleteNewCode = obsoleteNewCode; } - public List getReportable() { + List getReportable() { return _reportable; } @@ -185,7 +187,7 @@ public void setReportable(List reportable) { _reportable = reportable; } - public List getAbstractorNote() { + List getAbstractorNote() { return _abstractorNote; } @@ -193,7 +195,7 @@ public void setAbstractorNote(List abstractorNote) { _abstractorNote = abstractorNote; } - public List getTreatment() { + List getTreatment() { return _treatment; } @@ -201,7 +203,7 @@ public void setTreatment(List treatment) { _treatment = treatment; } - public List getGenetics() { + List getGenetics() { return _genetics; } @@ -209,7 +211,7 @@ public void setGenetics(List genetics) { _genetics = genetics; } - public List getAlternateName() { + List getAlternateName() { return _alternateName; } @@ -217,7 +219,7 @@ public void setAlternateName(List alternateName) { _alternateName = alternateName; } - public List getDefinition() { + List getDefinition() { return _definition; } @@ -225,7 +227,7 @@ public void setDefinition(List definition) { _definition = definition; } - public List getIcdO2Morphology() { + List getIcdO2Morphology() { return _icdO2Morphology; } @@ -233,7 +235,7 @@ public void setIcdO2Morphology(List icdO2Morphology) { _icdO2Morphology = icdO2Morphology; } - public List getIcdO1Morphology() { + List getIcdO1Morphology() { return _icdO1Morphology; } @@ -241,7 +243,7 @@ public void setIcdO1Morphology(List icdO1Morphology) { _icdO1Morphology = icdO1Morphology; } - public List getIcd10CmCode() { + List getIcd10CmCode() { return _icd10CmCode; } @@ -249,7 +251,7 @@ public void setIcd10CmCode(List icd10CmCode) { _icd10CmCode = icd10CmCode; } - public List getIcd10Code() { + List getIcd10Code() { return _icd10Code; } @@ -257,7 +259,7 @@ public void setIcd10Code(List icd10Code) { _icd10Code = icd10Code; } - public List getIcd9Code() { + List getIcd9Code() { return _icd9Code; } @@ -265,7 +267,7 @@ public void setIcd9Code(List icd9Code) { _icd9Code = icd9Code; } - public List getSigns() { + List getSigns() { return _signs; } @@ -273,7 +275,7 @@ public void setSigns(List signs) { _signs = signs; } - public List getExams() { + List getExams() { return _exams; } @@ -281,7 +283,7 @@ public void setExams(List exams) { _exams = exams; } - public List getRecurrence() { + List getRecurrence() { return _recurrence; } @@ -289,7 +291,7 @@ public void setRecurrence(List recurrence) { _recurrence = recurrence; } - public List getMortality() { + List getMortality() { return _mortality; } @@ -297,7 +299,15 @@ public void setMortality(List mortality) { _mortality = mortality; } - public YearRange getIcdO3Effective() { + public List getSource() { + return _source; + } + + public void setSource(List source) { + _source = source; + } + + YearRange getIcdO3Effective() { return _icdO3Effective; } @@ -305,7 +315,7 @@ public void setIcdO3Effective(YearRange icdO3Effective) { _icdO3Effective = icdO3Effective; } - public YearRange getIcdO2Effective() { + YearRange getIcdO2Effective() { return _icdO2Effective; } @@ -313,7 +323,7 @@ public void setIcdO2Effective(YearRange icdO2Effective) { _icdO2Effective = icdO2Effective; } - public YearRange getIcdO1Effective() { + YearRange getIcdO1Effective() { return _icdO1Effective; } @@ -321,7 +331,7 @@ public void setIcdO1Effective(YearRange icdO1Effective) { _icdO1Effective = icdO1Effective; } - public List getMissingPrimarySiteMessage() { + List getMissingPrimarySiteMessage() { return _missingPrimarySiteMessage; } @@ -329,7 +339,7 @@ public void setMissingPrimarySiteMessage(List missingPrimarySit _missingPrimarySiteMessage = missingPrimarySiteMessage; } - public List getGrade() { + List getGrade() { return _grade; } @@ -337,7 +347,7 @@ public void setGrade(List grade) { _grade = grade; } - public List getTransformTo() { + List getTransformTo() { return _transformTo; } @@ -345,7 +355,7 @@ public void setTransformTo(List transformTo) { _transformTo = transformTo; } - public List getTransformFrom() { + List getTransformFrom() { return _transformFrom; } @@ -369,7 +379,7 @@ public void setTransformToText(List transformToText) { _transformToText = transformToText; } - public List getImmunophenotype() { + List getImmunophenotype() { return _immunophenotype; } @@ -377,7 +387,7 @@ public void setImmunophenotype(List immunophenotype) { _immunophenotype = immunophenotype; } - public List getDiagnosisMethod() { + List getDiagnosisMethod() { return _diagnosisMethod; } @@ -385,7 +395,7 @@ public void setDiagnosisMethod(List diagnosisMethod) { _diagnosisMethod = diagnosisMethod; } - public List getModuleId() { + List getModuleId() { return _moduleId; } @@ -393,7 +403,7 @@ public void setModuleId(List moduleId) { _moduleId = moduleId; } - public List getSamePrimaries() { + List getSamePrimaries() { return _samePrimaries; } @@ -409,7 +419,7 @@ public void setSamePrimariesText(List samePrimariesText) { _samePrimariesText = samePrimariesText; } - public List getBiomarkers() { + List getBiomarkers() { return _biomarkers; } @@ -417,7 +427,7 @@ public void setBiomarkers(List biomarkers) { _biomarkers = biomarkers; } - public List getTreatmentText() { + List getTreatmentText() { return _treatmentText; } @@ -425,6 +435,10 @@ public void setTreatmentText(List treatmentText) { _treatmentText = treatmentText; } + public List getProgression() { + return _progression; + } + public void setProgression(List progression) { _progression = progression; } diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java new file mode 100644 index 0000000..b0a40e4 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseSource.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.disease; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({"name", "section", "pages"}) +public class DiseaseSource { + + @JsonProperty("name") + private String _name; + @JsonProperty("section") + private String _section; + @JsonProperty("pages") + private String _pages; + + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + + public String getSection() { + return _section; + } + + public void setSection(String section) { + _section = section; + } + + public String getPages() { + return _pages; + } + + public void setPages(String pages) { + _pages = pages; + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java index 0a5a4ec..1bf9def 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java @@ -54,6 +54,8 @@ public class NdcProduct { private Date _dateRemoved; @JsonProperty("seer") private NdcSeerInfo _seerInfo; + @JsonProperty("score") + private Double _score; public String getNdc() { return _ndc; @@ -134,4 +136,8 @@ public Date getDateRemoved() { public NdcSeerInfo getSeerInfo() { return _seerInfo; } + + public Double getScore() { + return _score; + } } diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 3da3d3b..a427243 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -84,7 +84,7 @@ public void testDiseaseById() throws IOException { Disease disease = _DISEASE.getById("latest", "51f6cf58e3e27c3994bd5408").execute().body(); assertNotNull(disease); - assertEquals("Acute erythroid leukemia", disease.getName()); + assertEquals("Pure erythroid leukemia", disease.getName()); assertEquals(Disease.Type.HEMATO, disease.getType()); assertEquals("9840/3", disease.getIcdO3Morphology()); assertTrue(disease.getSamePrimaries().size() > 0); @@ -121,11 +121,10 @@ public void testDiseaseById() throws IOException { assertEquals(1, disease.getAbstractorNote().size()); assertEquals(2, disease.getTreatment().size()); assertNull(disease.getGenetics()); - assertEquals(12, disease.getAlternateName().size()); - assertEquals("Acute erythremia [OBS]", disease.getAlternateName().get(0).getValue()); - assertTrue(disease.getDefinition().get(0).getValue().startsWith("Acute erythroid leukemia is characterized by a predominant erythroid")); - assertEquals(Collections.singletonList("9840/3"), disease.getIcdO2Morphology()); - assertEquals(Collections.singletonList("9840/3"), disease.getIcdO1Morphology()); + assertTrue(disease.getAlternateName().size() > 0); + assertEquals("Acute erythremia", disease.getAlternateName().get(0).getValue()); + assertTrue(disease.getIcdO2Morphology().contains("9840/3")); + assertTrue(disease.getIcdO1Morphology().contains("9840/3")); assertEquals("C94.0 Acute erythroid leukemia", disease.getIcd10CmCode().get(0).getValue()); assertEquals("C94.0 Acute erythremia and erythroleukemia", disease.getIcd10Code().get(0)); assertEquals("207.0 Acute erythremia and erythroleukemia", disease.getIcd9Code().get(0)); @@ -141,9 +140,9 @@ public void testDiseaseById() throws IOException { assertEquals(1991, disease.getIcdO1Effective().getEndYear().longValue()); assertNull(disease.getMissingPrimarySiteMessage()); assertNull(disease.getGrade()); - assertNull(disease.getTransformFrom()); + assertNotNull(disease.getTransformFrom()); assertNull(disease.getTransformTo()); - assertNull(disease.getImmunophenotype()); + assertNotNull(disease.getImmunophenotype()); assertEquals("Bone marrow biopsy", disease.getDiagnosisMethod().get(0).getValue()); assertEquals("See abstractor notes", disease.getModuleId().get(0).getValue()); assertNull(disease.getBiomarkers()); @@ -169,8 +168,8 @@ public void testDiseaseSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(3, results.getTotal().longValue()); - assertEquals(3, results.getResults().size()); + assertEquals(6, results.getTotal().longValue()); + assertEquals(6, results.getResults().size()); assertEquals(Collections.singletonList("basophilic"), results.getTerms()); search.setSiteCategory("BAD_VALUE"); @@ -205,8 +204,8 @@ public void testDiseaseSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(4, results.getTotal().longValue()); - assertEquals(4, results.getResults().size()); + assertEquals(7, results.getTotal().longValue()); + assertEquals(7, results.getResults().size()); assertEquals(Collections.singletonList("basophilic"), results.getTerms()); } From 648d99e666bed168457f9415f2012be90c4dc806 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 4 May 2018 09:47:18 -0400 Subject: [PATCH 015/243] Added has_seer_info parameter to NDC search --- .../imsweb/seerapi/client/ndc/NdcSearch.java | 11 ++++++++ .../imsweb/seerapi/client/ndc/NdcTest.java | 25 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java index b663113..c0306e9 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java @@ -12,6 +12,7 @@ public class NdcSearch { private String _query; private Category _category; + private Boolean _hasSeerInfo; private Boolean _includeRemoved; private String _addedSince; private String _modifiedSince; @@ -36,6 +37,14 @@ public void setCategory(Category category) { _category = category; } + public Boolean getHasSeerInfo() { + return _hasSeerInfo; + } + + public void setHasSeerInfo(Boolean hasSeerInfo) { + _hasSeerInfo = hasSeerInfo; + } + public Boolean getIncludeRemoved() { return _includeRemoved; } @@ -103,6 +112,8 @@ public Map paramMap() { params.put("q", getQuery()); if (getCategory() != null) params.put("category", getCategory().toString()); + if (getHasSeerInfo() != null) + params.put("has_seer_info", getHasSeerInfo().toString()); if (getIncludeRemoved() != null) params.put("include_removed", getIncludeRemoved() ? "true" : "false"); if (getAddedSince() != null) diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index a2ff4fa..eab07e6 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -116,4 +116,29 @@ public void testNdcSearchByCategory() throws IOException { assertThat(product.getSeerInfo().getCategories()).contains(Category.CHEMOTHERAPY); } + @Test + public void testNdcHasSeerInfo() throws IOException { + NdcSearch search = new NdcSearch(); + search.setIncludeRemoved(true); + + // get count of all drugs + Response> response = _NDC.search(search.paramMap()).execute(); + Integer totalCount = Integer.parseInt(response.headers().get("X-Total-Count")); + assertThat(totalCount).isGreaterThan(0); + + // get count of seer-info drugs + search.setHasSeerInfo(true); + response = _NDC.search(search.paramMap()).execute(); + Integer withCount = Integer.parseInt(response.headers().get("X-Total-Count")); + assertThat(withCount).isGreaterThan(0).isLessThan(totalCount); + + // get count of non seer-info drugs + search.setHasSeerInfo(false); + response = _NDC.search(search.paramMap()).execute(); + Integer withoutCount = Integer.parseInt(response.headers().get("X-Total-Count")); + assertThat(withCount).isGreaterThan(0).isLessThan(totalCount); + + assertThat(totalCount).isEqualTo(withCount + withoutCount); + } + } From df297066acd83ac809d71faf7bcd29b4b871fc47 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 9 May 2018 12:58:28 -0400 Subject: [PATCH 016/243] Added helper classes for TNM and EOD staging --- build.gradle | 2 +- .../client/staging/eod/EodSchemaLookup.java | 37 ++++ .../client/staging/eod/EodStagingData.java | 187 ++++++++++++++++ .../client/staging/tnm/TnmSchemaLookup.java | 32 +++ .../client/staging/tnm/TnmStagingData.java | 204 ++++++++++++++++++ 5 files changed, 461 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java create mode 100644 src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java create mode 100644 src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java create mode 100644 src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java diff --git a/build.gradle b/build.gradle index 90eb107..7e40a89 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.9' +version = '3.10-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java new file mode 100644 index 0000000..91e4f1d --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.eod; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodInput; + +public class EodSchemaLookup extends SchemaLookup { + + private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( + EodStagingData.PRIMARY_SITE_KEY, + EodStagingData.HISTOLOGY_KEY, + EodInput.SEX.toString(), + EodInput.DISCRIMINATOR_1.toString(), + EodInput.DISCRIMINATOR_2.toString()))); + + /** + * Constructor + * @param site primary site + * @param histology histology + */ + public EodSchemaLookup(String site, String histology) { + super(site, histology); + } + + @Override + public Set getAllowedKeys() { + return _ALLOWED_KEYS; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java new file mode 100644 index 0000000..4d129d4 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2014 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.eod; + +import com.imsweb.seerapi.client.staging.StagingData; + +public class EodStagingData extends StagingData { + + /** + * Default constructor + */ + public EodStagingData() { + super(); + } + + /** + * Construct with site and histology + * @param site primary site + * @param hist histology + */ + public EodStagingData(String site, String hist) { + super(site, hist); + } + + /** + * Construct with site, histology and discriminators + * @param site primary site + * @param hist histology + * @param discriminator1 first discriminator + */ + public EodStagingData(String site, String hist, String discriminator1) { + super(site, hist); + + setInput(EodInput.DISCRIMINATOR_1, discriminator1); + } + + /** + * Construct with site, histology and discriminators + * @param site primary site + * @param hist histology + * @param discriminator1 first discriminator + * @param discriminator2 second discriminator + */ + public EodStagingData(String site, String hist, String discriminator1, String discriminator2) { + super(site, hist); + + setInput(EodInput.DISCRIMINATOR_1, discriminator1); + setInput(EodInput.DISCRIMINATOR_2, discriminator2); + } + + /** + * Return the specified input value + * @param key input key + * @return input + */ + public String getInput(EodInput key) { + return getInput(key.toString()); + } + + /** + * Set the specified input value + * @param key input key + * @param value value + */ + public void setInput(EodInput key, String value) { + setInput(key.toString(), value); + } + + /** + * Return the specified output value + * @param key output key + * @return output + */ + public String getOutput(EodOutput key) { + return getOutput(key.toString()); + } + + // input key definitions + public enum EodInput { + PRIMARY_SITE("site"), + HISTOLOGY("hist"), + BEHAVIOR("behavior"), + SEX("sex"), + AGE_AT_DX("age_dx"), + DISCRIMINATOR_1("discriminator_1"), + DISCRIMINATOR_2("discriminator_2"), + CLIN_T("clin_t"), + CLIN_T_SUFFIX("clin_t_suffix"), + CLIN_N("clin_n"), + CLIN_N_SUFFIX("clin_n_suffix"), + CLIN_M("clin_m"), + CLIN_STAGE_GROUP_DIRECT("clin_stage_group_direct"), + PATH_T("path_t"), + PATH_T_SUFFIX("path_t_suffix"), + PATH_N("path_n"), + PATH_N_SUFFIX("path_n_suffix"), + PATH_M("path_m"), + PATH_STAGE_GROUP_DIRECT("path_stage_group_direct"), + YPATH_T("ypath_t"), + YPATH_T_SUFFIX("ypath_t_suffix"), + YPATH_N("ypath_n"), + YPATH_N_SUFFIX("ypath_n_suffix"), + YPATH_M("ypath_m"), + YPATH_STAGE_GROUP_DIRECT("ypath_stage_group_direct"), + NODES_POS("nodes_pos"), + NODES_EXAM("nodes_exam"), + EOD_PRIMARY_TUMOR("eod_primary_tumor"), + EOD_REGIONAL_NODES("eod_regional_nodes"), + EOD_METS("eod_mets"), + GRADE_CLIN("grade_clin"), + GRADE_PATH("grade_path"), + GRADE_POST_THERAPY("grade_post_therapy"), + DX_YEAR("year_dx"), + TUMOR_SIZE_CLIN("size_clin"), + TUMOR_SIZE_PATH("size_path"), + TUMOR_SIZE_SUMMARY("size_summary"), + RADIATION_SURG_SEQ("radiation_surg_seq"), + SYSTEMIC_SURG_SEQ("systemic_surg_seq"), + SS_2018("ss2018"); + + private String _name; + + EodInput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + // output key definitions + public enum EodOutput { + NAACCR_SCHEMA_ID("naaccr_schema_id"), + AJCC_ID("ajcc_id"), + DERIVED_VERSION("derived_version"), + EOD_2018_T("eod_2018_t"), + EOD_2018_N("eod_2018_n"), + EOD_2018_M("eod_2018_m"), + EOD_2018_STAGE_GROUP("eod_2018_stage_group"), + SS_2018_DERIVED("ss2018_derived"); + + private String _name; + + EodOutput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + /** + * TnmStagingInputBuilder builder + */ + public static class EodStagingInputBuilder { + + private EodStagingData _data; + + public EodStagingInputBuilder() { + _data = new EodStagingData(); + } + + public EodStagingInputBuilder withDisciminator1(String discriminator1) { + _data.setInput(EodInput.DISCRIMINATOR_1, discriminator1); + return this; + } + + public EodStagingInputBuilder withDisciminator2(String discriminator2) { + _data.setInput(EodInput.DISCRIMINATOR_2, discriminator2); + return this; + } + + public EodStagingInputBuilder withInput(EodInput key, String value) { + _data.setInput(key, value); + return this; + } + + public EodStagingData build() { + return _data; + } + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java new file mode 100644 index 0000000..fb75680 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.tnm; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.imsweb.seerapi.client.staging.SchemaLookup; + +public class TnmSchemaLookup extends SchemaLookup { + + private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(TnmStagingData.PRIMARY_SITE_KEY, + TnmStagingData.HISTOLOGY_KEY, TnmStagingData.SSF25_KEY, TnmStagingData.SEX_KEY))); + + /** + * Constructor + * @param site primary site + * @param histology histology + */ + public TnmSchemaLookup(String site, String histology) { + super(site, histology); + } + + @Override + public Set getAllowedKeys() { + return _ALLOWED_KEYS; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java new file mode 100644 index 0000000..edbcd79 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2014 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.staging.tnm; + +import com.imsweb.seerapi.client.staging.StagingData; + +public class TnmStagingData extends StagingData { + + // key definitions + public static final String SEX_KEY = "sex"; + public static final String SSF25_KEY = "ssf25"; + + // SSF prefix + public static final String INPUT_SSF_PREFIX = "ssf"; + + // input key definitions + public enum TnmInput { + PRIMARY_SITE("site"), + HISTOLOGY("hist"), + BEHAVIOR("behavior"), + GRADE("grade"), + SEX("sex"), + DX_YEAR("year_dx"), + AGE_AT_DX("age_dx"), + CLIN_STAGE_GROUP_DIRECT("clin_stage_group_direct"), + PATH_STAGE_GROUP_DIRECT("path_stage_group_direct"), + RX_SUMM_SURGERY("systemic_surg_seq"), + RX_SUMM_RADIATION("radiation_surg_seq"), + CLIN_T("clin_t"), + CLIN_N("clin_n"), + CLIN_M("clin_m"), + PATH_T("path_t"), + PATH_N("path_n"), + PATH_M("path_m"), + REGIONAL_NODES_POSITIVE("nodes_pos"), + SSF1("ssf1"), + SSF2("ssf2"), + SSF3("ssf3"), + SSF4("ssf4"), + SSF5("ssf5"), + SSF6("ssf6"), + SSF7("ssf7"), + SSF8("ssf8"), + SSF9("ssf9"), + SSF10("ssf10"), + SSF11("ssf11"), + SSF12("ssf12"), + SSF13("ssf13"), + SSF14("ssf14"), + SSF15("ssf15"), + SSF16("ssf16"), + SSF17("ssf17"), + SSF18("ssf18"), + SSF19("ssf19"), + SSF20("ssf20"), + SSF21("ssf21"), + SSF22("ssf22"), + SSF23("ssf23"), + SSF24("ssf24"), + SSF25("ssf25"); + + private String _name; + + TnmInput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + // output key definitions + public enum TnmOutput { + DERIVED_VERSION("derived_version"), + CLIN_STAGE_GROUP("clin_stage_group"), + PATH_STAGE_GROUP("path_stage_group"), + COMBINED_STAGE_GROUP("combined_stage_group"), + SOURCE_T("source_t"), + COMBINED_T("combined_t"), + SOURCE_N("source_n"), + COMBINED_N("combined_n"), + SOURCE_M("source_m"), + COMBINED_M("combined_m"); + + private String _name; + + TnmOutput(String name) { + _name = name; + } + + @Override + public String toString() { + return _name; + } + } + + /** + * Default constructor + */ + public TnmStagingData() { + super(); + } + + /** + * Construct with site and histology + * @param site primary site + * @param hist histology + */ + public TnmStagingData(String site, String hist) { + super(site, hist); + } + + /** + * Construct with site, histology and SSF25 + * @param site primary site + * @param hist histology + * @param ssf25 site-specific factor 25 + */ + public TnmStagingData(String site, String hist, String ssf25) { + super(site, hist); + + setSsf(25, ssf25); + } + + /** + * Return the specified input value + * @param key input key + * @return input + */ + public String getInput(TnmInput key) { + return getInput(key.toString()); + } + + /** + * Set the specified input value + * @param key input key + * @param value value + */ + public void setInput(TnmInput key, String value) { + setInput(key.toString(), value); + } + + /** + * Return the specified output value + * @param key output key + * @return output + */ + public String getOutput(TnmOutput key) { + return getOutput(key.toString()); + } + + /** + * Get the specified input site-specific factor + * @param id site-specific factor number + * @return ssf value + */ + public String getSsf(Integer id) { + if (id < 1 || id > 25) + throw new IllegalStateException("Site specific factor must be between 1 and 25."); + + return getInput(INPUT_SSF_PREFIX + id); + } + + /** + * Set the specified input site-specific factor + * @param id site-specific factor number + * @param ssf site-specfic factor value + */ + public void setSsf(Integer id, String ssf) { + if (id < 1 || id > 25) + throw new IllegalStateException("Site specific factor must be between 1 and 25."); + + setInput(INPUT_SSF_PREFIX + id, ssf); + } + + /** + * TnmStagingInputBuilder builder + */ + public static class TnmStagingInputBuilder { + + private TnmStagingData _data; + + public TnmStagingInputBuilder() { + _data = new TnmStagingData(); + } + + public TnmStagingInputBuilder withSsf(Integer id, String ssf) { + _data.setSsf(id, ssf); + return this; + } + + public TnmStagingInputBuilder withInput(TnmInput key, String value) { + _data.setInput(key, value); + return this; + } + + public TnmStagingData build() { + return _data; + } + } +} From 745ba123d58baa467ede3a23c6d68db80fae9631 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 25 May 2018 15:00:54 -0400 Subject: [PATCH 017/243] Methods should not have been made package private --- .../seerapi/client/disease/Disease.java | 65 ++++++++++--------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java index 90ac710..3ebfeca 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java @@ -6,6 +6,7 @@ import com.imsweb.seerapi.client.publishable.Publishable; +@SuppressWarnings("WeakerAccess") public class Disease extends Publishable { @JsonProperty("history") @@ -131,7 +132,7 @@ public void setIcdO3Morphology(String icdO3Morphology) { _icdO3Morphology = icdO3Morphology; } - List getPrimarySite() { + public List getPrimarySite() { return _primarySite; } @@ -147,7 +148,7 @@ public void setPrimarySiteText(String primarySiteText) { _primarySiteText = primarySiteText; } - String getSiteCategory() { + public String getSiteCategory() { return _siteCategory; } @@ -163,7 +164,7 @@ public void setType(Type type) { _type = type; } - YearRange getValid() { + public YearRange getValid() { return _valid; } @@ -171,7 +172,7 @@ public void setValid(YearRange valid) { _valid = valid; } - List getObsoleteNewCode() { + public List getObsoleteNewCode() { return _obsoleteNewCode; } @@ -179,7 +180,7 @@ public void setObsoleteNewCode(List obsoleteNewCode) { _obsoleteNewCode = obsoleteNewCode; } - List getReportable() { + public List getReportable() { return _reportable; } @@ -187,7 +188,7 @@ public void setReportable(List reportable) { _reportable = reportable; } - List getAbstractorNote() { + public List getAbstractorNote() { return _abstractorNote; } @@ -195,7 +196,7 @@ public void setAbstractorNote(List abstractorNote) { _abstractorNote = abstractorNote; } - List getTreatment() { + public List getTreatment() { return _treatment; } @@ -203,7 +204,7 @@ public void setTreatment(List treatment) { _treatment = treatment; } - List getGenetics() { + public List getGenetics() { return _genetics; } @@ -211,7 +212,7 @@ public void setGenetics(List genetics) { _genetics = genetics; } - List getAlternateName() { + public List getAlternateName() { return _alternateName; } @@ -219,7 +220,7 @@ public void setAlternateName(List alternateName) { _alternateName = alternateName; } - List getDefinition() { + public List getDefinition() { return _definition; } @@ -227,7 +228,7 @@ public void setDefinition(List definition) { _definition = definition; } - List getIcdO2Morphology() { + public List getIcdO2Morphology() { return _icdO2Morphology; } @@ -235,7 +236,7 @@ public void setIcdO2Morphology(List icdO2Morphology) { _icdO2Morphology = icdO2Morphology; } - List getIcdO1Morphology() { + public List getIcdO1Morphology() { return _icdO1Morphology; } @@ -243,7 +244,7 @@ public void setIcdO1Morphology(List icdO1Morphology) { _icdO1Morphology = icdO1Morphology; } - List getIcd10CmCode() { + public List getIcd10CmCode() { return _icd10CmCode; } @@ -251,7 +252,7 @@ public void setIcd10CmCode(List icd10CmCode) { _icd10CmCode = icd10CmCode; } - List getIcd10Code() { + public List getIcd10Code() { return _icd10Code; } @@ -259,7 +260,7 @@ public void setIcd10Code(List icd10Code) { _icd10Code = icd10Code; } - List getIcd9Code() { + public List getIcd9Code() { return _icd9Code; } @@ -267,7 +268,7 @@ public void setIcd9Code(List icd9Code) { _icd9Code = icd9Code; } - List getSigns() { + public List getSigns() { return _signs; } @@ -275,7 +276,7 @@ public void setSigns(List signs) { _signs = signs; } - List getExams() { + public List getExams() { return _exams; } @@ -283,7 +284,7 @@ public void setExams(List exams) { _exams = exams; } - List getRecurrence() { + public List getRecurrence() { return _recurrence; } @@ -291,7 +292,7 @@ public void setRecurrence(List recurrence) { _recurrence = recurrence; } - List getMortality() { + public List getMortality() { return _mortality; } @@ -307,7 +308,7 @@ public void setSource(List source) { _source = source; } - YearRange getIcdO3Effective() { + public YearRange getIcdO3Effective() { return _icdO3Effective; } @@ -315,7 +316,7 @@ public void setIcdO3Effective(YearRange icdO3Effective) { _icdO3Effective = icdO3Effective; } - YearRange getIcdO2Effective() { + public YearRange getIcdO2Effective() { return _icdO2Effective; } @@ -323,7 +324,7 @@ public void setIcdO2Effective(YearRange icdO2Effective) { _icdO2Effective = icdO2Effective; } - YearRange getIcdO1Effective() { + public YearRange getIcdO1Effective() { return _icdO1Effective; } @@ -331,7 +332,7 @@ public void setIcdO1Effective(YearRange icdO1Effective) { _icdO1Effective = icdO1Effective; } - List getMissingPrimarySiteMessage() { + public List getMissingPrimarySiteMessage() { return _missingPrimarySiteMessage; } @@ -339,7 +340,7 @@ public void setMissingPrimarySiteMessage(List missingPrimarySit _missingPrimarySiteMessage = missingPrimarySiteMessage; } - List getGrade() { + public List getGrade() { return _grade; } @@ -347,7 +348,7 @@ public void setGrade(List grade) { _grade = grade; } - List getTransformTo() { + public List getTransformTo() { return _transformTo; } @@ -355,7 +356,7 @@ public void setTransformTo(List transformTo) { _transformTo = transformTo; } - List getTransformFrom() { + public List getTransformFrom() { return _transformFrom; } @@ -379,7 +380,7 @@ public void setTransformToText(List transformToText) { _transformToText = transformToText; } - List getImmunophenotype() { + public List getImmunophenotype() { return _immunophenotype; } @@ -387,7 +388,7 @@ public void setImmunophenotype(List immunophenotype) { _immunophenotype = immunophenotype; } - List getDiagnosisMethod() { + public List getDiagnosisMethod() { return _diagnosisMethod; } @@ -395,7 +396,7 @@ public void setDiagnosisMethod(List diagnosisMethod) { _diagnosisMethod = diagnosisMethod; } - List getModuleId() { + public List getModuleId() { return _moduleId; } @@ -403,7 +404,7 @@ public void setModuleId(List moduleId) { _moduleId = moduleId; } - List getSamePrimaries() { + public List getSamePrimaries() { return _samePrimaries; } @@ -419,7 +420,7 @@ public void setSamePrimariesText(List samePrimariesText) { _samePrimariesText = samePrimariesText; } - List getBiomarkers() { + public List getBiomarkers() { return _biomarkers; } @@ -427,7 +428,7 @@ public void setBiomarkers(List biomarkers) { _biomarkers = biomarkers; } - List getTreatmentText() { + public List getTreatmentText() { return _treatmentText; } From 23e949991e01ec13d4d66a937f4f8cdad0981289 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 25 May 2018 15:01:34 -0400 Subject: [PATCH 018/243] Preparing release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 83c34a2..ac79c85 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.9 + 3.10 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.9' +compile 'com.imsweb:seerapi-client-java:3.10' ``` ## Usage diff --git a/build.gradle b/build.gradle index 7e40a89..4a747d9 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.10-SNAPSHOT' +version = '3.10' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From 4d7540d147c645b0653687117cb83a295398dadc Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 25 May 2018 15:08:17 -0400 Subject: [PATCH 019/243] Fixed link. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac79c85..e688a5b 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,6 @@ api.staging().schemaById("cs", "02.05.50", "brain").execute().body() ``` For a complete description of all available API inputs and outputs, see the SEER*API -[Documentation](https://api.seer.cancer.gov/api.do) page. +[Documentation](https://api.seer.cancer.gov/docs) page. [1]: http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.imsweb&a=seerapi-client-java&v=LATEST From abbed0ee5640e82a798267db08a8057974ce1caf Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 9 Jul 2018 14:38:47 -0400 Subject: [PATCH 020/243] Support new columns field in staging error --- README.md | 4 +- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.jar | Bin 54413 -> 54417 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- .../seerapi/client/staging/StagingError.java | 72 ++++++++++-------- 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index e688a5b..2e729c3 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.10 + 3.11 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.10' +compile 'com.imsweb:seerapi-client-java:3.11' ``` ## Usage diff --git a/build.gradle b/build.gradle index 4a747d9..b1f9c48 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.10' +version = '3.11' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -62,7 +62,7 @@ findbugs { } task wrapper(type: Wrapper) { - gradleVersion = '4.7' + gradleVersion = '4.8.1' } modifyPom { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 91ca28c8b802289c3a438766657a5e98f20eff03..758de960ec7947253b058ff79c88ce51f3abe08a 100644 GIT binary patch delta 676 zcmYk)T}V@590u^ce`_BwX;Cw`SqsGrC&`wT8k1(Ggu_`V=0Gr_sZh~0XniU|SEl89 zY#?Y-Hzi$2m>0E5*V*Pi)H!E2MPPJO3=H!&qSu#Y9XOod^SuA}a1Q4TPGor}vWCi3 zGZ)U+R>@?tX0NSL>HMbq*}dM)5O5h@ygdD0JGE50O?JwzP+lLZZqxFyUHpVs%EKY4 z_}^Z1N{wt3ZzKzw#hO&k(&&=spfYHpeGFg1TJ!`@P>Wn}UZuo+xf0*`s#UR7T~X*@ z51D98C8~i?Ii>e(t$q#J=u@tUN5gg0Z{##!#<&|DaScLYJ+ojne1?n%#EfIEf>b4f zk2nVo3$D$TQR<|iHFAX7?SkX=+3-bs}Sd6CKkkC%t{+BWVe^%cg#dRot!#U#~oB~2?1{&CgWA?71ra;q;rd+ z!L8nXAwpcHhSvitia_(4Wh#uHUEy8?gd=$3`dzo@G6yr|{XIkLhJINq)`}@n(f7J&VGY i>R@AdmTG5i>{vNy`2TOp{reo^8bIqxu{=-O41WNHN*rSV delta 734 zcmYk4?MqWp9LINl(x&CZEs?G3QZyo*xYXDh88%8PlyqT9ltqwPLKE>t(g;HEMP$~t z?}(NU3&CK~8xib5D%*o|o14!0BHvhVB81*pe}J71x3vq0`}v&jxtH%b_qzN!BmNxc zk-TSJFT=-GD%E+HwO!-=-M`h(R8Dz%_FSO&utsHT(d6DQ#85F`v6~NfNDoV}`u|h7 z9c*XMF(0gBAMq<_VVf9i(c(m?iu4T5XbIYwjIoe`I@Cg);aq$V)zeW;M$O@qG@7TV zg*LUBpG#03(fSPT%d2Ei4IjNsCGvhXkU#mTTKxr!V-+x(ZktUh~|`p z12LIhhc#wn0k~qv*cOtpt90)cin{mWbi9=+>_`pkaoMg#EN-ATy+S+V zB=G%^9vevm%?xvG#4BF+;<8NBk43uSRbzbFN>i?k{&Y!VQ*lprvpG*@fqkWc-ab_{ zAL}c%H0~8@Or4@TV*6>g6uhZSs8^EJL1x#yFY4*>k`}c*#{S&UORjYNuzw!r5nIvKW diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2489c8f..bb1e0c5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 18 09:06:34 EDT 2018 +#Mon Jul 09 14:37:08 EDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java index 3f583ea..335a547 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingError.java @@ -3,49 +3,23 @@ */ package com.imsweb.seerapi.client.staging; +import java.util.List; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** * An error object */ -@JsonPropertyOrder({"type", "table", "key", "message"}) +@JsonPropertyOrder({"type", "table", "columns", "key", "message"}) public class StagingError { private Type _type; private String _table; + private List _columns; private String _key; private String _message; - public enum Type { - // an input key was supplied that is not defined in the input definition - UNKNOWN_INPUT, - - // a required input value was not contained in the input definition table - INVALID_REQUIRED_INPUT, - - // a non-required input value was not contained in the input definition table - INVALID_NON_REQUIRED_INPUT, - - // an input mapping from value did not exist - UNKNOWN_INPUT_MAPPING, - - // an ERROR endpoint was hit during staging processing - STAGING_ERROR, - - // a table was processed during staging and no match was found - MATCH_NOT_FOUND, - - // a specified table does not exist - UNKNOWN_TABLE, - - // processing a table ended up in an infinite loop due to JUMPs - INFINITE_LOOP, - - // an output value was produced which was not contained in the output definition table - INVALID_OUTPUT - } - /** * Default constructor (required for Jackson) */ @@ -78,6 +52,15 @@ public void setTable(String table) { _table = table; } + @JsonProperty("columns") + public List getColumns() { + return _columns; + } + + public void setColumns(List columns) { + _columns = columns; + } + @JsonProperty("key") public String getKey() { return _key; @@ -96,4 +79,33 @@ public void setMessage(String message) { _message = message; } + public enum Type { + // an input key was supplied that is not defined in the input definition + UNKNOWN_INPUT, + + // a required input value was not contained in the input definition table + INVALID_REQUIRED_INPUT, + + // a non-required input value was not contained in the input definition table + INVALID_NON_REQUIRED_INPUT, + + // an input mapping from value did not exist + UNKNOWN_INPUT_MAPPING, + + // an ERROR endpoint was hit during staging processing + STAGING_ERROR, + + // a table was processed during staging and no match was found + MATCH_NOT_FOUND, + + // a specified table does not exist + UNKNOWN_TABLE, + + // processing a table ended up in an infinite loop due to JUMPs + INFINITE_LOOP, + + // an output value was produced which was not contained in the output definition table + INVALID_OUTPUT + } + } From dcfce265cd643fb6e248e56ab3eb3d37b8481bda Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 23 Jul 2018 15:48:22 -0400 Subject: [PATCH 021/243] Update Gradle wrapper --- build.gradle | 4 ++-- gradle/wrapper/gradle-wrapper.jar | Bin 54417 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index b1f9c48..16c33fc 100644 --- a/build.gradle +++ b/build.gradle @@ -61,8 +61,8 @@ findbugs { excludeFilter = file("config/findbugs/findbugs-exclude.xml") } -task wrapper(type: Wrapper) { - gradleVersion = '4.8.1' +wrapper { + gradleVersion = '4.9' } modifyPom { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 758de960ec7947253b058ff79c88ce51f3abe08a..0d4a9516871afd710a9d84d89e31ba77745607bd 100644 GIT binary patch delta 732 zcmYk4Ur19?9LINl)~4m3n;~1*r8tRj;+ldsTG*&j;mD0LiLwYROK2iKWQ|?~A0o3h zzap4_7J?6pUPQ=BD%&6DHm6Q~$R4bh2%#5!>&Z@s+uDW0{d~^%+{^czdwqed{y>)Z zc+T&yL!MJAm8!{SYf|rYZFe!1SDt!vF<7`q<#K4UACyiSVEQmpTWJ* zCH4Yyp=$OKJ0T0(LXSg>)8PuzGk9Y~a55RAVIwuGg?b~|_z|w56PmQvMb6Mjj-nRY z(x#K25gTpjgx1eD(Bo2p{&_ncGbpGYh+64zl`vOT0mdT|v?eK+msKu}NrWG2H3&p& z=t-@jdDx8_DRo|`ZJ~~CIRy4EIH}`;f_VcmGv8lz>^k${dF(1Rx9~&{Z%aNJQWB2D zW!4H?+{J?M#ZR(rEX8loqq`_*JA`wIMk;e7)u+cbw-)h)k!CuCwj@e%v@^4%wo?S{ zi*>97FBdP?lmGw# delta 674 zcmYk)T}V@590u^ce`_BwX^}IxS%%_;lVr!`V#{7~K>D!@P~?^<`NH4(Ing@BclV!#Ts#S?=kqkqXuP zh4b|_GMTK^ZEaC})BWsS?`2rD8(zFT^*$$2zD;)0rchoVsqNJAp+Rb5f&VDlMi zQYES(UnQk?Z>@gyS?N=rh)4VlG+4lCz=!dlOI4&Q6MV!u zbVzV*se)1`1TBHXk#o* z@F>~s=(iW+T*%107!Fxz!;Wl6Iev$X)Yr|aLv6T;iY{T%osXGt4SR+4a4YGYqG)!i z`5iSFi0EnGRbCZgAz~)AORzt>9ZfDROi?2}zLBXcG2Lu~p&2;mQ;Ja8o z&D|9&iPzEWJ Date: Mon, 8 Oct 2018 13:05:11 -0400 Subject: [PATCH 022/243] Added automatic module name --- build.gradle | 5 +++-- gradle/wrapper/gradle-wrapper.jar | Bin 54413 -> 56177 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 16c33fc..6e6ca42 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ dependencies { compile 'com.squareup.retrofit2:converter-jackson:2.4.0' testCompile 'junit:junit:4.11' - testCompile 'org.assertj:assertj-core:3.9.1' + testCompile 'org.assertj:assertj-core:3.11.1' } jar { @@ -47,6 +47,7 @@ jar { 'Built-By': System.getProperty('user.name'), 'Built-Date': new Date(), 'Built-JDK': System.getProperty('java.version'), + 'Automatic-Module-Name': 'com.imsweb.seerapi.client' ) } } @@ -62,7 +63,7 @@ findbugs { } wrapper { - gradleVersion = '4.9' + gradleVersion = '4.10.2' } modifyPom { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 0d4a9516871afd710a9d84d89e31ba77745607bd..29953ea141f55e3b8fc691d31b5ca8816d89fa87 100644 GIT binary patch delta 49463 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

Gauk6VzRKaGELdj)1bl0ug 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 Date: Thu, 11 Oct 2018 09:50:27 -0400 Subject: [PATCH 023/243] Updates for recent changes to SEER*API - Change method signature of samePrimaries call - Added new field to NdcSeerInfo --- README.md | 4 ++-- build.gradle | 2 +- .../client/disease/DiseaseService.java | 5 +++-- .../seerapi/client/disease/SamePrimaries.java | 22 ++++++++++++------- .../seerapi/client/ndc/NdcSeerInfo.java | 12 +++++----- .../seerapi/client/disease/DiseaseTest.java | 17 +++++++++++--- .../imsweb/seerapi/client/ndc/NdcTest.java | 8 +++++++ 7 files changed, 47 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 2e729c3..c7ddae5 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.11 + 3.12 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.11' +compile 'com.imsweb:seerapi-client-java:3.12' ``` ## Usage diff --git a/build.gradle b/build.gradle index 6e6ca42..d027824 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.11' +version = '3.12' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java index 0d39063..bfd2b95 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java @@ -87,11 +87,12 @@ public interface DiseaseService { * @param version Disease version * @param morphology1 ICD O3 Morphology * @param morphology2 ICD O3 Morphology - * @param year Year of Diagnosis + * @param year1 Year of Diagnosis1 + * @param year1 Year of Diagnosis2 * @return a SamePrimary object */ @GET("disease/{version}/same_primary") - Call samePrimaries(@Path("version") String version, @Query("d1") String morphology1, @Query("d2") String morphology2, @Query("year") String year); + Call samePrimaries(@Path("version") String version, @Query("d1") String morphology1, @Query("d2") String morphology2, @Query("year1") String year1, @Query("year2") String year2); /** * Returns the reportable year range of the supplied disease. diff --git a/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java b/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java index 71ce2fb..db12705 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/SamePrimaries.java @@ -8,8 +8,10 @@ public class SamePrimaries { protected String _disease1; @JsonProperty("disease2") protected String _disease2; - @JsonProperty("year") - protected Integer _year; + @JsonProperty("year1") + protected Integer _year1; + @JsonProperty("year2") + protected Integer _year2; @JsonProperty("is_same") protected Boolean _isSame; @@ -29,16 +31,20 @@ public void setDisease2(String disease2) { _disease2 = disease2; } - public Integer getYear() { - return _year; + public Integer getYear1() { + return _year1; } - public void setYear(Integer year) { - _year = year; + public void setYear1(Integer year1) { + _year1 = year1; } - public Boolean isSame() { - return _isSame; + public Integer getYear2() { + return _year2; + } + + public void setYear2(Integer year2) { + _year2 = year2; } public Boolean getIsSame() { diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java index 84c98a9..d5fdecf 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -6,24 +6,26 @@ import java.util.Date; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"seer_rx_id", "categories", "subcategory", "major_drug_class", "minor_drug_class", "orphan_drug", "date_modified"}) +@JsonPropertyOrder({"seer_rx_id", "categories", "subcategory", "major_drug_class", "minor_drug_class", "orphan_drug", "exclusive_oncologic_agent", "date_modified"}) +@JsonIgnoreProperties(ignoreUnknown = true) public class NdcSeerInfo { @JsonProperty("seer_rx_id") private String _seerRxId; @JsonProperty("categories") private List _categories; - @JsonProperty("subcategory") - private String _subcategory; @JsonProperty("major_drug_class") private String _majorDrugClass; @JsonProperty("minor_drug_class") private String _minorDrugClass; @JsonProperty("orphan_drug") private Boolean _orphanDrug; + @JsonProperty("exclusive_oncologic_agent") + private Boolean _exclusiveAgent; @JsonProperty("date_modified") private Date _dateModified; @@ -35,10 +37,6 @@ public List getCategories() { return _categories; } - public String getSubcategory() { - return _subcategory; - } - public String getMajorDrugClass() { return _majorDrugClass; } diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index a427243..e83edd8 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -151,11 +151,22 @@ public void testDiseaseById() throws IOException { @Test public void testDiseaseSamePrimary() throws IOException { - SamePrimaries same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010").execute().body(); + SamePrimaries same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010", "2010").execute().body(); assertNotNull(same); - assertEquals(false, same.isSame()); - assertEquals(2010, same.getYear().longValue()); + assertEquals(false, same.getIsSame()); + assertEquals(2010, same.getYear1().longValue()); + assertEquals(2010, same.getYear2().longValue()); + assertEquals("9870/3", same.getDisease1()); + assertEquals("9872/3", same.getDisease2()); + + // try same with different years + same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010", "2015").execute().body(); + + assertNotNull(same); + assertEquals(false, same.getIsSame()); + assertEquals(2010, same.getYear1().longValue()); + assertEquals(2015, same.getYear2().longValue()); assertEquals("9870/3", same.getDisease1()); assertEquals("9872/3", same.getDisease2()); } diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index eab07e6..0ec17dc 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -16,6 +16,7 @@ import static org.assertj.core.api.Assertions.assertThat; +@SuppressWarnings("ConstantConditions") public class NdcTest { private static NdcService _NDC; @@ -66,6 +67,13 @@ public void testNdcByCode() throws IOException { assertThat(product.getProprietaryName()).isEqualTo("Verzenio"); assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.CHEMOTHERAPY); + assertThat(product.getSeerInfo().getMajorDrugClass()).startsWith("Cyclin dependent"); + assertThat(product.getSeerInfo().getMinorDrugClass()).isEqualTo("CDK 4/6"); + + // the subcategory is being removed but still exists in production; the key should be ignored + product = _NDC.getByCode("0006-0072").execute().body(); + assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); + assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.ANCILLARY); } @Test From 8545f58f1443ea8153df9e0897524625286a5bc2 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 11 Oct 2018 10:12:29 -0400 Subject: [PATCH 024/243] Fixed bad Javadoc. --- .../java/com/imsweb/seerapi/client/disease/DiseaseService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java index bfd2b95..003001d 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseService.java @@ -88,7 +88,7 @@ public interface DiseaseService { * @param morphology1 ICD O3 Morphology * @param morphology2 ICD O3 Morphology * @param year1 Year of Diagnosis1 - * @param year1 Year of Diagnosis2 + * @param year2 Year of Diagnosis2 * @return a SamePrimary object */ @GET("disease/{version}/same_primary") From 33cdab88338991f07921c36c45e50dd5f8ded1dd Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 15 Oct 2018 11:52:00 -0400 Subject: [PATCH 025/243] Forgot to add a getter for now field. --- README.md | 4 ++-- build.gradle | 2 +- src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c7ddae5..d4de4d3 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.12 + 3.13 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.12' +compile 'com.imsweb:seerapi-client-java:3.13' ``` ## Usage diff --git a/build.gradle b/build.gradle index d027824..ba84cb4 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.12' +version = '3.13' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java index d5fdecf..13a3fbc 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -49,6 +49,10 @@ public Boolean getOrphanDrug() { return _orphanDrug; } + public Boolean getExclusiveAgent() { + return _exclusiveAgent; + } + public Date getDateModified() { return _dateModified; } From cc62dc7839304759219bdd8068f23c418b497922 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 15 Oct 2018 11:52:46 -0400 Subject: [PATCH 026/243] Removed reference to deleted "subcategory" field --- src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java index 13a3fbc..cda7772 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -10,7 +10,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"seer_rx_id", "categories", "subcategory", "major_drug_class", "minor_drug_class", "orphan_drug", "exclusive_oncologic_agent", "date_modified"}) +@JsonPropertyOrder({"seer_rx_id", "categories", "major_drug_class", "minor_drug_class", "orphan_drug", "exclusive_oncologic_agent", "date_modified"}) @JsonIgnoreProperties(ignoreUnknown = true) public class NdcSeerInfo { From eac1811b362853ebf7e00ca0aad96a5cb334913f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 13 Nov 2018 10:28:59 -0500 Subject: [PATCH 027/243] Add wrapper dist type --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index ba84cb4..d40954d 100644 --- a/build.gradle +++ b/build.gradle @@ -64,6 +64,7 @@ findbugs { wrapper { gradleVersion = '4.10.2' + distributionType = Wrapper.DistributionType.ALL } modifyPom { From b45a8feb0d980480baea113b3d226477869bea40 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 25 Jan 2019 15:16:46 -0500 Subject: [PATCH 028/243] Dependency updates --- .circleci/config.yml | 29 +++++++++++++++++++ .travis.yml | 17 ----------- README.md | 2 +- build.gradle | 15 ++++------ .../spotbugs-exclude.xml} | 0 gradle/wrapper/gradle-wrapper.properties | 3 +- .../imsweb/seerapi/client/mph/MphService.java | 2 +- .../seerapi/client/disease/DiseaseTest.java | 17 ++++------- .../seerapi/client/glossary/GlossaryTest.java | 16 ++++++---- .../com/imsweb/seerapi/client/rx/RxTest.java | 12 ++++---- 10 files changed, 60 insertions(+), 53 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 .travis.yml rename config/{findbugs/findbugs-exclude.xml => spotbugs/spotbugs-exclude.xml} (100%) diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..d74c1d1 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,29 @@ +version: 2.0 +jobs: + build: + docker: + - image: circleci/openjdk:8-jdk + environment: + JVM_OPTS: -Xmx512m + steps: + - checkout + - restore_cache: + keys: + - gradle-{{ checksum "build.gradle" }} + - run: + name: Run tests + command: gradle assemble test + - run: + name: Save test results + command: | + mkdir -p ~/junit/ + find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \; + when: always + - store_test_results: + path: ~/junit + - store_artifacts: + path: ~/junit + - save_cache: + paths: + - ~/.gradle + key: gradle-{{ checksum "build.gradle" }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f1d3876..0000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: java - -jdk: -- oraclejdk8 - -before_install: -- chmod +x gradlew - -env: - global: - - secure: ahfNxDTQyt3G0nI/XQZHTUQUzlv4z0FLk8OycmxbK2HzX29d/XyyF0EJKDJ4IqjsIR3++i/DP9j6BSW4Rrl7WpuvkKjArwIVXgs0vHHsII0CKPMi3D+7KxreWutONGNuxfJoW17vl9Sp/2lwGP7s0asFGdt/C3F6sj23l/dobiQ= - -notifications: - email: - - mayc@imsweb.com - - depryf@imsweb.com - diff --git a/README.md b/README.md index d4de4d3..91d357f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # seerapi-client-java -[![Build Status](https://travis-ci.org/imsweb/seerapi-client-java.svg?branch=master)](https://travis-ci.org/imsweb/seerapi-client-java) +[![CircleCI](https://circleci.com/gh/imsweb/seerapi-client-java.svg?style=svg)](https://circleci.com/gh/imsweb/seerapi-client-java) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and diff --git a/build.gradle b/build.gradle index d40954d..ef20144 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,9 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java' id 'checkstyle' - id 'findbugs' + id "com.github.spotbugs" version "1.6.5" id 'com.bmuschko.nexus' version '2.3.1' - id "io.codearte.nexus-staging" version "0.11.0" - id 'net.ossindex.audit' version '0.1.1' + id "io.codearte.nexus-staging" version "0.20.0" } group = 'com.imsweb' @@ -52,18 +51,16 @@ jar { } } -// checkstyle plugin settings checkstyle { configFile = file("config/checkstyle/checkstyle.xml") } -// findbugs plugin settings -findbugs { - excludeFilter = file("config/findbugs/findbugs-exclude.xml") +spotbugs { + toolVersion = '3.1.8' + excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } - wrapper { - gradleVersion = '4.10.2' + gradleVersion = '5.1.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/config/findbugs/findbugs-exclude.xml b/config/spotbugs/spotbugs-exclude.xml similarity index 100% rename from config/findbugs/findbugs-exclude.xml rename to config/spotbugs/spotbugs-exclude.xml diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 892aef9..c4486d4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Mon Oct 08 13:02:30 EDT 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphService.java b/src/main/java/com/imsweb/seerapi/client/mph/MphService.java index adb9dc7..ad31228 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphService.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphService.java @@ -23,7 +23,7 @@ public interface MphService { /** * Uses multiple primary rules to compare two diseases * @param pair a pair of diseases - * @param matchMode + * @param matchMode match mode * @return a result indicating whether the two diseases are the same primary */ @POST("mph") diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index e83edd8..71daa61 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -36,17 +36,12 @@ public void testDiseaseTypeCategory() { public void testDiseaseVersions() throws IOException { List versions = _DISEASE.versions().execute().body(); - assertTrue(versions.size() > 0); - for (DiseaseVersion version : versions) { - assertTrue(version.getName().length() > 0); - assertTrue(version.getType().length() > 0); - assertNotNull(version.getLastModified()); - if (version.getName().equals("latest")) { - assertNotNull(version.getType()); - assertNotNull(version.getFirstPublished()); - assertNotNull(version.getCount()); - } - } + assertEquals(1, versions.size()); + DiseaseVersion version = versions.get(0); + assertEquals("latest", version.getName()); + assertNull(version.getType()); // type not returned when no permisisons + assertNotNull(version.getFirstPublished()); + assertNotNull(version.getCount()); } @Test diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index 5d44360..2f6cfed 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -15,6 +15,10 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + public class GlossaryTest { private static GlossaryService _GLOSSARY; @@ -33,12 +37,12 @@ public void testGlossaryCategory() { public void testGlossaryVersions() throws IOException { List versions = _GLOSSARY.versions().execute().body(); - Assert.assertTrue(versions.size() > 0); - for (GlossaryVersion version : versions) { - Assert.assertTrue(version.getName().length() > 0); - Assert.assertTrue(version.getType().length() > 0); - Assert.assertNotNull(version.getLastModified()); - } + assertEquals(1, versions.size()); + GlossaryVersion version = versions.get(0); + assertEquals("latest", version.getName()); + assertNull(version.getType()); // type not returned when no permisisons + assertNotNull(version.getFirstPublished()); + assertNotNull(version.getCount()); } @Test diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index b33a499..fad1ca7 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -33,12 +33,12 @@ public static void setup() { public void testRxVersions() throws IOException { List versions = _RX.versions().execute().body(); - assertTrue(versions.size() > 0); - for (RxVersion version : versions) { - assertTrue(version.getName().length() > 0); - assertTrue(version.getType().length() > 0); - assertNotNull(version.getLastModified()); - } + assertEquals(1, versions.size()); + RxVersion version = versions.get(0); + assertEquals("latest", version.getName()); + assertNull(version.getType()); // type not returned when no permisisons + assertNotNull(version.getFirstPublished()); + assertNotNull(version.getCount()); } @Test From b93f47483c532f6c7fd012999edf1e1e5d2b7cb0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 25 Jan 2019 15:18:03 -0500 Subject: [PATCH 029/243] Dependency updates --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ef20144..822c3d1 100644 --- a/build.gradle +++ b/build.gradle @@ -27,8 +27,8 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.4.0' - compile 'com.squareup.retrofit2:converter-jackson:2.4.0' + compile 'com.squareup.retrofit2:retrofit:2.5.0' + compile 'com.squareup.retrofit2:converter-jackson:2.5.0' testCompile 'junit:junit:4.11' testCompile 'org.assertj:assertj-core:3.11.1' From f83f17135aa295cefd1e15f72aa238fd56c4e706 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 8 Feb 2019 10:47:41 -0500 Subject: [PATCH 030/243] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91d357f..22ff3df 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # seerapi-client-java -[![CircleCI](https://circleci.com/gh/imsweb/seerapi-client-java.svg?style=svg)](https://circleci.com/gh/imsweb/seerapi-client-java) +[![CircleCI](https://circleci.com/gh/imsweb/seerapi-client-java.svg?style=shield)](https://circleci.com/gh/imsweb/seerapi-client-java) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and From 0c80cce6b21fda8ccbe5efe605718aeaa3144f6b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 8 Feb 2019 10:54:20 -0500 Subject: [PATCH 031/243] Use Gradle wrapper --- .circleci/config.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d74c1d1..de4798c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,9 +10,12 @@ jobs: - restore_cache: keys: - gradle-{{ checksum "build.gradle" }} + - run: + name: chmod permissions + command: chmod +x ./gradlew - run: name: Run tests - command: gradle assemble test + command: ./gradlew assemble test - run: name: Save test results command: | From 3e3d773eedfcbd5f0345b95d77de64cdb9e1a853 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 8 Feb 2019 16:32:42 -0500 Subject: [PATCH 032/243] Spotbugs was not running --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index de4798c..6032e38 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: command: chmod +x ./gradlew - run: name: Run tests - command: ./gradlew assemble test + command: ./gradlew build - run: name: Save test results command: | From c1917a7961998d6b64cbc78a21a50c0e68610bcf Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 11 Feb 2019 09:03:41 -0500 Subject: [PATCH 033/243] Checkstyle fixes --- .circleci/config.yml | 2 +- build.gradle | 7 ++++++- config/checkstyle/checkstyle-exclude.xml | 9 --------- config/checkstyle/checkstyle.xml | 6 +----- gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 55190 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- gradlew.bat | 2 +- 8 files changed, 11 insertions(+), 19 deletions(-) delete mode 100644 config/checkstyle/checkstyle-exclude.xml diff --git a/.circleci/config.yml b/.circleci/config.yml index 6032e38..fa5485e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,7 +15,7 @@ jobs: command: chmod +x ./gradlew - run: name: Run tests - command: ./gradlew build + command: ./gradlew check - run: name: Save test results command: | diff --git a/build.gradle b/build.gradle index 822c3d1..c3c8a5a 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ plugins { id "com.github.spotbugs" version "1.6.5" id 'com.bmuschko.nexus' version '2.3.1' id "io.codearte.nexus-staging" version "0.20.0" + id 'com.adarshr.test-logger' version '1.6.0' } group = 'com.imsweb' @@ -51,6 +52,10 @@ jar { } } +testlogger { + theme 'mocha' +} + checkstyle { configFile = file("config/checkstyle/checkstyle.xml") } @@ -60,7 +65,7 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } wrapper { - gradleVersion = '5.1.1' + gradleVersion = '5.2.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/config/checkstyle/checkstyle-exclude.xml b/config/checkstyle/checkstyle-exclude.xml deleted file mode 100644 index 9d941ec..0000000 --- a/config/checkstyle/checkstyle-exclude.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index a58e86b..33d228b 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -1,8 +1,7 @@ - - + @@ -162,8 +161,5 @@ - - - diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea141f55e3b8fc691d31b5ca8816d89fa87..87b738cbd051603d91cc39de6cb000dd98fe6b02 100644 GIT binary patch delta 46897 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 delta 47854 zcmY(KQ*DWo<_WjQ}7Y{XRz3dwMVU4-Q zn%}IHTCm#|FbG8%FmSZ^JoI=RR8%w&kni6?KtO~*dN9W%g#T3<@q%*b#-shs8K>Ad zr`Wenw@%+c{`&~&xBr}5L;ue^5&RoI=KuWw38x$_I|K*_BMb-#ePSFbMxy*Te87D{ z9O*B{gu1cl_hD#GL1RfGHwO0Nq?DkNU&Lg);5Z^>(8W|w>&T-Ht)1=jBnuC$yK|!S;vP}>MV^c_r5GVcLs=nH^?rC-*=KA7NJXV?cuDb zS0XP*_AqA;t}qDGK_~w2gbd*IVL+s@XEB%-ar>e_Id-a96hu9C?RXo?piLW%$X3{o z6thF_ILtq7nlQ%HZieLF;a5y`uYWPL6cf4i#ThY!$5@7#D=@tn--Z8>zpi^Ws~JMrK>!OEzJ*l%TcY-YNr$DuvZ&5SeAQcQ`&2vpVPD^i~w>A3>y#3 zrPkuZ>hzg9iEw`#R+-_3Qs!3{ajlg#qK%nNbTX8(T*x!hvzA@>&khT<#UkpOqnSiz z;kisws8VZ&2jH@6o|>$cp12n3Ug>#?E03JkRqwNcke`G4t`38PU9zR|7?hS{!i;3} zY$eEqVL$O&H70pQ46^-)U;*x#H7N~=l&#8xMtrDfSdx&zk=RUwu;t7hXv^|m9!t5~+VRoN)j*{uEY6gE+W6zvCY z4#_@qY<5c#W_iWMD6M)YpLH%QD~Zvgm&QqmFBty5yi})XlHatyTj=KBRr@Snbo(%05sx7WMs$AydwDW?C

ohmj(wKVBMg2V`Or6Dh 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c4486d4..1b2b07c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d..af6708f 100644 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index f955316..6d57edc 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome From 3f5d0518e1205c43d707d89ac637db7a5d43c3a2 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 11 Feb 2019 09:04:25 -0500 Subject: [PATCH 034/243] Newer Spotbugs version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c3c8a5a..f8e5536 100644 --- a/build.gradle +++ b/build.gradle @@ -61,7 +61,7 @@ checkstyle { } spotbugs { - toolVersion = '3.1.8' + toolVersion = '3.1.11' excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } wrapper { From aa94742cb7bd28fc00f6b29a5e9a3a815b63053b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 22 Feb 2019 11:12:06 -0500 Subject: [PATCH 035/243] Cleanup --- build.gradle | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index f8e5536..299e2c3 100644 --- a/build.gradle +++ b/build.gradle @@ -15,12 +15,14 @@ description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" -// UTF-8 for all compilation tasks -[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' - -// fail the build if there are compiler warnings tasks.withType(JavaCompile) { - options.compilerArgs << "-Xlint:all" << "-Xlint:-processing" << "-Xlint:-serial" << "-Werror" + options.encoding = 'UTF-8' + options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Werror" +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } repositories { From 6269b6d247e2975a93a9f80c572a798b6e21cb5f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 4 Mar 2019 11:29:06 -0500 Subject: [PATCH 036/243] Added support for "section" and "default_value" in NAACCR field. --- build.gradle | 4 ++-- .../seerapi/client/naaccr/NaaccrField.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 299e2c3..a4f0f17 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.13' +version = '3.14' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -63,7 +63,7 @@ checkstyle { } spotbugs { - toolVersion = '3.1.11' + toolVersion = '3.1.12' excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } wrapper { diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java index 4b79e68..db3696f 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java @@ -6,13 +6,17 @@ import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +@JsonPropertyOrder({"item", "name", "section", "start_col", "end_col", "alignment", "padding_char", "default_value", "documentation", "subfield"}) public class NaaccrField { @JsonProperty("item") protected Integer _item; @JsonProperty("name") protected String _name; + @JsonProperty("section") + protected String _section; @JsonProperty("start_col") protected Integer _start; @JsonProperty("end_col") @@ -21,6 +25,8 @@ public class NaaccrField { protected String _align; @JsonProperty("padding_char") protected String _padChar; + @JsonProperty("default_value") + protected String _defaultValue; @JsonProperty("documentation") protected String _documentation; @JsonProperty("subfield") @@ -42,6 +48,14 @@ public void setName(String name) { _name = name; } + public String getSection() { + return _section; + } + + public void setSection(String section) { + _section = section; + } + public Integer getStart() { return _start; } @@ -74,6 +88,14 @@ public void setPadChar(String padChar) { _padChar = padChar; } + public String getDefaultValue() { + return _defaultValue; + } + + public void setDefaultValue(String defaultValue) { + _defaultValue = defaultValue; + } + public String getDocumentation() { return _documentation; } From bbe7ec85a336061145a141c49b2b47c9b8df6e76 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 4 Mar 2019 11:29:33 -0500 Subject: [PATCH 037/243] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22ff3df..7cd3c32 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.13 + 3.14 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.13' +compile 'com.imsweb:seerapi-client-java:3.14' ``` ## Usage From e45a6057def389f397efefb44a2b7f755f2616d7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 4 Mar 2019 11:34:19 -0500 Subject: [PATCH 038/243] Update Spotbugs plugin --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a4f0f17..493139e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java' id 'checkstyle' - id "com.github.spotbugs" version "1.6.5" + id "com.github.spotbugs" version "1.6.10" id 'com.bmuschko.nexus' version '2.3.1' id "io.codearte.nexus-staging" version "0.20.0" id 'com.adarshr.test-logger' version '1.6.0' From e25b12c8738d25e3b1366c6e2f8a6655d19da792 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 5 Mar 2019 09:57:23 -0500 Subject: [PATCH 039/243] Added test cases for new NAACCR API fields --- .../java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index 84e56d6..cb2125a 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -54,6 +54,7 @@ public void testNaaccrField() throws IOException { assertThat(name).isNotNull(); assertThat(name.getName()).isEqualTo("Morph--Type&Behav ICD-O-3"); + assertThat(name.getSection()).isEqualTo("Cancer Identification"); assertThat(name.getAlign()).isEqualTo("LEFT"); assertThat(name.getPadChar()).isEqualTo(" "); assertThat(name.getDocumentation()).startsWith("

"); @@ -70,6 +71,12 @@ public void testNaaccrField() throws IOException { assertThat(sub.getEnd()).isEqualTo(553); assertThat(sub.getAlign()).isEqualTo("LEFT"); assertThat(sub.getPadChar()).isEqualTo(" "); + + // test one with default value + NaaccrField recordID = _NAACCR.field("18", 10).execute().body(); + assertThat(recordID.getName()).isEqualTo("Record Type"); + assertThat(recordID.getSection()).isEqualTo("Record ID"); + assertThat(recordID.getDefaultValue()).isEqualTo("A"); } } From faf674dfd019c689a76798f7915ba60202748555 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 5 Mar 2019 09:59:24 -0500 Subject: [PATCH 040/243] Fixed warnings --- .../java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index cb2125a..cbd6279 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -13,7 +13,6 @@ import static org.assertj.core.api.Assertions.assertThat; - public class NaaccrTest { private static NaaccrService _NAACCR; @@ -41,7 +40,7 @@ public void testNaaccrVersions() throws IOException { public void testNaaccrFieldNames() throws IOException { List names = _NAACCR.fieldNames("latest").execute().body(); - assertThat(names).isNotEmpty(); + assertThat(names).isNotNull(); for (NaaccrFieldName name : names) { assertThat(name.getItem()).isGreaterThan(0); assertThat(name.getName()).isNotEmpty(); @@ -74,6 +73,7 @@ public void testNaaccrField() throws IOException { // test one with default value NaaccrField recordID = _NAACCR.field("18", 10).execute().body(); + assertThat(recordID).isNotNull(); assertThat(recordID.getName()).isEqualTo("Record Type"); assertThat(recordID.getSection()).isEqualTo("Record ID"); assertThat(recordID.getDefaultValue()).isEqualTo("A"); From 04f509961c3a5ece7b232ecb8d8cb8f89d810a85 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 5 Mar 2019 09:59:41 -0500 Subject: [PATCH 041/243] Fixed warnings --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 493139e..ad53f11 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.14' +version = '3.15-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From 31c81f58633ba4494e70f6ae2161b35b195fbac9 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 3 Jun 2019 14:16:00 -0400 Subject: [PATCH 042/243] Added support for HCPCS API (#22) --- build.gradle | 4 +- gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 18 ++- gradlew.bat | 18 ++- .../com/imsweb/seerapi/client/SeerApi.java | 11 ++ .../imsweb/seerapi/client/hcpcs/Hcpcs.java | 115 ++++++++++++++++++ .../seerapi/client/hcpcs/HcpcsService.java | 28 +++++ .../client/hcpcs/HcpcsServiceTest.java | 91 ++++++++++++++ 9 files changed, 282 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java create mode 100644 src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java create mode 100644 src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java diff --git a/build.gradle b/build.gradle index ad53f11..eebc0ec 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { } group = 'com.imsweb' -version = '3.15-SNAPSHOT' +version = '3.15' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -67,7 +67,7 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } wrapper { - gradleVersion = '5.2.1' + gradleVersion = '5.4.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch delta 3320 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 _brandNames; + @JsonProperty("strength") + private String _strength; + @JsonProperty("fda_approval_year") + private String _fdaApprovalYear; + @JsonProperty("fda_discontinuation_year") + private String _fdaDiscontinuationYear; + @JsonProperty("cms_approval_date") + private String _cmsApprovalDate; + @JsonProperty("cms_discontinuation_date") + private String _cmsDiscontinuationDate; + @JsonProperty("categories") + private List _categories; + @JsonProperty("major_drug_class") + private String _majorDrugClass; + @JsonProperty("minor_drug_class") + private String _minorDrugClass; + @JsonProperty("oral") + private Boolean _oral; + @JsonProperty("date_added") + private Date _dateAdded; + @JsonProperty("date_modified") + private Date _dateModified; + @JsonProperty("score") + private Double score; + + public String getHcpcsCode() { + return _hcpcsCode; + } + + public String getGenericName() { + return _genericName; + } + + public List getBrandNames() { + return _brandNames; + } + + public String getStrength() { + return _strength; + } + + public String getFdaApprovalYear() { + return _fdaApprovalYear; + } + + public String getFdaDiscontinuationYear() { + return _fdaDiscontinuationYear; + } + + public String getCmsApprovalDate() { + return _cmsApprovalDate; + } + + public String getCmsDiscontinuationDate() { + return _cmsDiscontinuationDate; + } + + public List getCategories() { + return _categories; + } + + public String getMajorDrugClass() { + return _majorDrugClass; + } + + public String getMinorDrugClass() { + return _minorDrugClass; + } + + public Boolean getOral() { + return _oral; + } + + public Date getDateAdded() { + return _dateAdded; + } + + public Date getDateModified() { + return _dateModified; + } + + public Double getScore() { + return score; + } + + // drug categories + public enum Category { + HORMONAL_THERAPY, + ANCILLARY, + CHEMOTHERAPY, + IMMUNOTHERAPY, + RADIOPHARMACEUTICAL; + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java b/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java new file mode 100644 index 0000000..55e7f60 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.hcpcs; + +import java.util.List; +import java.util.Map; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; +import retrofit2.http.QueryMap; + +public interface HcpcsService { + + /** + * Return an HCPCS entity based on code. + */ + @GET("hcpcs/code/{code}") + Call getProcedure(@Path("code") String code); + + /** + * Return a list of matching HCPCS procedures + */ + @GET("hcpcs") + Call> search(@QueryMap Map searchParams); + +} diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java new file mode 100644 index 0000000..78e8ff3 --- /dev/null +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -0,0 +1,91 @@ +package com.imsweb.seerapi.client.hcpcs; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.junit.BeforeClass; +import org.junit.Test; + +import retrofit2.Response; + +import com.imsweb.seerapi.client.NotFoundException; +import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.hcpcs.Hcpcs.Category; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; + +public class HcpcsServiceTest { + + private static HcpcsService _HCPCS; + + @BeforeClass + public static void setup() { + _HCPCS = new SeerApi.Builder().connect().hcpcs(); + } + + @Test + public void testGetProcedureByCode() throws IOException { + Hcpcs proc = _HCPCS.getProcedure("S0087").execute().body(); + + assertThat(proc).isNotNull(); + assertThat(proc.getHcpcsCode()).isEqualTo("S0087"); + assertThat(proc.getGenericName()).isEqualTo("Alemtuzumab"); + assertThat(proc.getBrandNames()).containsExactly("Campath"); + assertThat(proc.getStrength()).isEqualTo("30 mg"); + assertThat(proc.getFdaApprovalYear()).isEqualTo("2001"); + assertThat(proc.getFdaDiscontinuationYear()).isEqualTo("2012"); + assertThat(proc.getCmsApprovalDate()).isEqualTo("2002-01-01"); + assertThat(proc.getCmsDiscontinuationDate()).isEqualTo("2002-12-31"); + assertThat(proc.getCategories()).containsExactly(Category.IMMUNOTHERAPY); + assertThat(proc.getMajorDrugClass()).isEqualTo("Monoclonal Antibody"); + assertThat(proc.getMinorDrugClass()).isEqualTo("CD52"); + assertThat(proc.getOral()).isEqualTo(false); + assertThat(proc.getDateAdded()).isNotNull(); + assertThat(proc.getDateModified()).isNotNull(); + + assertThatExceptionOfType(NotFoundException.class) + .isThrownBy(() -> _HCPCS.getProcedure("bad_code").execute()) + .withMessage("HCPCS code '%s' does not exist.", "bad_code"); + } + + @Test + public void testSearch() throws IOException { + Response> response = _HCPCS.search(new HashMap<>()).execute(); + assertThat(response.headers().get("X-Total-Count")).isNotNull(); + assertThat(Integer.valueOf(Objects.requireNonNull(response.headers().get("X-Total-Count")))).isGreaterThan(100); + + List results = response.body(); + assertThat(results).hasSize(25); // default page size is 25 + + Map params = new HashMap<>(); + params.put("page", "2"); + + // test second page + assertThat(_HCPCS.search(params).execute().body()).hasSize(25); + + // test page out of range + params.put("page", "1000"); + assertThat(_HCPCS.search(params).execute().body()).hasSize(0); + + // test searching + params.clear(); + params.put("q", "Ixempra"); + results = _HCPCS.search(params).execute().body(); + assertThat(results).hasSize(2); + assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); + assertThat(Objects.requireNonNull(results).get(0).getScore()).isGreaterThan(0); + + // test categories + params.put("category", Category.CHEMOTHERAPY.toString()); + results = _HCPCS.search(params).execute().body(); + assertThat(results).hasSize(2); + assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); + + params.put("category", Category.IMMUNOTHERAPY.toString()); + assertThat(_HCPCS.search(params).execute().body()).hasSize(0); + } +} \ No newline at end of file From c271774ff1c51a54150f1a7ff1596982235a6727 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 3 Jun 2019 14:20:27 -0400 Subject: [PATCH 043/243] Suppress Checkstyle warning (#22) --- config/checkstyle/checkstyle.xml | 3 +++ config/checkstyle/suppressions.xml | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 config/checkstyle/suppressions.xml diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 33d228b..2b758ef 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -161,5 +161,8 @@ + + + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 0000000..2bc44d3 --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,7 @@ + + + + + + + From 55ad49c6a684cea9496a525647e0f8016d81790b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 3 Jun 2019 14:23:17 -0400 Subject: [PATCH 044/243] Fixed failing unit test (#22) --- src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 0ec17dc..bf5f5af 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -94,7 +94,7 @@ public void testNdcSearch() throws IOException { products = _NDC.search(search.paramMap()).execute().body(); assertThat(products.size()).isGreaterThan(1); - search.setRemovedSince("2016-07-21"); + search.setRemovedSince("2019-06-03"); products = _NDC.search(search.paramMap()).execute().body(); assertThat(products).isEmpty(); From a353bb1153929f357ce98f2ef78b284ee297576f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 3 Jun 2019 14:31:52 -0400 Subject: [PATCH 045/243] Added help text for new endpoints (#22) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7cd3c32..8e665ea 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,10 @@ The site-specific surgery tables available on the SEER website. api.surgery().tables().execute().body() ``` +### HCPCS + +Healthcare Common Procedure Coding Systems (HCPCS) nomenclatures. The information is maintained through [CanMED](https://seer.cancer.gov/oncologytoolbox). + ### Staging Cancer staging algorithms. Currently supports Collaborative Stage which is a unified data collection system designed to provide a From 10a4c90ec3c53f5166af316ce91ffd344cad7537 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 3 Jun 2019 14:32:14 -0400 Subject: [PATCH 046/243] Update version number in README (#22) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e665ea..f30d2a4 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.14 + 3.15 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.14' +compile 'com.imsweb:seerapi-client-java:3.15' ``` ## Usage From fbe7ca773dc280130b6015ef37dc624b0aa7517e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 3 Jun 2019 15:10:28 -0400 Subject: [PATCH 047/243] Update README (#22) --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f30d2a4..188e059 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,10 @@ api.surgery().tables().execute().body() Healthcare Common Procedure Coding Systems (HCPCS) nomenclatures. The information is maintained through [CanMED](https://seer.cancer.gov/oncologytoolbox). +```java +api.hcpcs().getProcedure("S0087").execute().body(); +``` + ### Staging Cancer staging algorithms. Currently supports Collaborative Stage which is a unified data collection system designed to provide a @@ -161,7 +165,7 @@ common data set to meet the needs of all three staging systems (TNM, SEER EOD, a improve data quality by standardizing rules for timing, clinical and pathologic assessments, and compatibility across all of the systems for all cancer sites. -``` +```java api.staging().schemaById("cs", "02.05.50", "brain").execute().body() ``` From 7887e748097f76c459289b9585885cb793f67d76 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 09:34:23 -0400 Subject: [PATCH 048/243] Dependency updates --- build.gradle | 10 +++++++--- .../imsweb/seerapi/client/staging/SchemaLookup.java | 6 ++++-- .../seerapi/client/staging/cs/CsStagingData.java | 4 ++-- .../seerapi/client/staging/eod/EodStagingData.java | 4 ++-- .../seerapi/client/staging/tnm/TnmStagingData.java | 4 ++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index eebc0ec..83f73db 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,11 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java' id 'checkstyle' + id "net.ltgt.errorprone" version "0.8.1" id "com.github.spotbugs" version "1.6.10" id 'com.bmuschko.nexus' version '2.3.1' id "io.codearte.nexus-staging" version "0.20.0" - id 'com.adarshr.test-logger' version '1.6.0' + id 'com.adarshr.test-logger' version '1.7.0' } group = 'com.imsweb' @@ -30,8 +31,10 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.5.0' - compile 'com.squareup.retrofit2:converter-jackson:2.5.0' + errorprone 'com.google.errorprone:error_prone_core:2.3.3' + + compile 'com.squareup.retrofit2:retrofit:2.6.1' + compile 'com.squareup.retrofit2:converter-jackson:2.6.1' testCompile 'junit:junit:4.11' testCompile 'org.assertj:assertj-core:3.11.1' @@ -59,6 +62,7 @@ testlogger { } checkstyle { + toolVersion '8.23' configFile = file("config/checkstyle/checkstyle.xml") } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java index 8be0e86..7c21833 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java @@ -137,8 +137,10 @@ public boolean hasDiscriminator() { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (!(o instanceof SchemaLookup)) + return false; SchemaLookup lookup = (SchemaLookup)o; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java index d03c180..db4d9c9 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java @@ -60,7 +60,7 @@ public enum CsInput { SSF24("ssf24"), SSF25("ssf25"); - private String _name; + private final String _name; CsInput(String name) { _name = name; @@ -116,7 +116,7 @@ public enum CsOutput { STOR_SS1977_STAGE("stor_ss77"), STOR_SS2000_STAGE("stor_ss2000"); - private String _name; + private final String _name; CsOutput(String name) { _name = name; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java index 4d129d4..6f8854a 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java @@ -119,7 +119,7 @@ public enum EodInput { SYSTEMIC_SURG_SEQ("systemic_surg_seq"), SS_2018("ss2018"); - private String _name; + private final String _name; EodInput(String name) { _name = name; @@ -142,7 +142,7 @@ public enum EodOutput { EOD_2018_STAGE_GROUP("eod_2018_stage_group"), SS_2018_DERIVED("ss2018_derived"); - private String _name; + private final String _name; EodOutput(String name) { _name = name; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java index edbcd79..e4c9172 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java @@ -60,7 +60,7 @@ public enum TnmInput { SSF24("ssf24"), SSF25("ssf25"); - private String _name; + private final String _name; TnmInput(String name) { _name = name; @@ -85,7 +85,7 @@ public enum TnmOutput { SOURCE_M("source_m"), COMBINED_M("combined_m"); - private String _name; + private final String _name; TnmOutput(String name) { _name = name; From f7f0bc8635ce86010a899df0109b19c239eba85e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 09:37:24 -0400 Subject: [PATCH 049/243] Errorprone setup --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 83f73db..fb3cb8b 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ repositories { } dependencies { - errorprone 'com.google.errorprone:error_prone_core:2.3.3' + errorproneJavac 'com.google.errorprone:error_prone_core:2.3.3' compile 'com.squareup.retrofit2:retrofit:2.6.1' compile 'com.squareup.retrofit2:converter-jackson:2.6.1' From b45553c1782d8e3eeb1aae5f1ba696979e09d484 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 09:49:12 -0400 Subject: [PATCH 050/243] Working on errorprone --- build.gradle | 6 ++++-- gradle/wrapper/gradle-wrapper.properties | 2 +- src/test/java/com/imsweb/seerapi/client/mph/MphTest.java | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index fb3cb8b..9a1d122 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,8 @@ repositories { } dependencies { - errorproneJavac 'com.google.errorprone:error_prone_core:2.3.3' + errorprone("com.google.errorprone:error_prone_core:2.3.3") + errorproneJavac("com.google.errorprone:javac:2.3.3") compile 'com.squareup.retrofit2:retrofit:2.6.1' compile 'com.squareup.retrofit2:converter-jackson:2.6.1' @@ -63,6 +64,7 @@ testlogger { checkstyle { toolVersion '8.23' + configProperties = ["suppressionFile": project(':').file('config/checkstyle/suppressions.xml')] configFile = file("config/checkstyle/checkstyle.xml") } @@ -71,7 +73,7 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } wrapper { - gradleVersion = '5.4.1' + gradleVersion = '5.6' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ee69dd6..8d58bda 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java index 57b5e0c..8ca656d 100644 --- a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java @@ -42,7 +42,7 @@ public void testMissingSite() throws IOException { input2.setDateOfDiagnosisYear("2016"); input2.setLaterality("1"); - MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + _MPH.mph(new MphInputPair(input1, input2)).execute().body(); } @Test From 3be87850ce266dfdb1daff7c11563ec9fc9fb162 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 09:51:44 -0400 Subject: [PATCH 051/243] Working on errorprone --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9a1d122..cfa562f 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,6 @@ repositories { dependencies { errorprone("com.google.errorprone:error_prone_core:2.3.3") - errorproneJavac("com.google.errorprone:javac:2.3.3") compile 'com.squareup.retrofit2:retrofit:2.6.1' compile 'com.squareup.retrofit2:converter-jackson:2.6.1' From 65b86cbb285967e722d1bd10bdd6056b2f2dcf68 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 09:54:17 -0400 Subject: [PATCH 052/243] Disable errorprone for now --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index cfa562f..2dc5861 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java' id 'checkstyle' - id "net.ltgt.errorprone" version "0.8.1" + //id "net.ltgt.errorprone" version "0.8.1" // errorprone disabled until move on from Java 8 id "com.github.spotbugs" version "1.6.10" id 'com.bmuschko.nexus' version '2.3.1' id "io.codearte.nexus-staging" version "0.20.0" @@ -31,7 +31,7 @@ repositories { } dependencies { - errorprone("com.google.errorprone:error_prone_core:2.3.3") + //errorprone("com.google.errorprone:error_prone_core:2.3.3") compile 'com.squareup.retrofit2:retrofit:2.6.1' compile 'com.squareup.retrofit2:converter-jackson:2.6.1' From 0753b6056a83dc5e79c4969a7fb6c266f883df1e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 10:08:12 -0400 Subject: [PATCH 053/243] Fixed surgery endpoint to match API changes --- .../client/surgery/SurgeryService.java | 25 ++++------ .../imsweb/seerapi/client/ndc/NdcTest.java | 2 +- .../seerapi/client/surgery/SurgeryTest.java | 47 +++++++------------ 3 files changed, 25 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java b/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java index e3fd4d7..4e2dee3 100644 --- a/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java +++ b/src/main/java/com/imsweb/seerapi/client/surgery/SurgeryService.java @@ -10,34 +10,25 @@ import retrofit2.http.Path; import retrofit2.http.Query; -import com.imsweb.seerapi.client.shared.Version; - public interface SurgeryService { /** - * Return a collection of Version objects which describe the available versions - * @return a list of the available site-specific surgery versions and information about each of them - */ - @GET("surgery/versions") - Call> versions(); - - /** - * Return a list of all the site-specific surgery table titles from a specific version - * @param version version + * Return a list of all the site-specific surgery table titles from a specific year + * @param year year * @return a list of site-specific surgery table titles */ - @GET("surgery/{version}/tables") - Call> tables(@Path("version") String version); + @GET("surgery/{year}/tables") + Call> tables(@Path("year") String year); /** - * Return a specific site-specific surgary table from a specific version - * @param version version + * Return a specific site-specific surgary table from a specific year + * @param year year * @param title site title (optional if the site/histology is provided) * @param site primary site (optional if the title is provided) * @param histology histology (optional if the title is provided) * @return a site-specific surgery table */ - @GET("surgery/{version}/table") - Call table(@Path("version") String version, @Query("title") String title, @Query("site") String site, @Query("hist") String histology); + @GET("surgery/{year}/table") + Call table(@Path("year") String year, @Query("title") String title, @Query("site") String site, @Query("hist") String histology); } diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index bf5f5af..0949ed3 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -67,7 +67,7 @@ public void testNdcByCode() throws IOException { assertThat(product.getProprietaryName()).isEqualTo("Verzenio"); assertThat(product.getSeerInfo()).as("must have 'seerinfo'").isNotNull(); assertThat(product.getSeerInfo().getCategories()).containsExactly(Category.CHEMOTHERAPY); - assertThat(product.getSeerInfo().getMajorDrugClass()).startsWith("Cyclin dependent"); + assertThat(product.getSeerInfo().getMajorDrugClass()).contains("Cyclin Dependent"); assertThat(product.getSeerInfo().getMinorDrugClass()).isEqualTo("CDK 4/6"); // the subcategory is being removed but still exists in production; the key should be ignored diff --git a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java index 116cc01..f8d5566 100644 --- a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java @@ -10,13 +10,8 @@ import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; -import com.imsweb.seerapi.client.shared.Version; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.assertj.core.api.Assertions.assertThat; public class SurgeryTest { @@ -27,43 +22,33 @@ public static void setup() { _SURGERY = new SeerApi.Builder().connect().surgery(); } - @Test - public void testSiteSpecificSurgeryVersions() throws IOException { - List versions = _SURGERY.versions().execute().body(); - - assertTrue(versions.size() > 0); - for (Version version : versions) { - assertTrue(version.getVersion().length() > 0); - assertTrue(version.getCount() > 0); - } - } - @Test public void testSiteSpecificSurgeryTables() throws IOException { List titles = _SURGERY.tables("2014").execute().body(); - assertTrue(titles.size() > 0); - assertTrue(titles.contains("Oral Cavity")); + assertThat(titles).isNotEmpty(); + assertThat(titles).containsAnyOf("Oral Cavity"); } @Test public void testSiteSpecificSurgeryTable() throws IOException { SurgeryTable table = _SURGERY.table("2014", "Oral Cavity", null, null).execute().body(); - assertNotNull(table); - assertEquals("Oral Cavity", table.getTitle()); - assertNotNull(table.getSiteInclusions()); - assertNotNull(table.getHistExclusions()); - assertNull(table.getHistInclusions()); - assertNotNull(table.getPreNote()); - assertNull(table.getPostNote()); + assertThat(table).isNotNull(); + assertThat(table.getTitle()).isEqualTo("Oral Cavity"); + assertThat(table.getSiteInclusions()).isNotNull(); + assertThat(table.getHistExclusions()).isNotNull(); + assertThat(table.getHistInclusions()).isNull(); + assertThat(table.getPreNote()).isNotNull(); + assertThat(table.getPostNote()).isNull(); + SurgeryRow row = table.getRows().get(0); - assertEquals("00", row.getCode()); - assertNotNull(row.getDescription()); - assertEquals(Integer.valueOf(0), row.getLevel()); - assertFalse(row.getLineBreak()); + assertThat(row.getCode()).isEqualTo("00"); + assertThat(row.getDescription()).isNotNull(); + assertThat(row.getLevel()).isEqualTo(Integer.valueOf(0)); + assertThat(row.getLineBreak()).isFalse(); table = _SURGERY.table("2014", null, "C001", "8000").execute().body(); - assertEquals("Oral Cavity", table.getTitle()); + assertThat(table.getTitle()).isEqualTo("Oral Cavity"); } } From 3044ff3b08a4565d690df4f0d688798d14438e47 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 Aug 2019 10:11:41 -0400 Subject: [PATCH 054/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 188e059..7317a14 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.15 + 3.16 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.15' +compile 'com.imsweb:seerapi-client-java:3.16' ``` ## Usage diff --git a/build.gradle b/build.gradle index 2dc5861..d989da8 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.15' +version = '3.16' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From 111aad509fa6804c204a2823bf79e9a3d5979248 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:32:32 -0500 Subject: [PATCH 055/243] Updating dependencies and switching release plugins --- .gitignore | 1 + build.gradle | 147 +++++++++++----- config/checkstyle/checkstyle.xml | 162 +++++++++--------- config/checkstyle/suppressions.xml | 7 - gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 35 ++-- gradlew.bat | 2 +- .../imsweb/seerapi/client/hcpcs/Hcpcs.java | 56 +++--- .../imsweb/seerapi/client/ndc/NdcPackage.java | 16 +- .../imsweb/seerapi/client/ndc/NdcProduct.java | 84 ++++----- .../seerapi/client/ndc/NdcSeerInfo.java | 28 +-- .../client/hcpcs/HcpcsServiceTest.java | 4 +- .../imsweb/seerapi/client/ndc/NdcTest.java | 2 +- 14 files changed, 296 insertions(+), 250 deletions(-) delete mode 100644 config/checkstyle/suppressions.xml diff --git a/.gitignore b/.gitignore index 190c29f..47bd85e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /target /build +/out /dist /classes /.gradle diff --git a/build.gradle b/build.gradle index d989da8..6422251 100644 --- a/build.gradle +++ b/build.gradle @@ -3,15 +3,16 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java' id 'checkstyle' - //id "net.ltgt.errorprone" version "0.8.1" // errorprone disabled until move on from Java 8 - id "com.github.spotbugs" version "1.6.10" - id 'com.bmuschko.nexus' version '2.3.1' - id "io.codearte.nexus-staging" version "0.20.0" - id 'com.adarshr.test-logger' version '1.7.0' + id 'maven-publish' + id 'signing' + id "com.github.spotbugs" version "3.0.0" + id 'com.adarshr.test-logger' version '2.0.0' + id "com.github.ben-manes.versions" version "0.27.0" + id "io.codearte.nexus-staging" version "0.21.2" } group = 'com.imsweb' -version = '3.16' +version = '3.17-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -24,6 +25,10 @@ tasks.withType(JavaCompile) { java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 + + + withJavadocJar() + withSourcesJar() } repositories { @@ -31,13 +36,11 @@ repositories { } dependencies { - //errorprone("com.google.errorprone:error_prone_core:2.3.3") - - compile 'com.squareup.retrofit2:retrofit:2.6.1' - compile 'com.squareup.retrofit2:converter-jackson:2.6.1' + compile 'com.squareup.retrofit2:retrofit:2.7.1' + compile 'com.squareup.retrofit2:converter-jackson:2.7.1' - testCompile 'junit:junit:4.11' - testCompile 'org.assertj:assertj-core:3.11.1' + testCompile 'junit:junit:4.13' + testCompile 'org.assertj:assertj-core:3.14.0' } jar { @@ -46,7 +49,7 @@ jar { manifest { attributes('Implementation-Title': 'SEER*API Java Client', - 'Implementation-Version': version, + 'Implementation-Version': archiveVersion, 'Implementation-Vendor': group, 'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")", 'Built-By': System.getProperty('user.name'), @@ -71,43 +74,103 @@ spotbugs { toolVersion = '3.1.12' excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } + +// when checking for later versions, exclude alphas, betas, etc.. +dependencyUpdates { + resolutionStrategy { + componentSelection { rules -> + rules.all { ComponentSelection selection -> + boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier -> + selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/ + } + if (rejected) { + selection.reject('Release candidate') + } + } + } + } +} + wrapper { - gradleVersion = '5.6' + gradleVersion = '6.1' distributionType = Wrapper.DistributionType.ALL } -modifyPom { - project { - name 'SEER*API Java Client' - description 'API mapping for SEER*API in Java' - url 'https://github.com/imsweb/seerapi-client-java' - inceptionYear '2014' - - scm { - url 'https://github.com/imsweb/seerapi-client-java' - connection 'scm:https://github.com/imsweb/seerapi-client-java.git' - developerConnection 'scm:git@github.com:imsweb/seerapi-client-java.git' - } +// don't try to release a snapshot to a non-snapshot repository, that won't work anyway +if (version.endsWith('-SNAPSHOT')) { + gradle.startParameter.excludedTaskNames += 'signMavenJavaPublication' + gradle.startParameter.excludedTaskNames += 'closeAndReleaseRepository' +} - licenses { - license { - name 'The MIT License (MIT)' - url 'http://www.opensource.org/licenses/mit-license.php' - distribution 'repo' +publishing { + publications { + mavenJava(MavenPublication) { + artifactId = 'seerapi-client-java' + from components.java + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } } - } - - developers { - developer { - id 'ctmay4' - name 'Chuck May' - email 'mayc@imsweb.com' + pom { + name = 'SEER*API Java Client' + description = 'API mapping for SEER*API in Java' + url = 'https://github.com/imsweb/seerapi-client-java' + inceptionYear = '2014' + + licenses { + license { + name = 'The MIT License (MIT)' + url = 'http://www.opensource.org/licenses/mit-license.php' + distribution = 'repo' + } + } + + developers { + developer { + id = 'ctmay4' + name = 'Chuck May' + email = 'mayc@imsweb.com' + } + developer { + id = 'depryf' + name = 'Fabian Depry' + email = 'depryf@imsweb.com' + } + } + + scm { + url = 'https://github.com/imsweb/seerapi-client-java' + connection = 'scm:https://github.com/imsweb/seerapi-client-java.git' + developerConnection = 'scm:git@github.com:imsweb/seerapi-client-java.git' + } } - developer { - id 'depryf' - name 'Fabian Depry' - email 'depryf@imsweb.com' + } + } + repositories { + maven { + def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" + def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + + credentials { + username = project.hasProperty('nexusUsername') ? project.getProperty('nexusUsername') : '' + password = project.hasProperty('nexusPassword') ? project.getProperty('nexusPassword') : '' } } } } + +signing { + sign publishing.publications.mavenJava +} + +javadoc { + if (JavaVersion.current().isJava9Compatible()) { + options.addBooleanOption('html5', true) + } +} + diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 2b758ef..6aaf4c2 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -1,168 +1,160 @@ - - + - + - + - + - + - + - - - + + + - + - + - + - + - + - + - - - + + + - + - - + + - - - + + + - + - - + + - - + + - + - - + + - + - + - + - + - + - + - - - + + + - + - - - + + + - - + + - - + + - + - + - + - + - + - - + + - + - - - + + + - + - - + + - - + + - - + + - + - - + + - + - + - + - + - + - + - - - - - + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml deleted file mode 100644 index 2bc44d3..0000000 --- a/config/checkstyle/suppressions.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..f3d88b1c2faf2fc91d853cd5d4242b5547257070 100644 GIT binary patch delta 22808 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 delta 20005 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 nvEpR}Ffj;rE}sKLhd|1%F5dI!=ox-rLy2 _brandNames; + private List brandNames; @JsonProperty("strength") - private String _strength; + private String strength; @JsonProperty("fda_approval_year") - private String _fdaApprovalYear; + private String fdaApprovalYear; @JsonProperty("fda_discontinuation_year") - private String _fdaDiscontinuationYear; + private String fdaDiscontinuationYear; @JsonProperty("cms_approval_date") - private String _cmsApprovalDate; + private String cmsApprovalDate; @JsonProperty("cms_discontinuation_date") - private String _cmsDiscontinuationDate; + private String cmsDiscontinuationDate; @JsonProperty("categories") - private List _categories; + private List categories; @JsonProperty("major_drug_class") - private String _majorDrugClass; + private String majorDrugClass; @JsonProperty("minor_drug_class") - private String _minorDrugClass; + private String minorDrugClass; @JsonProperty("oral") - private Boolean _oral; + private Boolean oral; @JsonProperty("date_added") - private Date _dateAdded; + private Date dateAdded; @JsonProperty("date_modified") - private Date _dateModified; + private Date dateModified; @JsonProperty("score") private Double score; public String getHcpcsCode() { - return _hcpcsCode; + return hcpcsCode; } public String getGenericName() { - return _genericName; + return genericName; } public List getBrandNames() { - return _brandNames; + return brandNames; } public String getStrength() { - return _strength; + return strength; } public String getFdaApprovalYear() { - return _fdaApprovalYear; + return fdaApprovalYear; } public String getFdaDiscontinuationYear() { - return _fdaDiscontinuationYear; + return fdaDiscontinuationYear; } public String getCmsApprovalDate() { - return _cmsApprovalDate; + return cmsApprovalDate; } public String getCmsDiscontinuationDate() { - return _cmsDiscontinuationDate; + return cmsDiscontinuationDate; } public List getCategories() { - return _categories; + return categories; } public String getMajorDrugClass() { - return _majorDrugClass; + return majorDrugClass; } public String getMinorDrugClass() { - return _minorDrugClass; + return minorDrugClass; } public Boolean getOral() { - return _oral; + return oral; } public Date getDateAdded() { - return _dateAdded; + return dateAdded; } public Date getDateModified() { - return _dateModified; + return dateModified; } public Double getScore() { diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java index f8531b1..8d0f2b5 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java @@ -10,28 +10,28 @@ public class NdcPackage { @JsonProperty("package") - private String _code; + private String code; @JsonProperty("description") - private String _description; + private String description; @JsonProperty("start_marketing_date") - private String _startMarketingDate; + private String startMarketingDate; @JsonProperty("end_marketing_date") - private String _endMarketingDate; + private String endMarketingDate; public String getCode() { - return _code; + return code; } public String getDescription() { - return _description; + return description; } public String getStartMarketingDate() { - return _startMarketingDate; + return startMarketingDate; } public String getEndMarketingDate() { - return _endMarketingDate; + return endMarketingDate; } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java index 1bf9def..6bba746 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java @@ -15,129 +15,129 @@ public class NdcProduct { @JsonProperty("ndc") - private String _ndc; + private String ndc; @JsonProperty("type_name") - private String _typeName; + private String typeName; @JsonProperty("proprietary_name") - private String _proprietaryName; + private String proprietaryName; @JsonProperty("proprietary_name_suffix") - private String _proprietaryNameSuffix; + private String proprietaryNameSuffix; @JsonProperty("non_proprietary_name") - private List _nonProprietaryName; + private List nonProprietaryName; @JsonProperty("dosage_form_name") - private String _dosageFormName; + private String dosageFormName; @JsonProperty("route_name") - private List _routeName; + private List routeName; @JsonProperty("start_marketing_date") - private String _startMarketingDate; + private String startMarketingDate; @JsonProperty("end_marketing_date") - private String _endMarketingDate; + private String endMarketingDate; @JsonProperty("marketing_category_name") - private String _marketingCategoryName; + private String marketingCategoryName; @JsonProperty("application_number") - private String _applicationNumber; + private String applicationNumber; @JsonProperty("labeler_name") - private String _labelerName; + private String labelerName; @JsonProperty("dea_schedule") - private String _deaSchedule; + private String deaSchedule; @JsonProperty("substances") - private List _substances; + private List substances; @JsonProperty("pharm_class") - private List _pharmClass; + private List pharmClass; @JsonProperty("packages") - private List _packages; + private List packages; @JsonProperty("date_added") - private Date _dateAdded; + private Date dateAdded; @JsonProperty("date_modified") - private Date _dateModified; + private Date dateModified; @JsonProperty("date_removed") - private Date _dateRemoved; + private Date dateRemoved; @JsonProperty("seer") - private NdcSeerInfo _seerInfo; + private NdcSeerInfo seerInfo; @JsonProperty("score") - private Double _score; + private Double score; public String getNdc() { - return _ndc; + return ndc; } public String getTypeName() { - return _typeName; + return typeName; } public String getProprietaryName() { - return _proprietaryName; + return proprietaryName; } public String getProprietaryNameSuffix() { - return _proprietaryNameSuffix; + return proprietaryNameSuffix; } public List getNonProprietaryName() { - return _nonProprietaryName; + return nonProprietaryName; } public String getDosageFormName() { - return _dosageFormName; + return dosageFormName; } public List getRouteName() { - return _routeName; + return routeName; } public String getStartMarketingDate() { - return _startMarketingDate; + return startMarketingDate; } public String getEndMarketingDate() { - return _endMarketingDate; + return endMarketingDate; } public String getMarketingCategoryName() { - return _marketingCategoryName; + return marketingCategoryName; } public String getApplicationNumber() { - return _applicationNumber; + return applicationNumber; } public String getLabelerName() { - return _labelerName; + return labelerName; } public String getDeaSchedule() { - return _deaSchedule; + return deaSchedule; } public List getSubstances() { - return _substances; + return substances; } public List getPharmClass() { - return _pharmClass; + return pharmClass; } public List getPackages() { - return _packages; + return packages; } public Date getDateAdded() { - return _dateAdded; + return dateAdded; } public Date getDateModified() { - return _dateModified; + return dateModified; } public Date getDateRemoved() { - return _dateRemoved; + return dateRemoved; } public NdcSeerInfo getSeerInfo() { - return _seerInfo; + return seerInfo; } public Double getScore() { - return _score; + return score; } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java index cda7772..68c0cd0 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -15,46 +15,46 @@ public class NdcSeerInfo { @JsonProperty("seer_rx_id") - private String _seerRxId; + private String seerRxId; @JsonProperty("categories") - private List _categories; + private List categories; @JsonProperty("major_drug_class") - private String _majorDrugClass; + private String majorDrugClass; @JsonProperty("minor_drug_class") - private String _minorDrugClass; + private String minorDrugClass; @JsonProperty("orphan_drug") - private Boolean _orphanDrug; + private Boolean orphanDrug; @JsonProperty("exclusive_oncologic_agent") - private Boolean _exclusiveAgent; + private Boolean exclusiveAgent; @JsonProperty("date_modified") - private Date _dateModified; + private Date dateModified; public String getSeerRxId() { - return _seerRxId; + return seerRxId; } public List getCategories() { - return _categories; + return categories; } public String getMajorDrugClass() { - return _majorDrugClass; + return majorDrugClass; } public String getMinorDrugClass() { - return _minorDrugClass; + return minorDrugClass; } public Boolean getOrphanDrug() { - return _orphanDrug; + return orphanDrug; } public Boolean getExclusiveAgent() { - return _exclusiveAgent; + return exclusiveAgent; } public Date getDateModified() { - return _dateModified; + return dateModified; } // drug categories diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java index 78e8ff3..c683776 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -77,7 +77,9 @@ public void testSearch() throws IOException { results = _HCPCS.search(params).execute().body(); assertThat(results).hasSize(2); assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); - assertThat(Objects.requireNonNull(results).get(0).getScore()).isGreaterThan(0); + + // TODO the scores should be coming back from the API but are not; waiting on API fix + //assertThat(Objects.requireNonNull(results).get(0).getScore()).isGreaterThan(0); // test categories params.put("category", Category.CHEMOTHERAPY.toString()); diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 0949ed3..f7aedd5 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -94,7 +94,7 @@ public void testNdcSearch() throws IOException { products = _NDC.search(search.paramMap()).execute().body(); assertThat(products.size()).isGreaterThan(1); - search.setRemovedSince("2019-06-03"); + search.setRemovedSince("2020-01-06"); products = _NDC.search(search.paramMap()).execute().body(); assertThat(products).isEmpty(); From 60d3362119109a90e8e22a62f2702792b21e56b1 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:34:22 -0500 Subject: [PATCH 056/243] Removed unneeded line --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6422251..53b4428 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,6 @@ testlogger { checkstyle { toolVersion '8.23' - configProperties = ["suppressionFile": project(':').file('config/checkstyle/suppressions.xml')] configFile = file("config/checkstyle/checkstyle.xml") } From 2b08672e0344c1959367e938e51aeb2d17d50076 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:38:46 -0500 Subject: [PATCH 057/243] Javadoc fixes --- .../java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java b/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java index 55e7f60..c30a889 100644 --- a/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java +++ b/src/main/java/com/imsweb/seerapi/client/hcpcs/HcpcsService.java @@ -15,12 +15,16 @@ public interface HcpcsService { /** * Return an HCPCS entity based on code. + * @param code HCPCS code + * @return an Hcpcs procedure */ @GET("hcpcs/code/{code}") Call getProcedure(@Path("code") String code); /** - * Return a list of matching HCPCS procedures + * Return a list of matching Hcpcs procedures + * @param searchParams A Map of search parameters. + * @return a List of Hcpcs procedures */ @GET("hcpcs") Call> search(@QueryMap Map searchParams); From 18272535d79000f14bc071bf5fdb942f73d6e7f7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:43:18 -0500 Subject: [PATCH 058/243] Fixed Gradle warnings --- build.gradle | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 53b4428..9a697fe 100644 --- a/build.gradle +++ b/build.gradle @@ -36,16 +36,16 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.7.1' - compile 'com.squareup.retrofit2:converter-jackson:2.7.1' + api 'com.squareup.retrofit2:retrofit:2.7.1' + api 'com.squareup.retrofit2:converter-jackson:2.7.1' - testCompile 'junit:junit:4.13' - testCompile 'org.assertj:assertj-core:3.14.0' + testImplementation 'junit:junit:4.13' + testImplementation 'org.assertj:assertj-core:3.14.0' } jar { // specify the archive name; otherwise the version is appended to the war file - archiveName = 'seerapi-java.jar' + archiveFileName = 'seerapi-java.jar' manifest { attributes('Implementation-Title': 'SEER*API Java Client', From ef9aa23dd237b4e758f994abd12283f144ab0278 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:47:29 -0500 Subject: [PATCH 059/243] Fixed Gradle warnings --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9a697fe..1763aad 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ import org.gradle.internal.jvm.Jvm plugins { - id 'java' + id 'java-library' id 'checkstyle' id 'maven-publish' id 'signing' From e1c11525157ff7b2b7a8739adf677a6e933a5208 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:50:16 -0500 Subject: [PATCH 060/243] Checkstyle update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1763aad..18cd7da 100644 --- a/build.gradle +++ b/build.gradle @@ -65,7 +65,7 @@ testlogger { } checkstyle { - toolVersion '8.23' + toolVersion '8.28' configFile = file("config/checkstyle/checkstyle.xml") } From 36f8e5738b415b799be2d819ce24f5e5357f5729 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:51:11 -0500 Subject: [PATCH 061/243] Cleanup --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 18cd7da..de50574 100644 --- a/build.gradle +++ b/build.gradle @@ -3,12 +3,12 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java-library' id 'checkstyle' + id "com.github.spotbugs" version "3.0.0" id 'maven-publish' id 'signing' - id "com.github.spotbugs" version "3.0.0" + id "io.codearte.nexus-staging" version "0.21.2" id 'com.adarshr.test-logger' version '2.0.0' id "com.github.ben-manes.versions" version "0.27.0" - id "io.codearte.nexus-staging" version "0.21.2" } group = 'com.imsweb' From 97298ae652425dc2a05cd4ff1b2fa7c1b9d06689 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 16 Jan 2020 15:57:04 -0500 Subject: [PATCH 062/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7317a14..973754b 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.16 + 3.17 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.16' +compile 'com.imsweb:seerapi-client-java:3.17' ``` ## Usage diff --git a/build.gradle b/build.gradle index de50574..9b76828 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { } group = 'com.imsweb' -version = '3.17-SNAPSHOT' +version = '3.17' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From 1e8f7c595fbe44e8fd38f3e598e0387d2cb1b725 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 18 May 2020 14:34:03 -0400 Subject: [PATCH 063/243] Dependency updates --- build.gradle | 12 ++++++------ gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 9b76828..3a388c4 100644 --- a/build.gradle +++ b/build.gradle @@ -3,12 +3,12 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "3.0.0" + id "com.github.spotbugs" version "4.2.0" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.21.2" id 'com.adarshr.test-logger' version '2.0.0' - id "com.github.ben-manes.versions" version "0.27.0" + id "com.github.ben-manes.versions" version "0.28.0" } group = 'com.imsweb' @@ -36,11 +36,11 @@ repositories { } dependencies { - api 'com.squareup.retrofit2:retrofit:2.7.1' - api 'com.squareup.retrofit2:converter-jackson:2.7.1' + api 'com.squareup.retrofit2:retrofit:2.8.1' + api 'com.squareup.retrofit2:converter-jackson:2.8.1' testImplementation 'junit:junit:4.13' - testImplementation 'org.assertj:assertj-core:3.14.0' + testImplementation 'org.assertj:assertj-core:3.16.1' } jar { @@ -91,7 +91,7 @@ dependencyUpdates { } wrapper { - gradleVersion = '6.1' + gradleVersion = '6.4.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 31a0802..21e622d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 91b04654b457471dda002bf7fda3c677f6000fc0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 18 May 2020 16:38:59 -0400 Subject: [PATCH 064/243] Initial move to Actions --- .github/workflows/ci.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6cfc2c1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,25 @@ +# Build the project and run unit tests + +name: Java CI with Gradle + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew build From ba0f79966c6d46f93f81914fef5d69b7e54464b8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 18 May 2020 16:48:58 -0400 Subject: [PATCH 065/243] Trying to get environment secret working --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6cfc2c1..05e40f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,3 +23,5 @@ jobs: run: chmod +x gradlew - name: Build with Gradle run: ./gradlew build + env: + SEER_API_KEY: ${{ secrets.SEER_API_KEY }} From b67d47d959b36d03b60587b45845b17d2e1f84ad Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 08:45:30 -0400 Subject: [PATCH 066/243] Working on badge --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05e40f9..d3791fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ # Build the project and run unit tests -name: Java CI with Gradle +name: build on: push: diff --git a/README.md b/README.md index 973754b..f5b08f4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # seerapi-client-java -[![CircleCI](https://circleci.com/gh/imsweb/seerapi-client-java.svg?style=shield)](https://circleci.com/gh/imsweb/seerapi-client-java) +![Java CI](https://github.com/imsweb/seerapi-client-java/workflows/build/badge.svg) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and From 86e7978bced97555595146d1089f1d5ec3c24f2c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 08:59:19 -0400 Subject: [PATCH 067/243] Remove CircleCI --- .circleci/config.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index fa5485e..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,32 +0,0 @@ -version: 2.0 -jobs: - build: - docker: - - image: circleci/openjdk:8-jdk - environment: - JVM_OPTS: -Xmx512m - steps: - - checkout - - restore_cache: - keys: - - gradle-{{ checksum "build.gradle" }} - - run: - name: chmod permissions - command: chmod +x ./gradlew - - run: - name: Run tests - command: ./gradlew check - - run: - name: Save test results - command: | - mkdir -p ~/junit/ - find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/junit/ \; - when: always - - store_test_results: - path: ~/junit - - store_artifacts: - path: ~/junit - - save_cache: - paths: - - ~/.gradle - key: gradle-{{ checksum "build.gradle" }} From f07215a92cf8d043df099ed4b85f9f67ac774d6d Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 09:01:24 -0400 Subject: [PATCH 068/243] Rename workflow --- .github/workflows/ci.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3791fa..3d28495 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ # Build the project and run unit tests -name: build +name: integration on: push: diff --git a/README.md b/README.md index f5b08f4..c58601d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # seerapi-client-java -![Java CI](https://github.com/imsweb/seerapi-client-java/workflows/build/badge.svg) +![Java CI](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and From df137da04664d8471dcd8134e4298111fa07f3e0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 09:12:11 -0400 Subject: [PATCH 069/243] Add caching --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d28495..0e10e87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,12 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 + - name: Cache Gradle packages + uses: actions/cache@v1 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle From c2166b0cc8e3021ded2891ab893544bad4c405ae Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 09:14:56 -0400 Subject: [PATCH 070/243] Force build --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c58601d..456bfdc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # seerapi-client-java -![Java CI](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg) +![integration](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and From a31c2eff79029cb958853c5fa5071b28a9e80044 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 09:21:26 -0400 Subject: [PATCH 071/243] Fixed badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 456bfdc..0d8c905 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # seerapi-client-java -![integration](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg) +[![integration](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg)](https://github.com/imsweb/seerapi-client-java/actions) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and From 791a2601a94f7be1a872e4d314163e8622e89afe Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 09:29:16 -0400 Subject: [PATCH 072/243] Switched trigger --- .github/workflows/ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e10e87..d0d2e3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,11 +2,7 @@ name: integration -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] +on: [push, pull_request] jobs: build: From 2f41a050ca5fd6c1b5bfd462e40efd3fe6c66a7c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 11:21:51 -0400 Subject: [PATCH 073/243] Set to SNAPSHOT version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3a388c4..8df1fb1 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { } group = 'com.imsweb' -version = '3.17' +version = '3.18-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From ec115fba066853ecf70f92e0694064d57230bf57 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 11:34:16 -0400 Subject: [PATCH 074/243] Add publish workflow --- .github/workflows/{ci.yml => integration.yml} | 0 .github/workflows/publish.yml | 33 +++++++++++++++++++ build.gradle | 4 +-- 3 files changed, 35 insertions(+), 2 deletions(-) rename .github/workflows/{ci.yml => integration.yml} (100%) create mode 100644 .github/workflows/publish.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/integration.yml similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/integration.yml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..1efb5f9 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,33 @@ +# Publish to Maven Central + +name: publish + +on: + repository_dispatch: + types: manual-event + +jobs: + publish: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Cache Gradle packages + uses: actions/cache@v1 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew publish closeAndReleaseRepository + env: + SEER_API_KEY: ${{ secrets.SEER_API_KEY }} + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} diff --git a/build.gradle b/build.gradle index 8df1fb1..731e46e 100644 --- a/build.gradle +++ b/build.gradle @@ -156,8 +156,8 @@ publishing { url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl credentials { - username = project.hasProperty('nexusUsername') ? project.getProperty('nexusUsername') : '' - password = project.hasProperty('nexusPassword') ? project.getProperty('nexusPassword') : '' + username = System.getenv("NEXUS_USERNAME") + password = System.getenv("NEXUS_PASSWORD") } } } From a38132d5b7b6691b8f1a810a72813bfbe92233c1 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 11:35:51 -0400 Subject: [PATCH 075/243] Rename type --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1efb5f9..4d1da0e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,7 +4,7 @@ name: publish on: repository_dispatch: - types: manual-event + types: manual-publish jobs: publish: From 64e39b58d8526930dbc99d200bba1815e5e22d2b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 13:25:11 -0400 Subject: [PATCH 076/243] Work on publishing --- .github/workflows/publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4d1da0e..0864c54 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,6 +5,9 @@ name: publish on: repository_dispatch: types: manual-publish +# once all is working, trigger when release is created +# release: +# types: [created] jobs: publish: From 06e3b88d1536e04faf42dcf9295c92abe49d98a2 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:04:23 -0400 Subject: [PATCH 077/243] Testing key setup --- .github/workflows/publish.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0864c54..d712144 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,9 +28,12 @@ jobs: restore-keys: ${{ runner.os }}-gradle - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew publish closeAndReleaseRepository - env: - SEER_API_KEY: ${{ secrets.SEER_API_KEY }} - NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} - NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + - name: Install gpg secret key + run: | + cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import + gpg --list-secret-keys --keyid-format LONG +# - name: Build with Gradle +# run: ./gradlew publish closeAndReleaseRepository +# env: +# NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} +# NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} From eb0074c17cf6eb3cfc83c1186fdd6075e0686dda Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:07:07 -0400 Subject: [PATCH 078/243] Testing key setup --- .github/workflows/publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d712144..2633013 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,7 +28,8 @@ jobs: restore-keys: ${{ runner.os }}-gradle - name: Grant execute permission for gradlew run: chmod +x gradlew - - name: Install gpg secret key + - id: install-secret-key + name: Install gpg secret key run: | cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import gpg --list-secret-keys --keyid-format LONG From f43d067982c5a27ea06d4efde67cf4af999a34cf Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:07:41 -0400 Subject: [PATCH 079/243] Formatting --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2633013..365b20c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -31,8 +31,8 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - gpg --list-secret-keys --keyid-format LONG + cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import + gpg --list-secret-keys --keyid-format LONG # - name: Build with Gradle # run: ./gradlew publish closeAndReleaseRepository # env: From 334d6397e3b0e26f336eea9a0c56c0f08ec5a3f2 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:29:11 -0400 Subject: [PATCH 080/243] Working on signing. --- .github/workflows/publish.yml | 13 ++++++++----- build.gradle | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 365b20c..8442c9a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -33,8 +33,11 @@ jobs: run: | cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import gpg --list-secret-keys --keyid-format LONG -# - name: Build with Gradle -# run: ./gradlew publish closeAndReleaseRepository -# env: -# NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} -# NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + - name: Build with Gradle + run: ./gradlew publish closeAndReleaseRepository + env: + ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + ORG_GRADLE_PROJECT_SEER_GPG_KEYID: ${{ secrets.SEER_GPG_KEYID }} + ORG_GRADLE_PROJECT_SEER_GPG_PASSWORD: ${{ secrets.SEER_GPG_PASSWORD }} + ORG_GRADLE_PROJECT_SEER_GPG_SECRET_KEYRING_FILE: ${{ secrets.SEER_GPG_SECRET_KEYRING_FILE }} diff --git a/build.gradle b/build.gradle index 731e46e..8df1fb1 100644 --- a/build.gradle +++ b/build.gradle @@ -156,8 +156,8 @@ publishing { url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl credentials { - username = System.getenv("NEXUS_USERNAME") - password = System.getenv("NEXUS_PASSWORD") + username = project.hasProperty('nexusUsername') ? project.getProperty('nexusUsername') : '' + password = project.hasProperty('nexusPassword') ? project.getProperty('nexusPassword') : '' } } } From 7a493048fc672f5906aa2defb72b31c12133e0d4 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:35:13 -0400 Subject: [PATCH 081/243] Ugh... --- .github/workflows/publish.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8442c9a..4bdb74f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -36,8 +36,8 @@ jobs: - name: Build with Gradle run: ./gradlew publish closeAndReleaseRepository env: - ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} - ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} - ORG_GRADLE_PROJECT_SEER_GPG_KEYID: ${{ secrets.SEER_GPG_KEYID }} - ORG_GRADLE_PROJECT_SEER_GPG_PASSWORD: ${{ secrets.SEER_GPG_PASSWORD }} - ORG_GRADLE_PROJECT_SEER_GPG_SECRET_KEYRING_FILE: ${{ secrets.SEER_GPG_SECRET_KEYRING_FILE }} + ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} + ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} + ORG_GRADLE_PROJECT_signing.keyId: ${{ secrets.SEER_GPG_KEYID }} + ORG_GRADLE_PROJECT_signing.password: ${{ secrets.SEER_GPG_PASSWORD }} + ORG_GRADLE_PROJECT_signing.secretKeyRingFile: ${{ secrets.SEER_GPG_SECRET_KEYRING_FILE }} From 57ec11ffb742aa4b84d7947461387a16be59f280 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:38:28 -0400 Subject: [PATCH 082/243] Remove caching in publish.yml --- .github/workflows/publish.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4bdb74f..96125d7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,12 +20,6 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 - - name: Cache Gradle packages - uses: actions/cache@v1 - with: - path: ~/.gradle/caches - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} - restore-keys: ${{ runner.os }}-gradle - name: Grant execute permission for gradlew run: chmod +x gradlew - id: install-secret-key From 41e2b940e00be4bfc04ca3f79c5dc02bba2e4221 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:41:50 -0400 Subject: [PATCH 083/243] Remove debugging --- .github/workflows/publish.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 96125d7..f979fa2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -24,9 +24,7 @@ jobs: run: chmod +x gradlew - id: install-secret-key name: Install gpg secret key - run: | - cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - gpg --list-secret-keys --keyid-format LONG + run: cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - name: Build with Gradle run: ./gradlew publish closeAndReleaseRepository env: From 02f2b73c3ce2f591a482ee3a56e9967bdcb3b498 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 14:51:41 -0400 Subject: [PATCH 084/243] Added link to documentation --- .github/workflows/publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f979fa2..50100ab 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,11 +1,13 @@ # Publish to Maven Central +# +# Instructions from https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c name: publish on: repository_dispatch: types: manual-publish -# once all is working, trigger when release is created +# once all is working, also trigger when release is created # release: # types: [created] From 3c1420a013a326fb276ca69b50dbf1685b162df0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 19 May 2020 15:08:32 -0400 Subject: [PATCH 085/243] Update Spotbugs --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8df1fb1..9418690 100644 --- a/build.gradle +++ b/build.gradle @@ -70,7 +70,7 @@ checkstyle { } spotbugs { - toolVersion = '3.1.12' + toolVersion = '4.0.3' excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } From d7ee13001d3d02d73a8ec13aeabaf628c3482563 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 10:33:10 -0400 Subject: [PATCH 086/243] Tweak publish workflow --- .github/workflows/publish.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 50100ab..4482af3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,11 +27,11 @@ jobs: - id: install-secret-key name: Install gpg secret key run: cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - - name: Build with Gradle + - name: Publish run: ./gradlew publish closeAndReleaseRepository env: - ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} - ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} ORG_GRADLE_PROJECT_signing.keyId: ${{ secrets.SEER_GPG_KEYID }} ORG_GRADLE_PROJECT_signing.password: ${{ secrets.SEER_GPG_PASSWORD }} - ORG_GRADLE_PROJECT_signing.secretKeyRingFile: ${{ secrets.SEER_GPG_SECRET_KEYRING_FILE }} + ORG_GRADLE_PROJECT_signing.secretKeyRingFile: ${{ secrets.SEER_GPG_KEYRING_FILE }} + ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} + ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From 9677312a09e4a2752632f4fc6e12f70eadc5aa78 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 10:39:19 -0400 Subject: [PATCH 087/243] Prepare for release --- .github/workflows/publish.yml | 1 - README.md | 4 ++-- build.gradle | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4482af3..0ced11e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,6 @@ name: publish on: repository_dispatch: types: manual-publish -# once all is working, also trigger when release is created # release: # types: [created] diff --git a/README.md b/README.md index 0d8c905..6d3dcba 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.17 + 3.18 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.17' +compile 'com.imsweb:seerapi-client-java:3.18' ``` ## Usage diff --git a/build.gradle b/build.gradle index 9418690..e3db6cb 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { } group = 'com.imsweb' -version = '3.18-SNAPSHOT' +version = '3.18' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From e215e2324f601bcc33c7b1a46c8282f5f79c4d4e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 10:52:00 -0400 Subject: [PATCH 088/243] Roll back to old release plugin --- .github/workflows/publish.yml | 2 +- build.gradle | 143 +++++++++--------------------- gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 58910 bytes gradlew | 2 + gradlew.bat | 4 + 5 files changed, 47 insertions(+), 104 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0ced11e..22d644e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,7 +27,7 @@ jobs: name: Install gpg secret key run: cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - name: Publish - run: ./gradlew publish closeAndReleaseRepository + run: ./gradlew uploadArchives closeAndReleaseRepository env: ORG_GRADLE_PROJECT_signing.keyId: ${{ secrets.SEER_GPG_KEYID }} ORG_GRADLE_PROJECT_signing.password: ${{ secrets.SEER_GPG_PASSWORD }} diff --git a/build.gradle b/build.gradle index e3db6cb..ce09d14 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,17 @@ import org.gradle.internal.jvm.Jvm plugins { - id 'java-library' + id 'java' id 'checkstyle' - id "com.github.spotbugs" version "4.2.0" - id 'maven-publish' - id 'signing' + id "com.github.spotbugs" version "4.2.1" + id 'com.bmuschko.nexus' version '2.3.1' id "io.codearte.nexus-staging" version "0.21.2" id 'com.adarshr.test-logger' version '2.0.0' id "com.github.ben-manes.versions" version "0.28.0" } group = 'com.imsweb' -version = '3.18' +version = '3.16' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -25,10 +24,6 @@ tasks.withType(JavaCompile) { java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 - - - withJavadocJar() - withSourcesJar() } repositories { @@ -36,20 +31,20 @@ repositories { } dependencies { - api 'com.squareup.retrofit2:retrofit:2.8.1' - api 'com.squareup.retrofit2:converter-jackson:2.8.1' + compile 'com.squareup.retrofit2:retrofit:2.8.2' + compile 'com.squareup.retrofit2:converter-jackson:2.8.2' - testImplementation 'junit:junit:4.13' - testImplementation 'org.assertj:assertj-core:3.16.1' + testCompile 'junit:junit:4.13' + testCompile 'org.assertj:assertj-core:3.16.1' } jar { // specify the archive name; otherwise the version is appended to the war file - archiveFileName = 'seerapi-java.jar' + archiveName = 'seerapi-java.jar' manifest { attributes('Implementation-Title': 'SEER*API Java Client', - 'Implementation-Version': archiveVersion, + 'Implementation-Version': version, 'Implementation-Vendor': group, 'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")", 'Built-By': System.getProperty('user.name'), @@ -65,7 +60,8 @@ testlogger { } checkstyle { - toolVersion '8.28' + toolVersion '8.23' + configProperties = ["suppressionFile": project(':').file('config/checkstyle/suppressions.xml')] configFile = file("config/checkstyle/checkstyle.xml") } @@ -74,102 +70,43 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } -// when checking for later versions, exclude alphas, betas, etc.. -dependencyUpdates { - resolutionStrategy { - componentSelection { rules -> - rules.all { ComponentSelection selection -> - boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier -> - selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/ - } - if (rejected) { - selection.reject('Release candidate') - } - } - } - } -} - wrapper { gradleVersion = '6.4.1' distributionType = Wrapper.DistributionType.ALL } -// don't try to release a snapshot to a non-snapshot repository, that won't work anyway -if (version.endsWith('-SNAPSHOT')) { - gradle.startParameter.excludedTaskNames += 'signMavenJavaPublication' - gradle.startParameter.excludedTaskNames += 'closeAndReleaseRepository' -} +modifyPom { + project { + name 'SEER*API Java Client' + description 'API mapping for SEER*API in Java' + url 'https://github.com/imsweb/seerapi-client-java' + inceptionYear '2014' + + scm { + url 'https://github.com/imsweb/seerapi-client-java' + connection 'scm:https://github.com/imsweb/seerapi-client-java.git' + developerConnection 'scm:git@github.com:imsweb/seerapi-client-java.git' + } -publishing { - publications { - mavenJava(MavenPublication) { - artifactId = 'seerapi-client-java' - from components.java - versionMapping { - usage('java-api') { - fromResolutionOf('runtimeClasspath') - } - usage('java-runtime') { - fromResolutionResult() - } - } - pom { - name = 'SEER*API Java Client' - description = 'API mapping for SEER*API in Java' - url = 'https://github.com/imsweb/seerapi-client-java' - inceptionYear = '2014' - - licenses { - license { - name = 'The MIT License (MIT)' - url = 'http://www.opensource.org/licenses/mit-license.php' - distribution = 'repo' - } - } - - developers { - developer { - id = 'ctmay4' - name = 'Chuck May' - email = 'mayc@imsweb.com' - } - developer { - id = 'depryf' - name = 'Fabian Depry' - email = 'depryf@imsweb.com' - } - } - - scm { - url = 'https://github.com/imsweb/seerapi-client-java' - connection = 'scm:https://github.com/imsweb/seerapi-client-java.git' - developerConnection = 'scm:git@github.com:imsweb/seerapi-client-java.git' - } + licenses { + license { + name 'The MIT License (MIT)' + url 'http://www.opensource.org/licenses/mit-license.php' + distribution 'repo' } } - } - repositories { - maven { - def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" - def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - - credentials { - username = project.hasProperty('nexusUsername') ? project.getProperty('nexusUsername') : '' - password = project.hasProperty('nexusPassword') ? project.getProperty('nexusPassword') : '' + + developers { + developer { + id 'ctmay4' + name 'Chuck May' + email 'mayc@imsweb.com' + } + developer { + id 'depryf' + name 'Fabian Depry' + email 'depryf@imsweb.com' } } } } - -signing { - sign publishing.publications.mavenJava -} - -javadoc { - if (JavaVersion.current().isJava9Compatible()) { - options.addBooleanOption('html5', true) - } -} - diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2faf2fc91d853cd5d4242b5547257070..62d4c053550b91381bbd28b1afc82d634bf73a8a 100644 GIT binary patch delta 12524 zcmY*pqN z|ERss*;ReIR@Lg&r_R7IT-GRDbpR4NMKNcwFgy&*A|eco1PnBHRth?SBneiw6$UT&^LVJ0?Naa`KfV(>F!Ez}~S z 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 delta 12163 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 diff --git a/gradlew b/gradlew index 2fe81a7..fbd7c51 100644 --- a/gradlew +++ b/gradlew @@ -82,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -129,6 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 9618d8d..5093609 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @@ -81,6 +84,7 @@ set CMD_LINE_ARGS=%* set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% From d2fab05779d4a5c1081fa64eb23c67c399634156 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 10:55:14 -0400 Subject: [PATCH 089/243] Fixed version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ce09d14..7b55762 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.16' +version = '3.18' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From 2e0abc35b5608fb1c215f58c9f91dc30a4c4ba4f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 10:59:53 -0400 Subject: [PATCH 090/243] Trying the command-line --- .github/workflows/publish.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 22d644e..3185583 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,10 +27,7 @@ jobs: name: Install gpg secret key run: cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - name: Publish - run: ./gradlew uploadArchives closeAndReleaseRepository + run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile${{ secrets.SEER_GPG_KEYRING_FILE }} env: - ORG_GRADLE_PROJECT_signing.keyId: ${{ secrets.SEER_GPG_KEYID }} - ORG_GRADLE_PROJECT_signing.password: ${{ secrets.SEER_GPG_PASSWORD }} - ORG_GRADLE_PROJECT_signing.secretKeyRingFile: ${{ secrets.SEER_GPG_KEYRING_FILE }} ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From 67f581bb13132e266263d2195def0b93ec806447 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:06:59 -0400 Subject: [PATCH 091/243] Typo --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3185583..a09585f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,7 +27,7 @@ jobs: name: Install gpg secret key run: cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import - name: Publish - run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile${{ secrets.SEER_GPG_KEYRING_FILE }} + run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile=${{ secrets.SEER_GPG_KEYRING_FILE }} env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From 227f7783c16f0bb6c11eb68fd1f53a6bba485b17 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:30:53 -0400 Subject: [PATCH 092/243] Debug --- .github/workflows/publish.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a09585f..97e2248 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -25,7 +25,10 @@ jobs: run: chmod +x gradlew - id: install-secret-key name: Install gpg secret key - run: cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import + run: | + cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import + gpg --list-secret-keys --keyid-format LONG + ls -lagF ~/.gpg - name: Publish run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile=${{ secrets.SEER_GPG_KEYRING_FILE }} env: From 4577e344591b073fd1a9a028404f5fe3feb2400c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:31:13 -0400 Subject: [PATCH 093/243] Move to SNAPSHOT --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7b55762..dd99814 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.18' +version = '3.19-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From c15a1719390fbb04a44734c96295029b682dc94f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:36:01 -0400 Subject: [PATCH 094/243] Tweak --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 97e2248..e9abc14 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,7 +28,7 @@ jobs: run: | cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import gpg --list-secret-keys --keyid-format LONG - ls -lagF ~/.gpg + ls -lagF ~/.gnupg - name: Publish run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile=${{ secrets.SEER_GPG_KEYRING_FILE }} env: From 1d16ffdfe691bc0fd296571a1e3ded45109d8dd8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:55:47 -0400 Subject: [PATCH 095/243] Try another method --- .github/workflows/publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e9abc14..0834ddf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,7 +26,8 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - cat <(echo -e "${{ secrets.SEER_GPG_SECRET_KEY }}") | gpg --batch --import + echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | $GPG_EXECUTABLE --import + echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | $GPG_EXECUTABLE --import-ownertrust gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish From e26efff2e9a2b98a9739b9c3314bb9f2964b15d0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:57:05 -0400 Subject: [PATCH 096/243] Grrr... --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0834ddf..5b740dd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,8 +26,8 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | $GPG_EXECUTABLE --import - echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | $GPG_EXECUTABLE --import-ownertrust + echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import + echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish From 71929809adc69ee4bc6e3ff3d5b20cba6cde7621 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 11:59:46 -0400 Subject: [PATCH 097/243] Try this? --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5b740dd..17d1ae8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,8 +26,8 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import - echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust + cat <(echo "${{ secrets.SEER_GPG_SECRET_KEY }}") | base64 --decode | gpg --import + cat <(echo "${{ secrets.SEER_GPG_OWNER_TRUST }}") | base64 --decode | gpg --import-ownertrust gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish From 8d99f57563f39d301f48288e040ad7127941162f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 13:06:09 -0400 Subject: [PATCH 098/243] More testing --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 17d1ae8..7807f90 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,8 +26,8 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - cat <(echo "${{ secrets.SEER_GPG_SECRET_KEY }}") | base64 --decode | gpg --import - cat <(echo "${{ secrets.SEER_GPG_OWNER_TRUST }}") | base64 --decode | gpg --import-ownertrust + cat <(echo "${{ secrets.SEER_GPG_SECRET_KEY }}") | base64 --decode | gpg --import --no-tty --batch --yes + cat <(echo "${{ secrets.SEER_GPG_OWNER_TRUST }}") | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish From 8b805fbb32bca7a91ad6a8c799edcc58468f11a8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 13:07:04 -0400 Subject: [PATCH 099/243] More testing --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7807f90..602dfcb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,8 +26,8 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - cat <(echo "${{ secrets.SEER_GPG_SECRET_KEY }}") | base64 --decode | gpg --import --no-tty --batch --yes - cat <(echo "${{ secrets.SEER_GPG_OWNER_TRUST }}") | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes + echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes + echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish From 25afda27c87957fc6df4c6f7ee3a336160210c0b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 13:14:14 -0400 Subject: [PATCH 100/243] One last try --- .github/workflows/publish.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 602dfcb..2ff9b9f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,6 +26,10 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | + echo use-agent >> ~/.gnupg/gpg.conf + echo pinentry-mode loopback >> ~/.gnupg/gpg.conf + echo allow-loopback-pinentry >> ~/.gnupg/gpg-agent.conf + echo RELOADAGENT | gpg-connect-agent echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes gpg --list-secret-keys --keyid-format LONG From 27a7cc3edd5d4355828c6455f53f0368aaa31b72 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 13:15:57 -0400 Subject: [PATCH 101/243] I am giving up now --- .github/workflows/publish.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2ff9b9f..02a8920 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,14 +26,14 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - echo use-agent >> ~/.gnupg/gpg.conf - echo pinentry-mode loopback >> ~/.gnupg/gpg.conf - echo allow-loopback-pinentry >> ~/.gnupg/gpg-agent.conf - echo RELOADAGENT | gpg-connect-agent - echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes - echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - gpg --list-secret-keys --keyid-format LONG - ls -lagF ~/.gnupg + # echo use-agent >> ~/.gnupg/gpg.conf + # echo pinentry-mode loopback >> ~/.gnupg/gpg.conf + # echo allow-loopback-pinentry >> ~/.gnupg/gpg-agent.conf + # echo RELOADAGENT | gpg-connect-agent + echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes + echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes + gpg --list-secret-keys --keyid-format LONG + ls -lagF ~/.gnupg - name: Publish run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile=${{ secrets.SEER_GPG_KEYRING_FILE }} env: From 2a55b22c2e9347496cad9e1047f54a4b4ee80449 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 14:03:00 -0400 Subject: [PATCH 102/243] Another shot --- .github/workflows/publish.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 02a8920..1612b0d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,16 +26,13 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - # echo use-agent >> ~/.gnupg/gpg.conf - # echo pinentry-mode loopback >> ~/.gnupg/gpg.conf - # echo allow-loopback-pinentry >> ~/.gnupg/gpg-agent.conf - # echo RELOADAGENT | gpg-connect-agent - echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes - echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - gpg --list-secret-keys --keyid-format LONG - ls -lagF ~/.gnupg + echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes + echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes + gpg --export-secret-keys -o ~/.gnupg/secring.gpg + gpg --list-secret-keys --keyid-format LONG + ls -lagF ~/.gnupg - name: Publish - run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} -Psigning.secretKeyRingFile=${{ secrets.SEER_GPG_KEYRING_FILE }} + run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From e9f0d4303746a46b28c202abb0a0bd9552bec930 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 14:04:18 -0400 Subject: [PATCH 103/243] Another shot --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1612b0d..2968a53 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -28,7 +28,7 @@ jobs: run: | echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - gpg --export-secret-keys -o ~/.gnupg/secring.gpg + gpg --export-secret-keys -o ~/.gnupg/secring.gpg --no-tty --batch --yes gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish From ec9196aa262f9dab0a96077b8e5209e298b8e30f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 14:08:52 -0400 Subject: [PATCH 104/243] Another shot --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2968a53..5ebc527 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,10 +26,10 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | + export GPG_TTY=$(tty) echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes gpg --export-secret-keys -o ~/.gnupg/secring.gpg --no-tty --batch --yes - gpg --list-secret-keys --keyid-format LONG ls -lagF ~/.gnupg - name: Publish run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} From 98f4dceef0d7875b5d1c500dfc36b442c663f866 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 14:18:44 -0400 Subject: [PATCH 105/243] One last try --- .github/workflows/publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5ebc527..5b59753 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,10 +26,9 @@ jobs: - id: install-secret-key name: Install gpg secret key run: | - export GPG_TTY=$(tty) echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - gpg --export-secret-keys -o ~/.gnupg/secring.gpg --no-tty --batch --yes + echo ${{ secrets.SEER_GPG_SECRING }} | base64 --decode > ~/.gnupg/secring.gpg ls -lagF ~/.gnupg - name: Publish run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} From 1b371f15c82bbf13eb2ccd54690fc3a88eef0cfd Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 14:22:03 -0400 Subject: [PATCH 106/243] Don't close repo for SNAPSHOT --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index dd99814..8fb9d1e 100644 --- a/build.gradle +++ b/build.gradle @@ -75,6 +75,10 @@ wrapper { distributionType = Wrapper.DistributionType.ALL } +// don't try to release a snapshot to a non-snapshot repository, that won't work anyway +if (version.endsWith('-SNAPSHOT')) + gradle.startParameter.excludedTaskNames += 'closeAndReleaseRepository' + modifyPom { project { name 'SEER*API Java Client' From 83c1d1c780a0fea7e3ee7b6675206d57666684c8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 15:15:41 -0400 Subject: [PATCH 107/243] Remove debug stuff --- .github/workflows/publish.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5b59753..a9a1c08 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -29,7 +29,6 @@ jobs: echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes echo ${{ secrets.SEER_GPG_SECRING }} | base64 --decode > ~/.gnupg/secring.gpg - ls -lagF ~/.gnupg - name: Publish run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} env: From fd5d6d8bc9f60e4e00871d085c0487edfd994b73 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 21:51:20 -0400 Subject: [PATCH 108/243] Switch to maven-publish plugin --- build.gradle | 139 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 41 deletions(-) diff --git a/build.gradle b/build.gradle index 8fb9d1e..cea2d15 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,18 @@ import org.gradle.internal.jvm.Jvm plugins { - id 'java' + id 'java-library' id 'checkstyle' id "com.github.spotbugs" version "4.2.1" - id 'com.bmuschko.nexus' version '2.3.1' + id 'maven-publish' + id 'signing' id "io.codearte.nexus-staging" version "0.21.2" id 'com.adarshr.test-logger' version '2.0.0' id "com.github.ben-manes.versions" version "0.28.0" } group = 'com.imsweb' -version = '3.19-SNAPSHOT' +version = '3.19' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -24,6 +25,9 @@ tasks.withType(JavaCompile) { java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 + + withJavadocJar() + withSourcesJar() } repositories { @@ -31,20 +35,20 @@ repositories { } dependencies { - compile 'com.squareup.retrofit2:retrofit:2.8.2' - compile 'com.squareup.retrofit2:converter-jackson:2.8.2' + api 'com.squareup.retrofit2:retrofit:2.9.0' + api 'com.squareup.retrofit2:converter-jackson:2.9.0' - testCompile 'junit:junit:4.13' - testCompile 'org.assertj:assertj-core:3.16.1' + testImplementation 'junit:junit:4.13' + testImplementation 'org.assertj:assertj-core:3.16.1' } jar { // specify the archive name; otherwise the version is appended to the war file - archiveName = 'seerapi-java.jar' + archiveFileName = 'seerapi-java.jar' manifest { attributes('Implementation-Title': 'SEER*API Java Client', - 'Implementation-Version': version, + 'Implementation-Version': archiveVersion, 'Implementation-Vendor': group, 'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")", 'Built-By': System.getProperty('user.name'), @@ -60,8 +64,7 @@ testlogger { } checkstyle { - toolVersion '8.23' - configProperties = ["suppressionFile": project(':').file('config/checkstyle/suppressions.xml')] + toolVersion '8.28' configFile = file("config/checkstyle/checkstyle.xml") } @@ -70,47 +73,101 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } +// when checking for later versions, exclude alphas, betas, etc.. +dependencyUpdates { + resolutionStrategy { + componentSelection { rules -> + rules.all { ComponentSelection selection -> + boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier -> + selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/ + } + if (rejected) { + selection.reject('Release candidate') + } + } + } + } +} + wrapper { gradleVersion = '6.4.1' distributionType = Wrapper.DistributionType.ALL } // don't try to release a snapshot to a non-snapshot repository, that won't work anyway -if (version.endsWith('-SNAPSHOT')) +if (version.endsWith('-SNAPSHOT')) { + gradle.startParameter.excludedTaskNames += 'signMavenJavaPublication' gradle.startParameter.excludedTaskNames += 'closeAndReleaseRepository' +} -modifyPom { - project { - name 'SEER*API Java Client' - description 'API mapping for SEER*API in Java' - url 'https://github.com/imsweb/seerapi-client-java' - inceptionYear '2014' - - scm { - url 'https://github.com/imsweb/seerapi-client-java' - connection 'scm:https://github.com/imsweb/seerapi-client-java.git' - developerConnection 'scm:git@github.com:imsweb/seerapi-client-java.git' - } - - licenses { - license { - name 'The MIT License (MIT)' - url 'http://www.opensource.org/licenses/mit-license.php' - distribution 'repo' +publishing { + publications { + mavenJava(MavenPublication) { + artifactId = 'seerapi-client-java' + from components.java + versionMapping { + usage('java-api') { + fromResolutionOf('runtimeClasspath') + } + usage('java-runtime') { + fromResolutionResult() + } } - } - - developers { - developer { - id 'ctmay4' - name 'Chuck May' - email 'mayc@imsweb.com' + pom { + name = 'SEER*API Java Client' + description = 'API mapping for SEER*API in Java' + url = 'https://github.com/imsweb/seerapi-client-java' + inceptionYear = '2014' + + licenses { + license { + name = 'The MIT License (MIT)' + url = 'http://www.opensource.org/licenses/mit-license.php' + distribution = 'repo' + } + } + + developers { + developer { + id = 'ctmay4' + name = 'Chuck May' + email = 'mayc@imsweb.com' + } + developer { + id = 'depryf' + name = 'Fabian Depry' + email = 'depryf@imsweb.com' + } + } + + scm { + url = 'https://github.com/imsweb/seerapi-client-java' + connection = 'scm:https://github.com/imsweb/seerapi-client-java.git' + developerConnection = 'scm:git@github.com:imsweb/seerapi-client-java.git' + } } - developer { - id 'depryf' - name 'Fabian Depry' - email 'depryf@imsweb.com' + } + } + repositories { + maven { + def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" + def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + + credentials { + username = project.hasProperty('nexusUsername') ? project.getProperty('nexusUsername') : '' + password = project.hasProperty('nexusPassword') ? project.getProperty('nexusPassword') : '' } } } } + +signing { + sign publishing.publications.mavenJava +} + +javadoc { + if (JavaVersion.current().isJava9Compatible()) { + options.addBooleanOption('html5', true) + } +} From 8a2640a114ab1f4e00a00006fc2b71b78e503602 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 21:59:31 -0400 Subject: [PATCH 109/243] Fix warning --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index cea2d15..94aece6 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,8 @@ repositories { } dependencies { + spotbugs 'com.github.spotbugs:spotbugs:4.0.3' + api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' @@ -69,7 +71,6 @@ checkstyle { } spotbugs { - toolVersion = '4.0.3' excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } From 45b857049cc8b0577d3fe72ab774e4b0fb4e4655 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 22:01:09 -0400 Subject: [PATCH 110/243] Back to SNAPSHOT --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 94aece6..06318d2 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { } group = 'com.imsweb' -version = '3.19' +version = '3.19-SNAPSHOT' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From 7e1cc34c78589ec15984edeb4b0fcc11a0fb72d3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 20 May 2020 22:09:53 -0400 Subject: [PATCH 111/243] More cleanup --- build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build.gradle b/build.gradle index 06318d2..26aa5df 100644 --- a/build.gradle +++ b/build.gradle @@ -61,10 +61,6 @@ jar { } } -testlogger { - theme 'mocha' -} - checkstyle { toolVersion '8.28' configFile = file("config/checkstyle/checkstyle.xml") From 6a2f81cbdb04e39f0f2f6b6325bf34524f458cd3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 09:11:38 -0400 Subject: [PATCH 112/243] Signing works now. --- .github/workflows/publish.yml | 15 +++++---------- build.gradle | 6 +++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a9a1c08..8fe7643 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,6 +1,4 @@ # Publish to Maven Central -# -# Instructions from https://gist.github.com/sualeh/ae78dc16123899d7942bc38baba5203c name: publish @@ -16,21 +14,18 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v2 - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: java-version: 1.8 - name: Grant execute permission for gradlew run: chmod +x gradlew - - id: install-secret-key - name: Install gpg secret key - run: | - echo ${{ secrets.SEER_GPG_SECRET_KEY }} | base64 --decode | gpg --import --no-tty --batch --yes - echo ${{ secrets.SEER_GPG_OWNER_TRUST }} | base64 --decode | gpg --import-ownertrust --no-tty --batch --yes - echo ${{ secrets.SEER_GPG_SECRING }} | base64 --decode > ~/.gnupg/secring.gpg - name: Publish - run: ./gradlew uploadArchives closeAndReleaseRepository -Psigning.keyId=${{ secrets.SEER_GPG_KEYID }} -Psigning.password=${{ secrets.SEER_GPG_PASSWORD }} + run: ./gradlew uploadArchives closeAndReleaseRepository env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SEER_GPG_SECRET_KEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SEER_GPG_PASSWORD }} diff --git a/build.gradle b/build.gradle index 26aa5df..1294d64 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { } group = 'com.imsweb' -version = '3.19-SNAPSHOT' +version = '3.18.1' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" @@ -160,6 +160,10 @@ publishing { } signing { + def signingKey = findProperty("signingKey") + def signingPassword = findProperty("signingPassword") + useInMemoryPgpKeys(signingKey, signingPassword) + sign publishing.publications.mavenJava } From 869095989cce6c25600ad662d7164f08df6b8688 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 09:17:03 -0400 Subject: [PATCH 113/243] Cleanup --- .github/workflows/integration.yml | 35 ++++++++++++++++--------------- .github/workflows/publish.yml | 6 +++--- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index d0d2e3a..949a297 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -10,20 +10,21 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Cache Gradle packages - uses: actions/cache@v1 - with: - path: ~/.gradle/caches - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} - restore-keys: ${{ runner.os }}-gradle - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Build with Gradle - run: ./gradlew build - env: - SEER_API_KEY: ${{ secrets.SEER_API_KEY }} + - name: Checkout + uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Cache Gradle packages + uses: actions/cache@v1 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Build and test + run: | + chmod +x gradlew + ./gradlew build + env: + SEER_API_KEY: ${{ secrets.SEER_API_KEY }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8fe7643..ca8ced5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,10 +20,10 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - name: Publish - run: ./gradlew uploadArchives closeAndReleaseRepository + run: | + chmod +x gradlew + ./gradlew uploadArchives closeAndReleaseRepository env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From e5b1ce88d168ed0ecbf99878af6a76ca2e7ade9f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 09:47:14 -0400 Subject: [PATCH 114/243] Test signing. --- .github/workflows/publish.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ca8ced5..7542aee 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -22,8 +22,9 @@ jobs: java-version: 1.8 - name: Publish run: | - chmod +x gradlew - ./gradlew uploadArchives closeAndReleaseRepository + chmod +x gradlew + # ./gradlew uploadArchives closeAndReleaseRepository + ./gradlew signMavenJavaPublication env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From b6b87f5ff6da9b487cc28e83e2cfa5e5097c5742 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 09:47:44 -0400 Subject: [PATCH 115/243] Test signing. --- .github/workflows/publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7542aee..dca9c8c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,5 @@ # Publish to Maven Central +# ./gradlew uploadArchives closeAndReleaseRepository name: publish @@ -22,9 +23,8 @@ jobs: java-version: 1.8 - name: Publish run: | - chmod +x gradlew - # ./gradlew uploadArchives closeAndReleaseRepository - ./gradlew signMavenJavaPublication + chmod +x gradlew + ./gradlew signMavenJavaPublication env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From 37ccc24c9675a37f069eef5de0b58b5b3ee4dcb4 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 09:51:40 -0400 Subject: [PATCH 116/243] Test signing. --- .github/workflows/publish.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dca9c8c..b6475e1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -24,9 +24,7 @@ jobs: - name: Publish run: | chmod +x gradlew - ./gradlew signMavenJavaPublication + ./gradlew signMavenJavaPublication -PsigningKey=${{ secrets.SEER_GPG_SECRET_KEY }} -PsigningPassword=${{ secrets.SEER_GPG_PASSWORD }} env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} - ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SEER_GPG_SECRET_KEY }} - ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SEER_GPG_PASSWORD }} From eb88a3f867758e737619de53a3a09df52c67f4dc Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 09:54:17 -0400 Subject: [PATCH 117/243] Not getting keys --- .github/workflows/publish.yml | 4 +++- build.gradle | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b6475e1..dca9c8c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -24,7 +24,9 @@ jobs: - name: Publish run: | chmod +x gradlew - ./gradlew signMavenJavaPublication -PsigningKey=${{ secrets.SEER_GPG_SECRET_KEY }} -PsigningPassword=${{ secrets.SEER_GPG_PASSWORD }} + ./gradlew signMavenJavaPublication env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SEER_GPG_SECRET_KEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SEER_GPG_PASSWORD }} diff --git a/build.gradle b/build.gradle index 1294d64..ba40510 100644 --- a/build.gradle +++ b/build.gradle @@ -160,8 +160,8 @@ publishing { } signing { - def signingKey = findProperty("signingKey") - def signingPassword = findProperty("signingPassword") + def signingKey = project.hasProperty('signingKey') ? project.getProperty('signingKey') : '' + def signingPassword = project.hasProperty('signingPassword') ? project.getProperty('signingPassword') : '' useInMemoryPgpKeys(signingKey, signingPassword) sign publishing.publications.mavenJava From 8259abeb1d49fb50b49c8b220680bb78fa0409a4 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 11:03:19 -0400 Subject: [PATCH 118/243] FINALLY got it working --- .github/workflows/publish.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index dca9c8c..ca8ced5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,5 +1,4 @@ # Publish to Maven Central -# ./gradlew uploadArchives closeAndReleaseRepository name: publish @@ -24,7 +23,7 @@ jobs: - name: Publish run: | chmod +x gradlew - ./gradlew signMavenJavaPublication + ./gradlew uploadArchives closeAndReleaseRepository env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} From 6d355515a0630469ea4b394a381b37b88491298a Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 11:07:57 -0400 Subject: [PATCH 119/243] Preparing for final test --- .github/workflows/publish.yml | 2 +- build.gradle | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ca8ced5..1b7cdda 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,7 +23,7 @@ jobs: - name: Publish run: | chmod +x gradlew - ./gradlew uploadArchives closeAndReleaseRepository + ./gradlew publish closeAndReleaseRepository env: ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} diff --git a/build.gradle b/build.gradle index ba40510..bee5511 100644 --- a/build.gradle +++ b/build.gradle @@ -152,16 +152,17 @@ publishing { url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl credentials { - username = project.hasProperty('nexusUsername') ? project.getProperty('nexusUsername') : '' - password = project.hasProperty('nexusPassword') ? project.getProperty('nexusPassword') : '' + username = project.findProperty('nexusUsername') ?: '' + password = project.findProperty('nexusPassword') ?: '' } } } } signing { - def signingKey = project.hasProperty('signingKey') ? project.getProperty('signingKey') : '' - def signingPassword = project.hasProperty('signingPassword') ? project.getProperty('signingPassword') : '' + def signingKey = project.findProperty('signingKey') ?: '' + def signingPassword = project.findProperty('signingPassword') ?: '' + useInMemoryPgpKeys(signingKey, signingPassword) sign publishing.publications.mavenJava From 3a38ca61662daf487f240ae0597b09ce3e852528 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 11:16:34 -0400 Subject: [PATCH 120/243] Need more retries for staging plugin. --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index bee5511..2993b4d 100644 --- a/build.gradle +++ b/build.gradle @@ -173,3 +173,9 @@ javadoc { options.addBooleanOption('html5', true) } } + +// configure nexus staging plugin +nexusStaging { + numberOfRetries = 50 + delayBetweenRetriesInMillis = 5000 +} \ No newline at end of file From 11fe98e3b5356f4c0fb846c96fbe2471b69d0c8f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 11:18:12 -0400 Subject: [PATCH 121/243] Final cleanup --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1b7cdda..3ebaa3a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,8 +5,8 @@ name: publish on: repository_dispatch: types: manual-publish -# release: -# types: [created] + release: + types: [created] jobs: publish: From 33d56b74cb1f3655b090bbf0eb1ac8913dbe316b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 21 May 2020 14:03:33 -0400 Subject: [PATCH 122/243] Up version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2993b4d..3daf805 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ plugins { } group = 'com.imsweb' -version = '3.18.1' +version = '3.18.2' description = 'Java client library for SEER*API' println "Starting build using ${Jvm.current()}" From c207da6f96d21a7622014bf5ea7d61046b1dca91 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 26 May 2020 09:37:19 -0400 Subject: [PATCH 123/243] Build tweak. --- .github/workflows/integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 949a297..c4ecc22 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -25,6 +25,6 @@ jobs: - name: Build and test run: | chmod +x gradlew - ./gradlew build + ./gradlew build --no-daemon env: SEER_API_KEY: ${{ secrets.SEER_API_KEY }} From 628b45d59f0f50c2b0a0ed6ffbc3785eff50611f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 27 May 2020 08:29:14 -0400 Subject: [PATCH 124/243] Teak caching --- .github/workflows/integration.yml | 6 ++++-- build.gradle | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index c4ecc22..be36242 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -17,9 +17,11 @@ jobs: with: java-version: 1.8 - name: Cache Gradle packages - uses: actions/cache@v1 + uses: actions/cache@v2 with: - path: ~/.gradle/caches + path: | + ~/.gradle/caches + ~/.gradle/wrapper key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - name: Build and test diff --git a/build.gradle b/build.gradle index 3daf805..4c6f6b5 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ import org.gradle.internal.jvm.Jvm plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.2.1" + id "com.github.spotbugs" version "4.2.3" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.21.2" From 16999622ac605d6d2505f9bc5bc7027ff579593c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 28 May 2020 14:09:57 -0400 Subject: [PATCH 125/243] Switch to SNAPSHOT version --- build.gradle | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 4c6f6b5..b7810a1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,3 @@ -import org.gradle.internal.jvm.Jvm - plugins { id 'java-library' id 'checkstyle' @@ -12,11 +10,9 @@ plugins { } group = 'com.imsweb' -version = '3.18.2' +version = '3.19-SNAPSHOT' description = 'Java client library for SEER*API' -println "Starting build using ${Jvm.current()}" - tasks.withType(JavaCompile) { options.encoding = 'UTF-8' options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Werror" From 22b7835785474ad681eafe0ad58d852575c338a5 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 2 Jun 2020 08:53:27 -0400 Subject: [PATCH 126/243] Added dependency check plugin --- build.gradle | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index b7810a1..ab992ae 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.2.3" + id "com.github.spotbugs" version "4.2.4" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.21.2" id 'com.adarshr.test-logger' version '2.0.0' id "com.github.ben-manes.versions" version "0.28.0" + id "org.owasp.dependencycheck" version "5.3.2.1" } group = 'com.imsweb' @@ -58,7 +59,7 @@ jar { } checkstyle { - toolVersion '8.28' + toolVersion '8.29' configFile = file("config/checkstyle/checkstyle.xml") } @@ -66,6 +67,12 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } +// OWASP check (https://jeremylong.github.io/DependencyCheck/index.html) +dependencyCheck { + failOnError = true + format = 'ALL' +} + // when checking for later versions, exclude alphas, betas, etc.. dependencyUpdates { resolutionStrategy { From c15895243d20c3790a29cc3ba1c4959783a268ff Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 8 Jun 2020 08:34:13 -0400 Subject: [PATCH 127/243] Spotbugs update --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ab992ae..152f953 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.2.4" + id "com.github.spotbugs" version "4.3.0" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.21.2" @@ -32,7 +32,7 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.0.3' + spotbugs 'com.github.spotbugs:spotbugs:4.0.4' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' From 3f29398724c8188b33a9abacc661d5cef79b4ae8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 8 Jun 2020 08:36:42 -0400 Subject: [PATCH 128/243] Maven missing dep --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 152f953..b1edd97 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.0.4' + spotbugs 'com.github.spotbugs:spotbugs:4.0.3' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' From cb76220005ee332ad374bf3237d8304efe37fe9f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 8 Jun 2020 14:50:48 -0400 Subject: [PATCH 129/243] Cleanup --- build.gradle | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index b1edd97..c05fdbc 100644 --- a/build.gradle +++ b/build.gradle @@ -73,19 +73,10 @@ dependencyCheck { format = 'ALL' } -// when checking for later versions, exclude alphas, betas, etc.. dependencyUpdates { - resolutionStrategy { - componentSelection { rules -> - rules.all { ComponentSelection selection -> - boolean rejected = ['alpha', 'beta', 'rc', 'cr', 'm'].any { qualifier -> - selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/ - } - if (rejected) { - selection.reject('Release candidate') - } - } - } + // ignore alpha, beta, etc. versions + rejectVersionIf { selection -> + isNonStable(selection.candidate.version) } } From 0908e5ebe27dffb21d50a5ff953c994d44fd580f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 8 Jun 2020 15:12:27 -0400 Subject: [PATCH 130/243] Ugh. --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index c05fdbc..52b4443 100644 --- a/build.gradle +++ b/build.gradle @@ -75,9 +75,9 @@ dependencyCheck { dependencyUpdates { // ignore alpha, beta, etc. versions - rejectVersionIf { selection -> - isNonStable(selection.candidate.version) - } +// rejectVersionIf { selection -> +// isNonStable(selection.candidate.version) +// } } wrapper { From 6c4c07ad4995f5566674f90ea8288e258f0fe715 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 8 Jun 2020 16:09:34 -0400 Subject: [PATCH 131/243] Cleanup --- build.gradle | 7 ------- 1 file changed, 7 deletions(-) diff --git a/build.gradle b/build.gradle index 52b4443..fbc6cde 100644 --- a/build.gradle +++ b/build.gradle @@ -73,13 +73,6 @@ dependencyCheck { format = 'ALL' } -dependencyUpdates { - // ignore alpha, beta, etc. versions -// rejectVersionIf { selection -> -// isNonStable(selection.candidate.version) -// } -} - wrapper { gradleVersion = '6.4.1' distributionType = Wrapper.DistributionType.ALL From 8db3ca392c87ddbd6fc25996a3516d974e81e198 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 9 Jun 2020 08:10:44 -0400 Subject: [PATCH 132/243] Update Spotbugs --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index fbc6cde..4a9783f 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.0.3' + spotbugs 'com.github.spotbugs:spotbugs:4.0.4' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' From f9fbf4630ad4cce9152a180f20b6f02d1f786816 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 1 Oct 2020 08:57:45 -0400 Subject: [PATCH 133/243] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..a486ead --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,71 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +name: "CodeQL" + +on: + push: + branches: [master] + pull_request: + # The branches below must be a subset of the branches above + branches: [master] + schedule: + - cron: '0 18 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # Override automatic language detection by changing the below list + # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] + language: ['java'] + # Learn more... + # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + # We must fetch at least the immediate parents so that if this is + # a pull request then we can checkout the head. + fetch-depth: 2 + + # If this run was triggered by a pull request event, then checkout + # the head of the pull request instead of the merge commit. + - run: git checkout HEAD^2 + if: ${{ github.event_name == 'pull_request' }} + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From f743f243b9f086a81f4c507c37a9f4255a68542f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 1 Oct 2020 09:35:45 -0400 Subject: [PATCH 134/243] Added support for "naaccr_xml_id" --- .../client/staging/StagingSchemaInput.java | 13 ++++++++++++- .../client/staging/StagingSchemaOutput.java | 13 ++++++++++++- .../imsweb/seerapi/client/ndc/NdcTest.java | 2 +- .../seerapi/client/staging/StagingTest.java | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java index 346d3ba..3301bb8 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java @@ -11,13 +11,14 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "values", "default", "table", "used_for_staging", "fail_on_invalid", "unit", "decimal_places", "metadata"}) +@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "values", "default", "table", "used_for_staging", "fail_on_invalid", "unit", "decimal_places", "metadata"}) public class StagingSchemaInput { private String _key; private String _name; private String _description; private Integer _naaccrItem; + private String _naaccrXmlId; private String _default; private String _table; private Boolean _usedForStaging; @@ -51,6 +52,7 @@ public StagingSchemaInput(StagingSchemaInput other) { setName(other.getName()); setDescription(other.getDescription()); setNaaccrItem(other.getNaaccrItem()); + setNaaccrXmlId(other.getNaaccrXmlId()); setDefault(other.getDefault()); setTable(other.getTable()); if (other.getMetadata() != null) @@ -96,6 +98,15 @@ public void setNaaccrItem(Integer naaccrItem) { _naaccrItem = naaccrItem; } + @JsonProperty("naaccr_xml_id") + public String getNaaccrXmlId() { + return _naaccrXmlId; + } + + public void setNaaccrXmlId(String naaccrXmlId) { + _naaccrXmlId = naaccrXmlId; + } + @JsonProperty("default") public String getDefault() { return _default; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java index a2ba9e4..ef2db06 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java @@ -6,13 +6,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "table"}) +@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "table"}) public class StagingSchemaOutput { private String _key; private String _name; private String _description; private Integer _naaccrItem; + private String _naaccrXmlId; private String _table; private String _default; @@ -42,6 +43,7 @@ public StagingSchemaOutput(StagingSchemaOutput other) { setName(other.getName()); setDescription(other.getDescription()); setNaaccrItem(other.getNaaccrItem()); + setNaaccrXmlId(other.getNaaccrXmlId()); setTable(other.getTable()); setDefault(other.getDefault()); } @@ -82,6 +84,15 @@ public void setNaaccrItem(Integer naaccrItem) { _naaccrItem = naaccrItem; } + @JsonProperty("naaccr_xml_id") + public String getNaaccrXmlId() { + return _naaccrXmlId; + } + + public void setNaaccrXmlId(String naaccrXmlId) { + _naaccrXmlId = naaccrXmlId; + } + @JsonProperty("table") public String getTable() { return _table; diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index f7aedd5..01296a0 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -94,7 +94,7 @@ public void testNdcSearch() throws IOException { products = _NDC.search(search.paramMap()).execute().body(); assertThat(products.size()).isGreaterThan(1); - search.setRemovedSince("2020-01-06"); + search.setRemovedSince("2020-10-01"); products = _NDC.search(search.paramMap()).execute().body(); assertThat(products).isEmpty(); diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 8698560..28733b2 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -82,6 +82,25 @@ public void testSchemaById() throws IOException { assertThat(schema.getAlgorithm()).isEqualTo("cs"); assertThat(schema.getVersion()).isEqualTo("02.05.50"); assertThat(schema.getId()).isEqualTo("brain"); + + // verify the inputs + StagingSchemaInput input = schema.getInputs().stream().filter(i -> "site".equals(i.getKey())).findFirst().orElse(null); + assertThat(input).isNotNull(); + assertThat(input.getName()).isEqualTo("Primary Site"); + assertThat(input.getDescription()).isEqualTo("Code for the primary site of the tumor being reported using either ICD-O-2 or ICD-O-3."); + assertThat(input.getNaaccrItem()).isEqualTo(400); + assertThat(input.getNaaccrXmlId()).isEqualTo("primarySite"); + assertThat(input.getUsedForStaging()).isTrue(); + assertThat(input.getTable()).isEqualTo("primary_site"); + + // verify the outputs + StagingSchemaOutput output = schema.getOutputs().stream().filter(i -> "csver_derived".equals(i.getKey())).findFirst().orElse(null); + assertThat(output).isNotNull(); + assertThat(output.getName()).isEqualTo("CS Version Derived"); + assertThat(output.getDescription()).isEqualTo("Collaborative Staging (CS) version used to derive the CS output fields."); + assertThat(output.getNaaccrItem()).isEqualTo(2936); + assertThat(output.getNaaccrXmlId()).isEqualTo("csVersionDerived"); + assertThat(output.getDefault()).isEqualTo("020550"); } @Test From d690f622a1bf408fdaa28cb568a08b5f111a1c72 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 1 Oct 2020 09:42:17 -0400 Subject: [PATCH 135/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6d3dcba..75e8293 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.18 + 3.19 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.18' +compile 'com.imsweb:seerapi-client-java:3.19' ``` ## Usage diff --git a/build.gradle b/build.gradle index 4a9783f..278333e 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.19-SNAPSHOT' +version = '3.19' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From c53fd0ef399d5daaa3c9aed88a47c767f8aee2a9 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 1 Oct 2020 09:57:32 -0400 Subject: [PATCH 136/243] Set to SNAPSHOT version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 278333e..a4cb2fe 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.19' +version = '3.20-SNAPSHOT' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From ab837daf6e37bd5d94c7f91a5bae3b1ebe8d0d19 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 1 Oct 2020 10:11:20 -0400 Subject: [PATCH 137/243] Dependency updates --- build.gradle | 16 ++++++++-------- gradle/wrapper/gradle-wrapper.jar | Bin 58910 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- gradlew.bat | 21 +++------------------ 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/build.gradle b/build.gradle index a4cb2fe..55848d2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.3.0" + id "com.github.spotbugs" version "4.5.1" id 'maven-publish' id 'signing' - id "io.codearte.nexus-staging" version "0.21.2" - id 'com.adarshr.test-logger' version '2.0.0' - id "com.github.ben-manes.versions" version "0.28.0" - id "org.owasp.dependencycheck" version "5.3.2.1" + id "io.codearte.nexus-staging" version "0.22.0" + id 'com.adarshr.test-logger' version '2.1.0' + id "com.github.ben-manes.versions" version "0.33.0" + id "org.owasp.dependencycheck" version "6.0.2" } group = 'com.imsweb' @@ -32,13 +32,13 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.0.4' + spotbugs 'com.github.spotbugs:spotbugs:4.1.3' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' testImplementation 'junit:junit:4.13' - testImplementation 'org.assertj:assertj-core:3.16.1' + testImplementation 'org.assertj:assertj-core:3.17.2' } jar { @@ -74,7 +74,7 @@ dependencyCheck { } wrapper { - gradleVersion = '6.4.1' + gradleVersion = '6.6.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053550b91381bbd28b1afc82d634bf73a8a..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 6656 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 Yte!%o?r4GTrVtxD61Ym!|5fq-1K$0e!T1w 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 21e622d..33682bb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c51..4f906e0 100644 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell From 85c597422b1df322d8bf57eb4344affde9593607 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 1 Oct 2020 16:28:13 -0400 Subject: [PATCH 138/243] Update codeql-analysis.yml General cleanup --- .github/workflows/codeql-analysis.yml | 31 ++------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a486ead..44e8830 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,8 +1,3 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. name: "CodeQL" on: @@ -22,22 +17,16 @@ jobs: strategy: fail-fast: false matrix: - # Override automatic language detection by changing the below list - # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] language: ['java'] - # Learn more... - # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - name: Checkout repository uses: actions/checkout@v2 with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. + # We must fetch at least the immediate parents so that if this is a pull request then we can checkout the head. fetch-depth: 2 - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. + # If this run was triggered by a pull request event, then checkout the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} @@ -46,26 +35,10 @@ jobs: uses: github/codeql-action/init@v1 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v1 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 From e9191f7507aad8e766b913cc84c518a85d571ade Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 13:08:29 -0500 Subject: [PATCH 139/243] Added missing staging glossary endpoints --- build.gradle | 14 ++++----- gradle/wrapper/gradle-wrapper.properties | 2 +- .../client/glossary/GlossaryService.java | 17 +++++++++++ .../seerapi/client/shared/KeywordMatch.java | 30 +++++++++++++++++++ .../client/staging/StagingService.java | 28 +++++++++++++++++ .../seerapi/client/glossary/GlossaryTest.java | 19 +++++++++++- .../seerapi/client/staging/StagingTest.java | 18 +++++++++++ 7 files changed, 119 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 55848d2..eb2d015 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,9 @@ plugins { id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.22.0" - id 'com.adarshr.test-logger' version '2.1.0' - id "com.github.ben-manes.versions" version "0.33.0" - id "org.owasp.dependencycheck" version "6.0.2" + id 'com.adarshr.test-logger' version '2.1.1' + id "com.github.ben-manes.versions" version "0.34.0" + id "org.owasp.dependencycheck" version "6.0.3" } group = 'com.imsweb' @@ -32,13 +32,13 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.1.3' + spotbugs 'com.github.spotbugs:spotbugs:4.1.4' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' - testImplementation 'junit:junit:4.13' - testImplementation 'org.assertj:assertj-core:3.17.2' + testImplementation 'junit:junit:4.13.1' + testImplementation 'org.assertj:assertj-core:3.18.0' } jar { @@ -74,7 +74,7 @@ dependencyCheck { } wrapper { - gradleVersion = '6.6.1' + gradleVersion = '6.7' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 33682bb..14e30f7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java index f1dd0d5..5ef8542 100644 --- a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java +++ b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryService.java @@ -8,11 +8,17 @@ import java.util.Set; import retrofit2.Call; +import retrofit2.http.Body; import retrofit2.http.GET; +import retrofit2.http.Headers; +import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.QueryMap; +import com.imsweb.seerapi.client.glossary.Glossary.Category; +import com.imsweb.seerapi.client.shared.KeywordMatch; + public interface GlossaryService { /** @@ -80,4 +86,15 @@ public interface GlossaryService { @GET("glossary/{version}/changelog") Call changelogs(@Path("version") String version, @Query("from") String fromDate, @Query("to") String toDate, @Query("count") Integer count); + /** + * Return a glossary results for a staging table + * @param text text to look up glossary references + * @param categories options list of categories + * @param wholeWordsOnly if true, only return whole word matcehs + * @return a set of matches + */ + @Headers("Content-Type:text/plain") + @POST("glossary/match") + Call> match(@Body String text, @Query("category") Set categories, @Query("wholeWordsOnly") Boolean wholeWordsOnly); + } diff --git a/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java b/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java index 29cd1c9..8da5be7 100644 --- a/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java +++ b/src/main/java/com/imsweb/seerapi/client/shared/KeywordMatch.java @@ -11,10 +11,16 @@ public class KeywordMatch { @JsonProperty("id") private String _id; + @JsonProperty("name") + private String _name; @JsonProperty("keyword") private String _keyword; @JsonProperty("category") private Set _category; + @JsonProperty("start") + private Integer _start; + @JsonProperty("end") + private Integer _end; public String getId() { return _id; @@ -24,6 +30,14 @@ public void setId(String id) { _id = id; } + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + public String getKeyword() { return _keyword; } @@ -39,4 +53,20 @@ public Set getCategory() { public void setCategory(Set category) { _category = category; } + + public Integer getStart() { + return _start; + } + + public void setStart(Integer start) { + _start = start; + } + + public Integer getEnd() { + return _end; + } + + public void setEnd(Integer end) { + _end = end; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java index 4986f15..4db4dfa 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Map; +import java.util.Set; import retrofit2.Call; import retrofit2.http.Body; @@ -13,6 +14,9 @@ import retrofit2.http.Path; import retrofit2.http.Query; +import com.imsweb.seerapi.client.glossary.Glossary.Category; +import com.imsweb.seerapi.client.shared.KeywordMatch; + public interface StagingService { /** @@ -69,6 +73,18 @@ public interface StagingService { @GET("staging/{algorithm}/{version}/schema/{id}") Call schemaById(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id); + /** + * Return a glossary results for a staging schema + * @param algorithm an algorithm identifier + * @param version a version + * @param id a table identifier + * @param categories options list of categories + * @param wholeWordsOnly if true, only return whole word matcehs + * @return a set of matches + */ + @GET("staging/{algorithm}/{version}/schema/{id}/glossary") + Call> schemaGlossary(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id, @Query("category") Set categories, @Query("wholeWordsOnly") Boolean wholeWordsOnly); + /** * Return a list of tables which are involved in the specified schema * @param algorithm an algorithm identifier @@ -108,6 +124,18 @@ public interface StagingService { @GET("staging/{algorithm}/{version}/table/{id}") Call tableById(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id); + /** + * Return a glossary results for a staging table + * @param algorithm an algorithm identifier + * @param version a version + * @param id a table identifier + * @param categories options list of categories + * @param wholeWordsOnly if true, only return whole word matcehs + * @return a set of matches + */ + @GET("staging/{algorithm}/{version}/table/{id}/glossary") + Call> tableGlossary(@Path("algorithm") String algorithm, @Path("version") String version, @Path("id") String id, @Query("category") Set categories, @Query("wholeWordsOnly") Boolean wholeWordsOnly); + /** * Return a list of schemas which the specified table is involved in * @param algorithm an algorithm identifier diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index 2f6cfed..d4097b6 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -6,7 +6,9 @@ import java.io.IOException; import java.util.Collections; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.junit.Assert; import org.junit.BeforeClass; @@ -14,7 +16,9 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; +import com.imsweb.seerapi.client.shared.KeywordMatch; +import static com.imsweb.seerapi.client.glossary.Glossary.Category.GENERAL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -54,7 +58,7 @@ public void testGlossaryById() throws IOException { Assert.assertNotNull(glossary); Assert.assertEquals("Lymphangiogram", glossary.getName()); - Assert.assertEquals(Collections.singletonList(Glossary.Category.GENERAL), glossary.getCategories()); + Assert.assertEquals(Collections.singletonList(GENERAL), glossary.getCategories()); Assert.assertNull(glossary.getPrimarySite()); Assert.assertNull(glossary.getHistology()); @@ -150,4 +154,17 @@ public void testGlossarySearchIterate() throws IOException { Assert.assertTrue(total > 100); } + @Test + public void testGlossaryMatch() throws IOException { + String text = "This text contains summary stage which should be found."; + + Set matches = _GLOSSARY.match(text, null, true).execute().body(); + Assert.assertNotNull(matches); + Assert.assertEquals(matches.size(), 1); + + matches = _GLOSSARY.match(text, new HashSet<>(Collections.singletonList(GENERAL)), true).execute().body(); + Assert.assertNotNull(matches); + Assert.assertEquals(matches.size(), 0); + } + } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 28733b2..2c4a571 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -4,12 +4,17 @@ package com.imsweb.seerapi.client.staging; import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.junit.BeforeClass; import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.glossary.Glossary.Category; +import com.imsweb.seerapi.client.shared.KeywordMatch; import com.imsweb.seerapi.client.staging.cs.CsSchemaLookup; import static org.assertj.core.api.Assertions.assertThat; @@ -231,4 +236,17 @@ public void testStagingWithErrors() throws IOException { assertThat(output.getErrors()).hasSize(9); } + @Test + public void testStagingGlossary() throws IOException { + Set matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", null, true).execute().body(); + assertThat(matches).hasSize(26); + matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", new HashSet<>(Collections.singletonList(Category.STAGING)), true).execute().body(); + assertThat(matches).hasSize(1); + + matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", null, true).execute().body(); + assertThat(matches).hasSize(20); + matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", new HashSet<>(Collections.singletonList(Category.STAGING)), true).execute().body(); + assertThat(matches).isEmpty(); + } + } From a2c3913406b9ba015916aa0814a32f588ebdaa5f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 13:10:16 -0500 Subject: [PATCH 140/243] Cleanup --- .../com/imsweb/seerapi/client/glossary/GlossaryTest.java | 3 +-- .../com/imsweb/seerapi/client/staging/StagingTest.java | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index d4097b6..e7043e6 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -6,7 +6,6 @@ import java.io.IOException; import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -162,7 +161,7 @@ public void testGlossaryMatch() throws IOException { Assert.assertNotNull(matches); Assert.assertEquals(matches.size(), 1); - matches = _GLOSSARY.match(text, new HashSet<>(Collections.singletonList(GENERAL)), true).execute().body(); + matches = _GLOSSARY.match(text, EnumSet.of(GENERAL), true).execute().body(); Assert.assertNotNull(matches); Assert.assertEquals(matches.size(), 0); } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 2c4a571..6bb0f86 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -4,8 +4,7 @@ package com.imsweb.seerapi.client.staging; import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; +import java.util.EnumSet; import java.util.List; import java.util.Set; @@ -240,12 +239,12 @@ public void testStagingWithErrors() throws IOException { public void testStagingGlossary() throws IOException { Set matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", null, true).execute().body(); assertThat(matches).hasSize(26); - matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", new HashSet<>(Collections.singletonList(Category.STAGING)), true).execute().body(); + matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", EnumSet.of(Category.STAGING), true).execute().body(); assertThat(matches).hasSize(1); matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", null, true).execute().body(); assertThat(matches).hasSize(20); - matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", new HashSet<>(Collections.singletonList(Category.STAGING)), true).execute().body(); + matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", EnumSet.of(Category.STAGING), true).execute().body(); assertThat(matches).isEmpty(); } From 668879b1fd294d192eb9f56f0224e6aea8ed6e32 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 13:18:35 -0500 Subject: [PATCH 141/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 75e8293..a34ceba 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.19 + 3.20 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.19' +compile 'com.imsweb:seerapi-client-java:3.20' ``` ## Usage diff --git a/build.gradle b/build.gradle index eb2d015..9477b45 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.20-SNAPSHOT' +version = '3.20' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 8c475329c924f60a1f5c57b18ed633d2d9a62bfc Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 13:37:03 -0500 Subject: [PATCH 142/243] Move to SNAPSHOT version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9477b45..5391443 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.20' +version = '3.21-SNAPSHOT' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 21dce96b204d7a62bcad2e0bd393eac9125f7d41 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 14:25:49 -0500 Subject: [PATCH 143/243] Added unused query parameter to tables endpoint --- .../imsweb/seerapi/client/staging/StagingService.java | 11 +++++++++++ .../imsweb/seerapi/client/staging/StagingTest.java | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java index 4db4dfa..aa44c30 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingService.java @@ -114,6 +114,17 @@ public interface StagingService { @GET("staging/{algorithm}/{version}/tables") Call> tables(@Path("algorithm") String algorithm, @Path("version") String version, @Query("q") String query); + /** + * Return a list of matching tables + * @param algorithm an algorithm identifier + * @param version a version + * @param query an optional text query + * @param unusedOnly if true, limit to unused tables + * @return a list of staging tables + */ + @GET("staging/{algorithm}/{version}/tables") + Call> tables(@Path("algorithm") String algorithm, @Path("version") String version, @Query("q") String query, @Query("unused") Boolean unusedOnly); + /** * Return a single table definition by table identifier * @param algorithm an algorithm identifier diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 6bb0f86..760cec1 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -117,7 +117,11 @@ public void testSchemaInvolvedTables() throws IOException { @Test public void testListTables() throws IOException { List tables = _STAGING.tables(_ALGORITHM, _VERSION, "ssf1").execute().body(); + assertThat(tables).isNotEmpty(); + tables = _STAGING.tables(_ALGORITHM, _VERSION, null, true).execute().body(); + assertThat(tables).isEmpty(); + tables = _STAGING.tables(_ALGORITHM, _VERSION, null, false).execute().body(); assertThat(tables).isNotEmpty(); } From d3ad3703db06bfe0f250019fce46cabfc1f96cd0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 14:30:56 -0500 Subject: [PATCH 144/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a34ceba..79dec29 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.20 + 3.21 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.20' +compile 'com.imsweb:seerapi-client-java:3.21' ``` ## Usage diff --git a/build.gradle b/build.gradle index 5391443..9d1213a 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.21-SNAPSHOT' +version = '3.21' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 0e01ea2f6554d237bfad2942de140f5d4b0b4b12 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 4 Nov 2020 14:50:50 -0500 Subject: [PATCH 145/243] Move to SNAPSHOT version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9d1213a..98f258b 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.21' +version = '3.22-SNAPSHOT' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From f4b06a9c8e89fad212368c7457d6b3d5afb5f28a Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 19 Feb 2021 16:25:48 -0500 Subject: [PATCH 146/243] Added support for new NAACCR endpoints. Supports both flat and XML versions. --- build.gradle | 32 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- .../client/naaccr/NaaccrFieldName.java | 10 ++ ...{NaaccrField.java => NaaccrFlatField.java} | 12 +- .../seerapi/client/naaccr/NaaccrService.java | 51 ++++-- .../seerapi/client/naaccr/NaaccrVersion.java | 30 ++++ .../seerapi/client/naaccr/NaaccrXmlField.java | 149 ++++++++++++++++++ .../seerapi/client/naaccr/NaaccrTest.java | 63 +++++++- .../com/imsweb/seerapi/client/rx/RxTest.java | 4 +- .../seerapi/client/staging/StagingTest.java | 2 +- 10 files changed, 322 insertions(+), 33 deletions(-) rename src/main/java/com/imsweb/seerapi/client/naaccr/{NaaccrField.java => NaaccrFlatField.java} (92%) create mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java diff --git a/build.gradle b/build.gradle index 98f258b..6d0d798 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.5.1" + id "com.github.spotbugs" version "4.6.1" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.22.0" id 'com.adarshr.test-logger' version '2.1.1' - id "com.github.ben-manes.versions" version "0.34.0" - id "org.owasp.dependencycheck" version "6.0.3" + id "com.github.ben-manes.versions" version "0.36.0" + id 'org.sonatype.gradle.plugins.scan' version '2.0.3' } group = 'com.imsweb' @@ -32,13 +32,13 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.1.4' + spotbugs 'com.github.spotbugs:spotbugs:4.2.1' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' - testImplementation 'junit:junit:4.13.1' - testImplementation 'org.assertj:assertj-core:3.18.0' + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.assertj:assertj-core:3.19.0' } jar { @@ -67,14 +67,24 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } -// OWASP check (https://jeremylong.github.io/DependencyCheck/index.html) -dependencyCheck { - failOnError = true - format = 'ALL' +// Nexus vulnerability scan (see https://github.com/sonatype-nexus-community/scan-gradle-plugin) +ossIndexAudit { + dependencyGraph = true + printBanner = false + + // only set proxy if running outside of Github Actions + if (!System.getenv().GITHUB_ACTIONS) { + proxyConfiguration { + protocol = 'http' + host = 'webproxy-btp.imsweb.com' + port = 8080 + } + } } +check.dependsOn 'ossIndexAudit' wrapper { - gradleVersion = '6.7' + gradleVersion = '6.8.2' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 14e30f7..25d3265 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java index b19dd61..20f4b51 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java @@ -7,11 +7,21 @@ public class NaaccrFieldName { + @JsonProperty("id") + protected String _id; @JsonProperty("item") protected Integer _item; @JsonProperty("name") protected String _name; + public String getId() { + return _id; + } + + public void setId(String id) { + _id = id; + } + public Integer getItem() { return _item; } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java similarity index 92% rename from src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java rename to src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java index db3696f..859344f 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrField.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java @@ -9,8 +9,10 @@ import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonPropertyOrder({"item", "name", "section", "start_col", "end_col", "alignment", "padding_char", "default_value", "documentation", "subfield"}) -public class NaaccrField { +public class NaaccrFlatField { + @JsonProperty("id") + protected String _id; @JsonProperty("item") protected Integer _item; @JsonProperty("name") @@ -32,6 +34,14 @@ public class NaaccrField { @JsonProperty("subfield") protected List _subFields; + public String getId() { + return _id; + } + + public void setId(String id) { + _id = id; + } + public Integer getItem() { return _item; } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java index eebc8a4..c155e4f 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java @@ -12,27 +12,60 @@ public interface NaaccrService { /** - * Return a collection of NaaccrVersion objects which descibe the available versions + * Return a collection of NaaccrVersion objects which descibe the available flat file versions * @return a list of the available NAACCR versions and information about each of them */ - @GET("naaccr/versions") - Call> versions(); + @GET("naaccr/flat/versions") + Call> flatVersions(); /** - * Return a list of all the field identifiers and names from a specified NAACCR version + * Return a collection of NaaccrVersion objects which descibe the available XML versions + * @return a list of the available NAACCR versions and information about each of them + */ + @GET("naaccr/xml/versions") + Call> xmlVersions(); + + /** + * Return a list of all the field identifiers and names from a specified NAACCR flat file version + * @param version NAACCR version + * @return a list of NaaccrFieldName objects + */ + @GET("naaccr/flat/{version}") + Call> flatFieldNames(@Path("version") String version); + + /** + * Return a list of all the field identifiers and names from a specified NAACCR XML version + * @param version NAACCR version + * @return a list of NaaccrFieldName objects + */ + @GET("naaccr/xml/{version}") + Call> xmlFieldNames(@Path("version") String version); + + /** + * Return a list of all the field identifiers and names from a specified NAACCR flat file version + * @param version NAACCR version + * @param item NAACCR item number + * @return a list of NaaccrFieldName objects + */ + @GET("naaccr/flat/{version}/item/{item}") + Call flatField(@Path("version") String version, @Path("item") Integer item); + + /** + * Return a list of all the field identifiers and names from a specified NAACCR XML version * @param version NAACCR version + * @param id NAACCR XML id * @return a list of NaaccrFieldName objects */ - @GET("naaccr/{version}") - Call> fieldNames(@Path("version") String version); + @GET("naaccr/xml/{version}/id/{id}") + Call xmlField(@Path("version") String version, @Path("id") String id); /** - * Return a list of all the field identifiers and names from a specified NAACCR version + * Return a list of all the field identifiers and names from a specified NAACCR XML version * @param version NAACCR version * @param item NAACCR item number * @return a list of NaaccrFieldName objects */ - @GET("naaccr/{version}/item/{item}") - Call field(@Path("version") String version, @Path("item") Integer item); + @GET("naaccr/xml/{version}/item/{item}") + Call xmlField(@Path("version") String version, @Path("item") Integer item); } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java index ad08b8b..eabf2f4 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java @@ -14,6 +14,12 @@ public class NaaccrVersion { protected String _description; @JsonProperty("style") protected String _style; + @JsonProperty("dictionary_uri") + protected String dictionaryUri; + @JsonProperty("dictionary_description") + protected String dictionaryDescription; + @JsonProperty("specification_version") + protected String specificationVersion; public String getVersion() { return _version; @@ -54,4 +60,28 @@ public String getStyle() { public void setStyle(String style) { _style = style; } + + public String getDictionaryUri() { + return dictionaryUri; + } + + public void setDictionaryUri(String dictionaryUri) { + this.dictionaryUri = dictionaryUri; + } + + public String getDictionaryDescription() { + return dictionaryDescription; + } + + public void setDictionaryDescription(String dictionaryDescription) { + this.dictionaryDescription = dictionaryDescription; + } + + public String getSpecificationVersion() { + return specificationVersion; + } + + public void setSpecificationVersion(String specificationVersion) { + this.specificationVersion = specificationVersion; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java new file mode 100644 index 0000000..785c2ba --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2011 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.naaccr; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({"id", "item", "name", "section", "parent_xml_element", "record_types", "data_type", "length", "start_col", + "pad_type", "trim_type", "allow_unlimited_text", "documentation"}) +public class NaaccrXmlField { + + @JsonProperty("id") + protected String _naaccrId; + @JsonProperty("item") + protected Integer _naaccrItemNum; + @JsonProperty("name") + protected String _name; + @JsonProperty("section") + protected String _section; + @JsonProperty("start_col") + protected Integer _start; + @JsonProperty("record_types") + protected List _recordTypes; + @JsonProperty("length") + protected Integer _length; + @JsonProperty("pad_type") + protected String _padType; + @JsonProperty("data_type") + protected String _dataType; + @JsonProperty("trim_type") + protected String _trimType; + @JsonProperty("allow_unlimited_text") + protected Boolean _allowUnlimitedText; + @JsonProperty("parent_xml_element") + protected String _parentXmlElement; + @JsonProperty("documentation") + protected String _documentation; + + public NaaccrXmlField() { + } + + public String getNaaccrId() { + return _naaccrId; + } + + public void setNaaccrId(String naaccrId) { + _naaccrId = naaccrId; + } + + public Integer getNaaccrItemNum() { + return _naaccrItemNum; + } + + public void setNaaccrItemNum(Integer naaccrItemNum) { + _naaccrItemNum = naaccrItemNum; + } + + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + + public String getSection() { + return _section; + } + + public void setSection(String section) { + _section = section; + } + + public Integer getStart() { + return _start; + } + + public void setStart(Integer start) { + _start = start; + } + + public List getRecordTypes() { + return _recordTypes; + } + + public void setRecordTypes(List recordTypes) { + _recordTypes = recordTypes; + } + + public Integer getLength() { + return _length; + } + + public void setLength(Integer length) { + _length = length; + } + + public String getPadType() { + return _padType; + } + + public void setPadType(String padType) { + _padType = padType; + } + + public String getDataType() { + return _dataType; + } + + public void setDataType(String dataType) { + _dataType = dataType; + } + + public String getTrimType() { + return _trimType; + } + + public void setTrimType(String trimType) { + _trimType = trimType; + } + + public Boolean getAllowUnlimitedText() { + return _allowUnlimitedText; + } + + public void setAllowUnlimitedText(Boolean allowUnlimitedText) { + _allowUnlimitedText = allowUnlimitedText; + } + + public String getParentXmlElement() { + return _parentXmlElement; + } + + public void setParentXmlElement(String parentXmlElement) { + _parentXmlElement = parentXmlElement; + } + + public String getDocumentation() { + return _documentation; + } + + public void setDocumentation(String documentation) { + _documentation = documentation; + } + +} diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index cbd6279..ce8987e 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -23,22 +23,39 @@ public static void setup() { } @Test - public void testNaaccrVersions() throws IOException { - List versions = _NAACCR.versions().execute().body(); + public void testNaaccrFlatVersions() throws IOException { + List versions = _NAACCR.flatVersions().execute().body(); assertThat(versions).isNotNull().isNotEmpty(); for (NaaccrVersion version : versions) { assertThat(version.getVersion()).isNotEmpty(); assertThat(version.getName()).isNotEmpty(); assertThat(version.getLength()).isGreaterThanOrEqualTo(22824); - assertThat(version.getDescription()).isNotEmpty(); + assertThat(version.getDescription()).isNull(); assertThat(version.getStyle()).isNotEmpty(); } } @Test - public void testNaaccrFieldNames() throws IOException { - List names = _NAACCR.fieldNames("latest").execute().body(); + public void testNaaccrXmlVersions() throws IOException { + List versions = _NAACCR.xmlVersions().execute().body(); + + assertThat(versions).isNotNull().isNotEmpty(); + for (NaaccrVersion version : versions) { + assertThat(version.getVersion()).isNotEmpty(); + assertThat(version.getName()).isNotEmpty(); + assertThat(version.getLength()).isNull(); + assertThat(version.getDescription()).isNull(); + assertThat(version.getStyle()).isNotEmpty(); + assertThat(version.getDictionaryUri()).isNotEmpty(); + assertThat(version.getDictionaryDescription()).isNotEmpty(); + assertThat(version.getSpecificationVersion()).isNotEmpty(); + } + } + + @Test + public void testNaaccrFlatFieldNames() throws IOException { + List names = _NAACCR.flatFieldNames("latest").execute().body(); assertThat(names).isNotNull(); for (NaaccrFieldName name : names) { @@ -48,8 +65,20 @@ public void testNaaccrFieldNames() throws IOException { } @Test - public void testNaaccrField() throws IOException { - NaaccrField name = _NAACCR.field("16", 521).execute().body(); + public void testNaaccrXmlFieldNames() throws IOException { + List names = _NAACCR.xmlFieldNames("latest").execute().body(); + + assertThat(names).isNotNull(); + for (NaaccrFieldName name : names) { + assertThat(name.getId()).isNotEmpty(); + assertThat(name.getItem()).isGreaterThan(0); + assertThat(name.getName()).isNotEmpty(); + } + } + + @Test + public void testNaaccrFlatField() throws IOException { + NaaccrFlatField name = _NAACCR.flatField("16", 521).execute().body(); assertThat(name).isNotNull(); assertThat(name.getName()).isEqualTo("Morph--Type&Behav ICD-O-3"); @@ -72,11 +101,29 @@ public void testNaaccrField() throws IOException { assertThat(sub.getPadChar()).isEqualTo(" "); // test one with default value - NaaccrField recordID = _NAACCR.field("18", 10).execute().body(); + NaaccrFlatField recordID = _NAACCR.flatField("18", 10).execute().body(); assertThat(recordID).isNotNull(); assertThat(recordID.getName()).isEqualTo("Record Type"); assertThat(recordID.getSection()).isEqualTo("Record ID"); assertThat(recordID.getDefaultValue()).isEqualTo("A"); } + @Test + public void testNaaccrXmlField() throws IOException { + NaaccrXmlField name = _NAACCR.xmlField("21", "phase2RadiationExternalBeamTech").execute().body(); + + assertThat(name).isNotNull(); + assertThat(name.getNaaccrId()).isEqualTo("phase2RadiationExternalBeamTech"); + assertThat(name.getNaaccrItemNum()).isEqualTo(1512); + assertThat(name.getName()).isEqualTo("Phase II Radiation External Beam Planning Tech"); + assertThat(name.getSection()).isEqualTo("Treatment-1st Course"); + assertThat(name.getParentXmlElement()).isEqualTo("Tumor"); + assertThat(name.getRecordTypes()).containsExactly("A", "M", "C", "I"); + assertThat(name.getDataType()).isEqualTo("digits"); + assertThat(name.getLength()).isEqualTo(2); + assertThat(name.getPadType()).isEqualTo("rightBlank"); + assertThat(name.getTrimType()).isEqualTo("all"); + assertThat(name.getAllowUnlimitedText()).isEqualTo(false); + assertThat(name.getDocumentation()).isNotEmpty(); + } } diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index fad1ca7..6a61660 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -107,8 +107,8 @@ public void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(9, results.getTotal().longValue()); - assertEquals(9, results.getResults().size()); + assertEquals(10, results.getTotal().longValue()); + assertEquals(10, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 760cec1..8c5e0dc 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -247,7 +247,7 @@ public void testStagingGlossary() throws IOException { assertThat(matches).hasSize(1); matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", null, true).execute().body(); - assertThat(matches).hasSize(20); + assertThat(matches).hasSize(24); matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", EnumSet.of(Category.STAGING), true).execute().body(); assertThat(matches).isEmpty(); } From 277d3943779c6ea7399face2720bdaaea25129d6 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 19 Feb 2021 16:29:48 -0500 Subject: [PATCH 147/243] Roll back Spotbugs plugin version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6d0d798..24a9be7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.6.1" + id "com.github.spotbugs" version "4.5.1" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.22.0" From 3a194725489b924ee751d060732f807a92572822 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 22 Feb 2021 08:33:22 -0500 Subject: [PATCH 148/243] Fix vulnerability --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 24a9be7..143fb2c 100644 --- a/build.gradle +++ b/build.gradle @@ -37,6 +37,9 @@ dependencies { api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' + // newer version of dependency to fix vulnerability until converter-jackson is updated + api 'com.fasterxml.jackson.core:jackson-databind:2.10.5.1' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.19.0' } From 1b5f16f574eb03903538877f94a7ef05f2050e0f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 22 Feb 2021 09:29:39 -0500 Subject: [PATCH 149/243] Additional unit testing --- .../client/naaccr/NaaccrFieldName.java | 16 +----- .../client/naaccr/NaaccrFlatField.java | 48 +---------------- .../seerapi/client/naaccr/NaaccrSubField.java | 24 --------- .../seerapi/client/naaccr/NaaccrVersion.java | 33 ------------ .../seerapi/client/naaccr/NaaccrXmlField.java | 54 +------------------ .../seerapi/client/naaccr/NaaccrTest.java | 33 ++++++++++-- 6 files changed, 33 insertions(+), 175 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java index 20f4b51..73ff8f8 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java @@ -14,27 +14,15 @@ public class NaaccrFieldName { @JsonProperty("name") protected String _name; - public String getId() { + public String getNaaccrId() { return _id; } - public void setId(String id) { - _id = id; - } - - public Integer getItem() { + public Integer getItemNum() { return _item; } - public void setItem(Integer item) { - _item = item; - } - public String getName() { return _name; } - - public void setName(String name) { - _name = name; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java index 859344f..2eb9ed6 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java @@ -34,91 +34,47 @@ public class NaaccrFlatField { @JsonProperty("subfield") protected List _subFields; - public String getId() { + public String getNaaccrId() { return _id; } - public void setId(String id) { - _id = id; - } - - public Integer getItem() { + public Integer getItemNum() { return _item; } - public void setItem(Integer item) { - _item = item; - } - public String getName() { return _name; } - public void setName(String name) { - _name = name; - } - public String getSection() { return _section; } - public void setSection(String section) { - _section = section; - } - public Integer getStart() { return _start; } - public void setStart(Integer start) { - _start = start; - } - public Integer getEnd() { return _end; } - public void setEnd(Integer end) { - _end = end; - } - public String getAlign() { return _align; } - public void setAlign(String align) { - _align = align; - } - public String getPadChar() { return _padChar; } - public void setPadChar(String padChar) { - _padChar = padChar; - } - public String getDefaultValue() { return _defaultValue; } - public void setDefaultValue(String defaultValue) { - _defaultValue = defaultValue; - } - public String getDocumentation() { return _documentation; } - public void setDocumentation(String documentation) { - _documentation = documentation; - } - public List getSubFields() { return _subFields; } - - public void setSubFields(List subFields) { - _subFields = subFields; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java index 22ae47b..f91e27a 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java @@ -24,47 +24,23 @@ public Integer getItem() { return _item; } - public void setItem(Integer item) { - _item = item; - } - public String getName() { return _name; } - public void setName(String name) { - _name = name; - } - public Integer getStart() { return _start; } - public void setStart(Integer start) { - _start = start; - } - public Integer getEnd() { return _end; } - public void setEnd(Integer end) { - _end = end; - } - public String getAlign() { return _align; } - public void setAlign(String align) { - _align = align; - } - public String getPadChar() { return _padChar; } - - public void setPadChar(String padChar) { - _padChar = padChar; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java index eabf2f4..ff918b8 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java @@ -25,63 +25,30 @@ public String getVersion() { return _version; } - public void setVersion(String version) { - _version = version; - } - public String getName() { return _name; } - public void setName(String name) { - _name = name; - } - public Integer getLength() { return _length; } - public void setLength(Integer length) { - _length = length; - } - public String getDescription() { return _description; } - public void setDescription(String description) { - _description = description; - } - public String getStyle() { return _style; } - public void setStyle(String style) { - _style = style; - } - public String getDictionaryUri() { return dictionaryUri; } - public void setDictionaryUri(String dictionaryUri) { - this.dictionaryUri = dictionaryUri; - } - public String getDictionaryDescription() { return dictionaryDescription; } - - public void setDictionaryDescription(String dictionaryDescription) { - this.dictionaryDescription = dictionaryDescription; - } - public String getSpecificationVersion() { return specificationVersion; } - - public void setSpecificationVersion(String specificationVersion) { - this.specificationVersion = specificationVersion; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java index 785c2ba..cbd8dd3 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java @@ -46,104 +46,52 @@ public String getNaaccrId() { return _naaccrId; } - public void setNaaccrId(String naaccrId) { - _naaccrId = naaccrId; - } - - public Integer getNaaccrItemNum() { + public Integer getItemNum() { return _naaccrItemNum; } - public void setNaaccrItemNum(Integer naaccrItemNum) { - _naaccrItemNum = naaccrItemNum; - } - public String getName() { return _name; } - public void setName(String name) { - _name = name; - } - public String getSection() { return _section; } - public void setSection(String section) { - _section = section; - } - public Integer getStart() { return _start; } - public void setStart(Integer start) { - _start = start; - } - public List getRecordTypes() { return _recordTypes; } - public void setRecordTypes(List recordTypes) { - _recordTypes = recordTypes; - } - public Integer getLength() { return _length; } - public void setLength(Integer length) { - _length = length; - } - public String getPadType() { return _padType; } - public void setPadType(String padType) { - _padType = padType; - } - public String getDataType() { return _dataType; } - public void setDataType(String dataType) { - _dataType = dataType; - } - public String getTrimType() { return _trimType; } - public void setTrimType(String trimType) { - _trimType = trimType; - } - public Boolean getAllowUnlimitedText() { return _allowUnlimitedText; } - public void setAllowUnlimitedText(Boolean allowUnlimitedText) { - _allowUnlimitedText = allowUnlimitedText; - } - public String getParentXmlElement() { return _parentXmlElement; } - public void setParentXmlElement(String parentXmlElement) { - _parentXmlElement = parentXmlElement; - } - public String getDocumentation() { return _documentation; } - public void setDocumentation(String documentation) { - _documentation = documentation; - } - } diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index ce8987e..bfb9b19 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -5,8 +5,10 @@ import java.io.IOException; import java.util.List; +import java.util.Objects; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; @@ -59,7 +61,7 @@ public void testNaaccrFlatFieldNames() throws IOException { assertThat(names).isNotNull(); for (NaaccrFieldName name : names) { - assertThat(name.getItem()).isGreaterThan(0); + assertThat(name.getItemNum()).isGreaterThan(0); assertThat(name.getName()).isNotEmpty(); } } @@ -70,8 +72,8 @@ public void testNaaccrXmlFieldNames() throws IOException { assertThat(names).isNotNull(); for (NaaccrFieldName name : names) { - assertThat(name.getId()).isNotEmpty(); - assertThat(name.getItem()).isGreaterThan(0); + assertThat(name.getNaaccrId()).isNotEmpty(); + assertThat(name.getItemNum()).isGreaterThan(0); assertThat(name.getName()).isNotEmpty(); } } @@ -81,12 +83,13 @@ public void testNaaccrFlatField() throws IOException { NaaccrFlatField name = _NAACCR.flatField("16", 521).execute().body(); assertThat(name).isNotNull(); + assertThat(name.getItemNum()).isEqualTo(521); + assertThat(name.getNaaccrId()).isEqualTo("morphTypebehavIcdO3"); assertThat(name.getName()).isEqualTo("Morph--Type&Behav ICD-O-3"); assertThat(name.getSection()).isEqualTo("Cancer Identification"); assertThat(name.getAlign()).isEqualTo("LEFT"); assertThat(name.getPadChar()).isEqualTo(" "); assertThat(name.getDocumentation()).startsWith("
"); - assertThat(name.getItem()).isEqualTo(521); assertThat(name.getStart()).isEqualTo(550); assertThat(name.getEnd()).isEqualTo(554); @@ -114,7 +117,7 @@ public void testNaaccrXmlField() throws IOException { assertThat(name).isNotNull(); assertThat(name.getNaaccrId()).isEqualTo("phase2RadiationExternalBeamTech"); - assertThat(name.getNaaccrItemNum()).isEqualTo(1512); + assertThat(name.getItemNum()).isEqualTo(1512); assertThat(name.getName()).isEqualTo("Phase II Radiation External Beam Planning Tech"); assertThat(name.getSection()).isEqualTo("Treatment-1st Course"); assertThat(name.getParentXmlElement()).isEqualTo("Tumor"); @@ -126,4 +129,24 @@ public void testNaaccrXmlField() throws IOException { assertThat(name.getAllowUnlimitedText()).isEqualTo(false); assertThat(name.getDocumentation()).isNotEmpty(); } + + // these two tests are slow so don't run them all the time; they verify that all the items from flat and NAACR can be read without error + + @Ignore + public void loadAllFlat() throws IOException { + for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.flatFieldNames("latest").execute().body())) { + NaaccrFlatField field = _NAACCR.flatField("latest", name.getItemNum()).execute().body(); + + assertThat(field).isNotNull(); + } + } + + @Ignore + public void loadAllXml() throws IOException { + for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.xmlFieldNames("latest").execute().body())) { + NaaccrXmlField field = _NAACCR.xmlField("latest", name.getNaaccrId()).execute().body(); + + assertThat(field).isNotNull(); + } + } } From 817a10de2da70bc7bab3986258b7f0cc85ed9ea3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 22 Feb 2021 09:48:25 -0500 Subject: [PATCH 150/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 79dec29..6bd5824 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.21 + 3.22 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.21' +compile 'com.imsweb:seerapi-client-java:3.22' ``` ## Usage diff --git a/build.gradle b/build.gradle index 143fb2c..ca1bba1 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.22-SNAPSHOT' +version = '3.22' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 2252f93368179bc81f22aac63f1caa6633fdb8c4 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 22 Feb 2021 09:51:00 -0500 Subject: [PATCH 151/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6bd5824..434af45 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.22 + 3.3 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.22' +compile 'com.imsweb:seerapi-client-java:3.3' ``` ## Usage diff --git a/build.gradle b/build.gradle index ca1bba1..c512ffa 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.22' +version = '3.3' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From f098a4dfab301ac90b5a472ee8cc5b64ca4cc9d7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 22 Feb 2021 09:52:32 -0500 Subject: [PATCH 152/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 434af45..6bd5824 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.3 + 3.22 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.3' +compile 'com.imsweb:seerapi-client-java:3.22' ``` ## Usage diff --git a/build.gradle b/build.gradle index c512ffa..ca1bba1 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.3' +version = '3.22' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 04e9b831750dff9167d33fa02f616132afa4e298 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 22 Apr 2021 13:49:18 -0400 Subject: [PATCH 153/243] Fixed MPH and added metadata to staging output --- build.gradle | 14 ++++++------- gradle/wrapper/gradle-wrapper.properties | 2 +- .../imsweb/seerapi/client/mph/MphService.java | 14 +------------ .../client/staging/StagingSchemaOutput.java | 20 ++++++++++++++++++- .../imsweb/seerapi/client/mph/MphTest.java | 13 ------------ .../com/imsweb/seerapi/client/rx/RxTest.java | 4 ++-- .../client/siterecode/SiteRecodeTest.java | 2 +- 7 files changed, 31 insertions(+), 38 deletions(-) diff --git a/build.gradle b/build.gradle index ca1bba1..655f357 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.5.1" + id "com.github.spotbugs" version "4.7.0" id 'maven-publish' id 'signing' - id "io.codearte.nexus-staging" version "0.22.0" - id 'com.adarshr.test-logger' version '2.1.1' - id "com.github.ben-manes.versions" version "0.36.0" - id 'org.sonatype.gradle.plugins.scan' version '2.0.3' + id "io.codearte.nexus-staging" version "0.30.0" + id 'com.adarshr.test-logger' version '3.0.0' + id "com.github.ben-manes.versions" version "0.38.0" + id 'org.sonatype.gradle.plugins.scan' version '2.0.7' } group = 'com.imsweb' @@ -32,7 +32,7 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.2.1' + spotbugs 'com.github.spotbugs:spotbugs:4.2.3' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' @@ -87,7 +87,7 @@ ossIndexAudit { check.dependsOn 'ossIndexAudit' wrapper { - gradleVersion = '6.8.2' + gradleVersion = '7.0' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 25d3265..3c4101c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphService.java b/src/main/java/com/imsweb/seerapi/client/mph/MphService.java index ad31228..e86fa8f 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphService.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphService.java @@ -6,27 +6,15 @@ import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; -import retrofit2.http.Query; - -import com.imsweb.seerapi.client.mph.MphInput.HistologyMatchMode; public interface MphService { - /** - * Uses multiple primary rules to compare two diseases using strict histology matching mode - * @param pair a pair of diseases - * @return a result indicating whether the two diseases are the same primary - */ - @POST("mph") - Call mph(@Body MphInputPair pair); - /** * Uses multiple primary rules to compare two diseases * @param pair a pair of diseases - * @param matchMode match mode * @return a result indicating whether the two diseases are the same primary */ @POST("mph") - Call mph(@Body MphInputPair pair, @Query("histology-matching-mode") HistologyMatchMode matchMode); + Call mph(@Body MphInputPair pair); } \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java index ef2db06..8cf1283 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java @@ -3,10 +3,15 @@ */ package com.imsweb.seerapi.client.staging; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "table"}) +@JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "table", "default", "metadata"}) public class StagingSchemaOutput { private String _key; @@ -16,6 +21,7 @@ public class StagingSchemaOutput { private String _naaccrXmlId; private String _table; private String _default; + private Set _metadata; /** * Morphia requires a default constructor @@ -46,6 +52,8 @@ public StagingSchemaOutput(StagingSchemaOutput other) { setNaaccrXmlId(other.getNaaccrXmlId()); setTable(other.getTable()); setDefault(other.getDefault()); + if (other.getMetadata() != null) + setMetadata(new HashSet<>(other.getMetadata())); } @JsonProperty("key") @@ -111,4 +119,14 @@ public void setDefault(String aDefault) { _default = aDefault; } + @JsonProperty("metadata") + public Set getMetadata() { + return _metadata; + } + + @JsonDeserialize(as = LinkedHashSet.class) + public void setMetadata(Set metadata) { + _metadata = metadata; + } + } diff --git a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java index 8ca656d..82ded4e 100644 --- a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java @@ -7,7 +7,6 @@ import com.imsweb.seerapi.client.BadRequestException; import com.imsweb.seerapi.client.SeerApi; -import com.imsweb.seerapi.client.mph.MphInput.HistologyMatchMode; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -125,18 +124,6 @@ public void testLenientMode() throws IOException { assertEquals(9, result.getAppliedRules().size()); assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); assertEquals("M12", result.getStep()); - - // specify STRICT - result = _MPH.mph(new MphInputPair(input1, input2), HistologyMatchMode.STRICT).execute().body(); - assertEquals(9, result.getAppliedRules().size()); - assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); - assertEquals("M12", result.getStep()); - - // specify LENIENT - result = _MPH.mph(new MphInputPair(input1, input2), HistologyMatchMode.LENIENT).execute().body(); - assertEquals(10, result.getAppliedRules().size()); - assertEquals(MphOutput.Result.SINGLE_PRIMARY, result.getResult()); - assertEquals("M13", result.getStep()); } @Test(expected = BadRequestException.class) diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 6a61660..04b2e78 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -107,8 +107,8 @@ public void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(10, results.getTotal().longValue()); - assertEquals(10, results.getResults().size()); + assertEquals(11, results.getTotal().longValue()); + assertEquals(11, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index 652273c..d2f6bd7 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -45,7 +45,7 @@ public void testExceptionMessages() throws IOException { // the API call works out to: // https://api.seer.cancer.gov/rest/recode/sitegroup?site=C379 - assertEquals("Required String parameter 'hist' is not present", message); + assertEquals("Required request parameter 'hist' for method parameter type String is not present", message); } @Test From 08a199f7e5703c567571c7dd3f6e6353dba17d49 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 22 Apr 2021 14:08:29 -0400 Subject: [PATCH 154/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6bd5824..d93e6a9 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.22 + 3.23 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.22' +compile 'com.imsweb:seerapi-client-java:3.23' ``` ## Usage diff --git a/build.gradle b/build.gradle index 655f357..a5a096e 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.22' +version = '3.23' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 116819bad9de067586e906ec328b0543971aeade Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 4 May 2021 09:22:24 -0400 Subject: [PATCH 155/243] Dependency update; build with Java 11 --- .github/workflows/integration.yml | 7 ++++--- .github/workflows/publish.yml | 7 ++++--- build.gradle | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index be36242..2ecc8c2 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -12,10 +12,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + - name: Set up JDK + uses: actions/setup-java@v2 with: - java-version: 1.8 + distribution: 'adopt' + java-version: '11' - name: Cache Gradle packages uses: actions/cache@v2 with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3ebaa3a..f254ded 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,10 +16,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 + - name: Set up JDK + uses: actions/setup-java@v2 with: - java-version: 1.8 + distribution: 'adopt' + java-version: '11' - name: Publish run: | chmod +x gradlew diff --git a/build.gradle b/build.gradle index a5a096e..c050f07 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.7.0" + id "com.github.spotbugs" version "4.7.1" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '3.0.0' id "com.github.ben-manes.versions" version "0.38.0" - id 'org.sonatype.gradle.plugins.scan' version '2.0.7' + id 'org.sonatype.gradle.plugins.scan' version '2.0.9' } group = 'com.imsweb' From 74d2111a33a1118f53c657025ab5c183116d35b7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 13 May 2021 08:49:41 -0400 Subject: [PATCH 156/243] Fixed unit test --- .../com/imsweb/seerapi/client/SeerApi.java | 35 +++++++------------ .../com/imsweb/seerapi/client/rx/RxTest.java | 4 +-- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/SeerApi.java b/src/main/java/com/imsweb/seerapi/client/SeerApi.java index ab8869d..3d33294 100644 --- a/src/main/java/com/imsweb/seerapi/client/SeerApi.java +++ b/src/main/java/com/imsweb/seerapi/client/SeerApi.java @@ -37,16 +37,16 @@ */ public final class SeerApi { - private DiseaseService _diseaseService; - private GlossaryService _glossaryService; - private MphService _mphService; - private NaaccrService _naaccrService; - private NdcService _ndcService; - private RxService _rxService; - private SiteRecodeService _siteRecodeService; - private StagingService _stagingService; - private SurgeryService _surgeryService; - private HcpcsService _hcpcsService; + private final DiseaseService _diseaseService; + private final GlossaryService _glossaryService; + private final MphService _mphService; + private final NaaccrService _naaccrService; + private final NdcService _ndcService; + private final RxService _rxService; + private final SiteRecodeService _siteRecodeService; + private final StagingService _stagingService; + private final SurgeryService _surgeryService; + private final HcpcsService _hcpcsService; /** * Creates a client API root object @@ -210,31 +210,20 @@ public static class Builder { /** * Return a list of user properties from the local .seerapi file - * @return + * @return Properties object */ private Properties getProperties() { Properties props = new Properties(); File config = new File(System.getProperty("user.home"), ".seerapi"); if (config.exists()) { - FileInputStream in = null; - try { - in = new FileInputStream(config); + try (FileInputStream in = new FileInputStream(config)) { props.load(in); } catch (IOException e) { // error reading } - finally { - try { - if (in != null) - in.close(); - } - catch (IOException e) { - // do nothing if error closing stream - } - } } return props; diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 04b2e78..f81f98a 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -107,8 +107,8 @@ public void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(11, results.getTotal().longValue()); - assertEquals(11, results.getResults().size()); + assertEquals(12, results.getTotal().longValue()); + assertEquals(12, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); From 215661db219243f0f32895ec74c31c04c551a499 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 1 Jun 2021 09:06:27 -0400 Subject: [PATCH 157/243] Changes to support new metadata type --- .../client/staging/StagingMetadata.java | 79 +++++++++++++++++++ .../staging/StagingMetadataDeserializer.java | 43 ++++++++++ .../seerapi/client/staging/StagingSchema.java | 7 -- .../client/staging/StagingSchemaInput.java | 15 ++-- .../client/staging/StagingSchemaOutput.java | 15 ++-- .../seerapi/client/staging/StagingTest.java | 11 +++ 6 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java create mode 100644 src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java new file mode 100644 index 0000000..f1538c1 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadata.java @@ -0,0 +1,79 @@ +package com.imsweb.seerapi.client.staging; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +@JsonPropertyOrder({"name", "start", "end"}) +@JsonDeserialize(using = StagingMetadataDeserializer.class) +public class StagingMetadata { + + private String _name; + private Integer _start; + private Integer _end; + + public StagingMetadata() { + } + + public StagingMetadata(String name) { + _name = name; + } + + public StagingMetadata(String name, Integer start) { + _name = name; + _start = start; + } + + public StagingMetadata(String name, Integer start, Integer end) { + _name = name; + _start = start; + _end = end; + } + + @JsonProperty("name") + public String getName() { + return _name; + } + + public void setName(String name) { + _name = name; + } + + @JsonProperty("start") + public Integer getStart() { + return _start; + } + + public void setStart(Integer start) { + _start = start; + } + + @JsonProperty("end") + public Integer getEnd() { + return _end; + } + + public void setEnd(Integer end) { + _end = end; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + StagingMetadata that = (StagingMetadata)o; + return Objects.equals(_name, that._name) && + Objects.equals(_start, that._start) && + Objects.equals(_end, that._end); + } + + @Override + public int hashCode() { + return Objects.hash(_name, _start, _end); + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java new file mode 100644 index 0000000..a218462 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java @@ -0,0 +1,43 @@ +package com.imsweb.seerapi.client.staging; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; + +public class StagingMetadataDeserializer extends StdDeserializer { + + public StagingMetadataDeserializer() { + this(null); + } + + protected StagingMetadataDeserializer(Class vc) { + super(vc); + } + + @Override + public StagingMetadata deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + JsonNode node = jp.getCodec().readTree(jp); + + if (node.isNull()) + return null; + + if (node.isObject()) { + StagingMetadata meta = new StagingMetadata(); + + if (node.get("name") != null) + meta.setName(node.get("name").asText()); + if (node.get("start") != null) + meta.setStart(node.get("start").asInt()); + if (node.get("end") != null) + meta.setEnd(node.get("end").asInt()); + + return meta; + } + + return new StagingMetadata(node.asText()); + } +} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java index 30f06d2..66e3611 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java @@ -6,10 +6,8 @@ import java.util.Date; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Set; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -200,11 +198,6 @@ public void setMappings(List mapping) { _mappings = mapping; } - @JsonIgnore - public Map getInputMap() { - return null; - } - @JsonProperty("involved_tables") public Set getInvolvedTables() { return _involvedTables; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java index 3301bb8..3005e57 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java @@ -3,13 +3,11 @@ */ package com.imsweb.seerapi.client.staging; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "values", "default", "table", "used_for_staging", "fail_on_invalid", "unit", "decimal_places", "metadata"}) public class StagingSchemaInput { @@ -24,7 +22,7 @@ public class StagingSchemaInput { private Boolean _usedForStaging; private String _unit; private Integer _decimalPlaces; - private Set _metadata; + private List _metadata; /** * Morphia requires a default constructor @@ -56,7 +54,7 @@ public StagingSchemaInput(StagingSchemaInput other) { setDefault(other.getDefault()); setTable(other.getTable()); if (other.getMetadata() != null) - setMetadata(new HashSet<>(other.getMetadata())); + setMetadata(new ArrayList<>(other.getMetadata())); setUsedForStaging(other.getUsedForStaging()); setUnit(other.getUnit()); setDecimalPlaces(other.getDecimalPlaces()); @@ -153,12 +151,11 @@ public void setUnit(String unit) { } @JsonProperty("metadata") - public Set getMetadata() { + public List getMetadata() { return _metadata; } - @JsonDeserialize(as = LinkedHashSet.class) - public void setMetadata(Set metadata) { + public void setMetadata(List metadata) { _metadata = metadata; } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java index 8cf1283..cc81ae0 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java @@ -3,13 +3,11 @@ */ package com.imsweb.seerapi.client.staging; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.ArrayList; +import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonPropertyOrder({"key", "name", "description", "naaccr_item", "naaccr_xml_id", "table", "default", "metadata"}) public class StagingSchemaOutput { @@ -21,7 +19,7 @@ public class StagingSchemaOutput { private String _naaccrXmlId; private String _table; private String _default; - private Set _metadata; + private List _metadata; /** * Morphia requires a default constructor @@ -53,7 +51,7 @@ public StagingSchemaOutput(StagingSchemaOutput other) { setTable(other.getTable()); setDefault(other.getDefault()); if (other.getMetadata() != null) - setMetadata(new HashSet<>(other.getMetadata())); + setMetadata(new ArrayList<>(other.getMetadata())); } @JsonProperty("key") @@ -120,12 +118,11 @@ public void setDefault(String aDefault) { } @JsonProperty("metadata") - public Set getMetadata() { + public List getMetadata() { return _metadata; } - @JsonDeserialize(as = LinkedHashSet.class) - public void setMetadata(Set metadata) { + public void setMetadata(List metadata) { _metadata = metadata; } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 8c5e0dc..e81cbc4 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -252,4 +252,15 @@ public void testStagingGlossary() throws IOException { assertThat(matches).isEmpty(); } + @Test + public void testStagingMetadata() throws IOException { + StagingSchema schema = _STAGING.schemaById("eod_public", "2.0", "brain").execute().body(); + assertThat(schema).isNotNull(); + + StagingSchemaInput mgmt = schema.getInputs().stream().filter(i -> i.getKey().equals("mgmt")).findFirst().orElse(null); + assertThat(mgmt).isNotNull(); + + assertThat(mgmt.getMetadata()).extracting("name").containsExactlyInAnyOrder("COC_REQUIRED", "SEER_REQUIRED", "SSDI"); + } + } From e3c492af6e4b55bab941ef94e737962f5999ce1e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 1 Jun 2021 10:08:13 -0400 Subject: [PATCH 158/243] Prepare for release --- README.md | 4 ++-- build.gradle | 8 ++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d93e6a9..f796831 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.23 + 3.24 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.23' +compile 'com.imsweb:seerapi-client-java:3.24' ``` ## Usage diff --git a/build.gradle b/build.gradle index c050f07..9059dcd 100644 --- a/build.gradle +++ b/build.gradle @@ -6,12 +6,12 @@ plugins { id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '3.0.0' - id "com.github.ben-manes.versions" version "0.38.0" - id 'org.sonatype.gradle.plugins.scan' version '2.0.9' + id "com.github.ben-manes.versions" version "0.39.0" + id 'org.sonatype.gradle.plugins.scan' version '2.0.10' } group = 'com.imsweb' -version = '3.23' +version = '3.24' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { @@ -87,7 +87,7 @@ ossIndexAudit { check.dependsOn 'ossIndexAudit' wrapper { - gradleVersion = '7.0' + gradleVersion = '7.0.2' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c4101c..29e4134 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From a44c52f757fa172c5cada014d17278eb0d79a72d Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 12 Aug 2021 09:54:42 -0400 Subject: [PATCH 159/243] Added diagnostic confirmation to disease entity --- .../com/imsweb/seerapi/client/disease/Disease.java | 10 ++++++++++ .../imsweb/seerapi/client/disease/DiseaseTest.java | 11 +---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java index 3ebfeca..e478827 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/Disease.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/Disease.java @@ -105,6 +105,8 @@ public class Disease extends Publishable { private List _samePrimariesText; @JsonProperty("progression") private List _progression; + @JsonProperty("diagnostic_confirmation") + private List _diagnosticConfirmation; /** * Solid tumor specific @@ -444,6 +446,14 @@ public void setProgression(List progression) { _progression = progression; } + public List getDiagnosticConfirmation() { + return _diagnosticConfirmation; + } + + public void setDiagnosticConfirmation(List diagnosticConfirmation) { + _diagnosticConfirmation = diagnosticConfirmation; + } + // values for the datasources public enum Type { SOLID_TUMOR, diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 71daa61..f4416d8 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -96,16 +96,6 @@ public void testDiseaseById() throws IOException { assertNull(disease.getFieldNotes()); assertNull(disease.getScore()); assertNull(disease.getGlossaryMatches()); - //assertNull(disease.getHistory()); - - // assertTrue(disease.getHistory().size() > 0); - // - // DiseaseHistoryEvent event = disease.getHistory().get(0); - // assertEquals("mayc@imsweb.com", event.getUser()); - // assertNotNull(event.getDate()); - // assertNull(event.getOld()); - // assertNull(event.getNew()); - assertEquals(1, disease.getPrimarySite().size()); assertEquals("C421", disease.getPrimarySite().get(0).getLow()); assertEquals("C421", disease.getPrimarySite().get(0).getHigh()); @@ -142,6 +132,7 @@ public void testDiseaseById() throws IOException { assertEquals("See abstractor notes", disease.getModuleId().get(0).getValue()); assertNull(disease.getBiomarkers()); assertNull(disease.getTreatmentText()); + assertTrue(disease.getDiagnosticConfirmation().get(0).getValue().startsWith("This histology can be determined by positive histology")); } @Test From 08f7be14b0f2dd980e63e2fe761354a1708cb8e5 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 12 Aug 2021 10:08:35 -0400 Subject: [PATCH 160/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f796831..e7fcf17 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.24 + 3.25 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.24' +compile 'com.imsweb:seerapi-client-java:3.25' ``` ## Usage diff --git a/build.gradle b/build.gradle index 9059dcd..c171145 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.24' +version = '3.25' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 283aaf8de247f4ac0c098ee57179a8a0a98fd58f Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 19 Aug 2021 14:56:03 -0400 Subject: [PATCH 161/243] Add support for new naaccr_version field --- build.gradle | 10 +- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 257 +++++++++++------- .../client/staging/StagingAlgorithm.java | 3 - .../staging/StagingColumnDefinition.java | 3 - .../seerapi/client/staging/StagingSchema.java | 3 - .../client/staging/StagingSchemaInput.java | 3 - .../client/staging/StagingSchemaOutput.java | 3 - .../seerapi/client/staging/StagingTable.java | 3 - .../client/staging/StagingTablePath.java | 3 - .../client/staging/StagingVersion.java | 15 +- 12 files changed, 170 insertions(+), 135 deletions(-) diff --git a/build.gradle b/build.gradle index c171145..29eeb32 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.7.1" + id "com.github.spotbugs" version "4.7.3" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '3.0.0' id "com.github.ben-manes.versions" version "0.39.0" - id 'org.sonatype.gradle.plugins.scan' version '2.0.10' + id 'org.sonatype.gradle.plugins.scan' version '2.1.0' } group = 'com.imsweb' @@ -32,7 +32,7 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.2.3' + spotbugs 'com.github.spotbugs:spotbugs:4.4.0' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' @@ -41,7 +41,7 @@ dependencies { api 'com.fasterxml.jackson.core:jackson-databind:2.10.5.1' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.assertj:assertj-core:3.19.0' + testImplementation 'org.assertj:assertj-core:3.20.2' } jar { @@ -87,7 +87,7 @@ ossIndexAudit { check.dependsOn 'ossIndexAudit' wrapper { - gradleVersion = '7.0.2' + gradleVersion = '7.2' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..7454180f2ae8848c63b8b4dea2cb829da983f2fa 100644 GIT binary patch delta 18435 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 B8dv}T delta 17845 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 X49Luk)baa85H9$5YCsTPT`SVRWMtMW diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 29e4134..a0f7639 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0..c53aefa 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright � 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions �$var�, �${var}�, �${var:-default}�, �${var+SET}�, +# �${var#prefix}�, �${var%suffix}�, and �$( cmd )�; +# * compound commands having a testable exit status, especially �case�; +# * various built-in commands including �command�, �set�, and �ulimit�. +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java index b3aac97..5c29d30 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingAlgorithm.java @@ -13,9 +13,6 @@ public class StagingAlgorithm { private String _name; private String _description; - /** - * Morphia requires a default constructor - */ public StagingAlgorithm() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java index 2fa404a..3ec6165 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingColumnDefinition.java @@ -20,9 +20,6 @@ enum ColumnType { ENDPOINT } - /** - * Morphia requires a default constructor - */ public StagingColumnDefinition() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java index 66e3611..7d5a105 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java @@ -46,9 +46,6 @@ public enum StagingInputErrorHandler { private Set _involvedTables; private StagingInputErrorHandler _onInvalidInput; - /** - * Morphia requires a default constructor - */ public StagingSchema() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java index 3005e57..2e361ca 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaInput.java @@ -24,9 +24,6 @@ public class StagingSchemaInput { private Integer _decimalPlaces; private List _metadata; - /** - * Morphia requires a default constructor - */ public StagingSchemaInput() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java index cc81ae0..245ebc0 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchemaOutput.java @@ -21,9 +21,6 @@ public class StagingSchemaOutput { private String _default; private List _metadata; - /** - * Morphia requires a default constructor - */ public StagingSchemaOutput() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java index ee48b8f..30f281b 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java @@ -27,9 +27,6 @@ public class StagingTable { private Set _extraInput; private List> _rows; - /** - * Morphia requires a default constructor - */ public StagingTable() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java index 8b14c3f..0983fa5 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTablePath.java @@ -19,9 +19,6 @@ public class StagingTablePath { private Set _inputs; private Set _outputs; - /** - * Morphia requires a default constructor - */ public StagingTablePath() { } diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java index c997fd7..99b601c 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingVersion.java @@ -9,17 +9,15 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"algorithm", "version", "type", "last_modified"}) +@JsonPropertyOrder({"algorithm", "version", "naaccr_version", "type", "last_modified"}) public class StagingVersion { private String _algorithm; private String _version; + private String _naaccrVersion; private Type _type; private Date _lastModified; - /** - * Default constructor is required by Morphia - */ public StagingVersion() { } @@ -46,6 +44,15 @@ public void setVersion(String version) { _version = version; } + @JsonProperty("naaccr_version") + public String getNaaccrVersion() { + return _naaccrVersion; + } + + public void setNaaccrVersion(String naaccrVersion) { + _naaccrVersion = naaccrVersion; + } + @JsonProperty("type") public Type getType() { return _type; From aff5a09028dacbca4715e0ae15bf4006160d7de8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 19 Aug 2021 15:04:06 -0400 Subject: [PATCH 162/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e7fcf17..3127f60 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 3.25 + 5.0 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:3.25' +compile 'com.imsweb:seerapi-client-java:5.0' ``` ## Usage diff --git a/build.gradle b/build.gradle index 29eeb32..4fb11d8 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ plugins { } group = 'com.imsweb' -version = '3.25' +version = '5.0' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 0b952e6736c13b8419d2fc05c8b32723a7074fef Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 23 Nov 2021 14:08:59 -0500 Subject: [PATCH 163/243] Dep updates --- .github/workflows/integration.yml | 2 +- .github/workflows/publish.yml | 2 +- build.gradle | 10 +++++----- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 10 +++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 2ecc8c2..15cb930 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -16,7 +16,7 @@ jobs: uses: actions/setup-java@v2 with: distribution: 'adopt' - java-version: '11' + java-version: '17' - name: Cache Gradle packages uses: actions/cache@v2 with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f254ded..5295861 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,7 +20,7 @@ jobs: uses: actions/setup-java@v2 with: distribution: 'adopt' - java-version: '11' + java-version: '17' - name: Publish run: | chmod +x gradlew diff --git a/build.gradle b/build.gradle index 4fb11d8..d5282c8 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,9 @@ plugins { id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" - id 'com.adarshr.test-logger' version '3.0.0' + id 'com.adarshr.test-logger' version '3.1.0' id "com.github.ben-manes.versions" version "0.39.0" - id 'org.sonatype.gradle.plugins.scan' version '2.1.0' + id 'org.sonatype.gradle.plugins.scan' version '2.2.1' } group = 'com.imsweb' @@ -38,10 +38,10 @@ dependencies { api 'com.squareup.retrofit2:converter-jackson:2.9.0' // newer version of dependency to fix vulnerability until converter-jackson is updated - api 'com.fasterxml.jackson.core:jackson-databind:2.10.5.1' + api 'com.fasterxml.jackson.core:jackson-databind:2.13.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.assertj:assertj-core:3.20.2' + testImplementation 'org.assertj:assertj-core:3.21.0' } jar { @@ -87,7 +87,7 @@ ossIndexAudit { check.dependsOn 'ossIndexAudit' wrapper { - gradleVersion = '7.2' + gradleVersion = '7.3' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a0f7639..fbce071 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index c53aefa..1b6c787 100644 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright � 2015-2021 the original authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,10 +32,10 @@ # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; -# * expansions �$var�, �${var}�, �${var:-default}�, �${var+SET}�, -# �${var#prefix}�, �${var%suffix}�, and �$( cmd )�; -# * compound commands having a testable exit status, especially �case�; -# * various built-in commands including �command�, �set�, and �ulimit�. +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # From 4adcec9ea085f1d5151a0a8c73b970308b2d45a1 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 23 Nov 2021 14:25:08 -0500 Subject: [PATCH 164/243] Stop Javadoc warnings --- build.gradle | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d5282c8..aa83757 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { options.encoding = 'UTF-8' - options.compilerArgs << "-Xlint:all" << "-Xlint:-serial" << "-Werror" + options.compilerArgs << "-Werror" } java { @@ -61,6 +61,13 @@ jar { } } +tasks.withType(Javadoc) { + failOnError false + options.addStringOption('Xdoclint:none', '-quiet') + options.addStringOption('encoding', 'UTF-8') + options.addStringOption('charSet', 'UTF-8') +} + checkstyle { toolVersion '8.29' configFile = file("config/checkstyle/checkstyle.xml") From 3722a24684a7e048c61312dcb36a15b0753854ed Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 25 May 2022 08:29:17 -0400 Subject: [PATCH 165/243] Dep updates --- build.gradle | 16 ++++++++-------- gradle/wrapper/gradle-wrapper.jar | Bin 59536 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index aa83757..67a579e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,13 +1,13 @@ plugins { id 'java-library' id 'checkstyle' - id "com.github.spotbugs" version "4.7.3" + id "com.github.spotbugs" version "5.0.7" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" - id 'com.adarshr.test-logger' version '3.1.0' - id "com.github.ben-manes.versions" version "0.39.0" - id 'org.sonatype.gradle.plugins.scan' version '2.2.1' + id 'com.adarshr.test-logger' version '3.2.0' + id "com.github.ben-manes.versions" version "0.42.0" + id 'org.sonatype.gradle.plugins.scan' version '2.3.0' } group = 'com.imsweb' @@ -32,16 +32,16 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.4.0' + spotbugs 'com.github.spotbugs:spotbugs:4.7.0' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' // newer version of dependency to fix vulnerability until converter-jackson is updated - api 'com.fasterxml.jackson.core:jackson-databind:2.13.0' + api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.assertj:assertj-core:3.21.0' + testImplementation 'org.assertj:assertj-core:3.22.0' } jar { @@ -94,7 +94,7 @@ ossIndexAudit { check.dependsOn 'ossIndexAudit' wrapper { - gradleVersion = '7.3' + gradleVersion = '7.4.2' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2ae8848c63b8b4dea2cb829da983f2fa..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 8958 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fbce071..92f06b5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From ecb38611ce0d7302af89eda85ccf86df76f282d4 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 25 May 2022 09:09:07 -0400 Subject: [PATCH 166/243] Don't run ossIndexAudit on every build --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 67a579e..22036fe 100644 --- a/build.gradle +++ b/build.gradle @@ -91,7 +91,6 @@ ossIndexAudit { } } } -check.dependsOn 'ossIndexAudit' wrapper { gradleVersion = '7.4.2' From f6de1abf29d32037e6ed60a71ad6d47239178066 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 2 Jun 2022 13:28:21 -0400 Subject: [PATCH 167/243] Update dependency --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 22036fe..8684840 100644 --- a/build.gradle +++ b/build.gradle @@ -41,7 +41,7 @@ dependencies { api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.assertj:assertj-core:3.22.0' + testImplementation 'org.assertj:assertj-core:3.23.1' } jar { From b046e9a57e84c6921c72c1fb04300f37ca8ce21c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 08:17:49 -0400 Subject: [PATCH 168/243] Add sonarqube plugin to build --- .github/workflows/integration.yml | 12 +++++++----- README.md | 1 + build.gradle | 18 +++++++++--------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 15cb930..1289f06 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -2,7 +2,7 @@ name: integration -on: [push, pull_request] +on: [ push, pull_request ] jobs: build: @@ -25,9 +25,11 @@ jobs: ~/.gradle/wrapper key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} restore-keys: ${{ runner.os }}-gradle - - name: Build and test - run: | - chmod +x gradlew - ./gradlew build --no-daemon + - name: Build and analyze env: SEER_API_KEY: ${{ secrets.SEER_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + chmod +x gradlew + ./gradlew build sonarqube diff --git a/README.md b/README.md index 3127f60..504ca02 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # seerapi-client-java +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=imsweb_seerapi-client-java&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=imsweb_seerapi-client-java) [![integration](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg)](https://github.com/imsweb/seerapi-client-java/actions) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) diff --git a/build.gradle b/build.gradle index 8684840..c39ea6e 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,7 @@ plugins { id 'com.adarshr.test-logger' version '3.2.0' id "com.github.ben-manes.versions" version "0.42.0" id 'org.sonatype.gradle.plugins.scan' version '2.3.0' + id "org.sonarqube" version "3.3" } group = 'com.imsweb' @@ -77,19 +78,18 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } +sonarqube { + properties { + property "sonar.projectKey", "imsweb_seerapi-client-java" + property "sonar.organization", "imsweb" + property "sonar.host.url", "https://sonarcloud.io" + } +} + // Nexus vulnerability scan (see https://github.com/sonatype-nexus-community/scan-gradle-plugin) ossIndexAudit { dependencyGraph = true printBanner = false - - // only set proxy if running outside of Github Actions - if (!System.getenv().GITHUB_ACTIONS) { - proxyConfiguration { - protocol = 'http' - host = 'webproxy-btp.imsweb.com' - port = 8080 - } - } } wrapper { From 2689744dcf570eee7f7cf72382d0909e928c587b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 08:35:58 -0400 Subject: [PATCH 169/243] Add code coverage --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index c39ea6e..4dd3de5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java-library' id 'checkstyle' + id 'jacoco' id "com.github.spotbugs" version "5.0.7" id 'maven-publish' id 'signing' From c83bd5e2f6fa45838a8cfd4ac7620b62c7d86a68 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 08:48:51 -0400 Subject: [PATCH 170/243] Forgot to add jacoco report --- build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/build.gradle b/build.gradle index 4dd3de5..2b7b23a 100644 --- a/build.gradle +++ b/build.gradle @@ -79,6 +79,13 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } +jacocoTestReport { + reports { + xml.enabled true + } +} +test.finalizedBy jacocoTestReport + sonarqube { properties { property "sonar.projectKey", "imsweb_seerapi-client-java" From d99181d860964b7bea1291bb1e5fbbad93ddc0b0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 09:00:00 -0400 Subject: [PATCH 171/243] Code cleanup --- .../com/imsweb/seerapi/client/disease/DateRange.java | 6 ------ .../imsweb/seerapi/client/disease/DateRangeString.java | 6 ------ .../client/disease/DiseaseChangelogResults.java | 6 ------ .../client/glossary/GlossaryChangelogResults.java | 6 ------ .../java/com/imsweb/seerapi/client/mph/MphOutput.java | 2 -- .../imsweb/seerapi/client/staging/SchemaLookup.java | 2 +- .../com/imsweb/seerapi/client/staging/StagingData.java | 2 +- .../seerapi/client/staging/cs/CsSchemaLookup.java | 3 ++- .../seerapi/client/staging/eod/EodSchemaLookup.java | 5 +++-- .../imsweb/seerapi/client/glossary/GlossaryTest.java | 4 ++-- .../imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java | 6 +++--- .../com/imsweb/seerapi/client/naaccr/NaaccrTest.java | 10 +++++----- .../com/imsweb/seerapi/client/surgery/SurgeryTest.java | 3 +-- 13 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java b/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java index 1f0b25c..8e3e408 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DateRange.java @@ -9,12 +9,6 @@ public class DateRange { @JsonProperty("end") protected String _endDate; - /** - * Default constructor - */ - public DateRange() { - } - public String getStartDate() { return _startDate; } diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java b/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java index 7873f65..0a2c52b 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DateRangeString.java @@ -7,12 +7,6 @@ public class DateRangeString extends DateRange { @JsonProperty("value") protected String _value; - /** - * Default constructor - */ - public DateRangeString() { - } - public String getValue() { return _value; } diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java index bada339..1a24bd5 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelogResults.java @@ -13,12 +13,6 @@ public class DiseaseChangelogResults extends PublishableChangelogResults { protected List _changelogs; - /** - * Default constructor - */ - public DiseaseChangelogResults() { - } - @JsonProperty("changelogs") public List getChangelogs() { return _changelogs; diff --git a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java index 81886fa..ae8da9d 100644 --- a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelogResults.java @@ -13,12 +13,6 @@ public class GlossaryChangelogResults extends PublishableChangelogResults { protected List _changelogs; - /** - * Default constructor - */ - public GlossaryChangelogResults() { - } - @JsonProperty("changelogs") public List getChangelogs() { return _changelogs; diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java index fdcf615..079bf57 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java @@ -16,8 +16,6 @@ public class MphOutput { private String _groupId; @JsonProperty("step") private String _step; - public MphOutput() { - } public Result getResult() { return _result; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java index 7c21833..4001202 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java @@ -122,7 +122,7 @@ public boolean hasDiscriminator() { for (Entry entry : _inputs.entrySet()) { String key = entry.getKey(); - if (StagingData.STANDARD_LOOKUP_KEYS.contains(key)) + if (StagingData._STANDARD_LOOKUP_KEYS.contains(key)) continue; String value = entry.getValue(); diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java index 59ecc60..643562e 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingData.java @@ -24,7 +24,7 @@ public class StagingData { public static final String YEAR_DX_KEY = "year_dx"; // set of keys that are standard for all schema lookups; any other keys are considered a discriminator - public static final Set STANDARD_LOOKUP_KEYS = new HashSet<>(Arrays.asList(PRIMARY_SITE_KEY, HISTOLOGY_KEY)); + protected static final Set _STANDARD_LOOKUP_KEYS = new HashSet<>(Arrays.asList(PRIMARY_SITE_KEY, HISTOLOGY_KEY)); private Result _result; private String _schemaId; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java index aaf1ba3..eeb3752 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsSchemaLookup.java @@ -8,10 +8,11 @@ import java.util.Set; import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.StagingData; public class CsSchemaLookup extends SchemaLookup { - private static final Set _ALLOWED_KEYS = new HashSet<>(Arrays.asList(CsStagingData.PRIMARY_SITE_KEY, CsStagingData.HISTOLOGY_KEY, CsStagingData.SSF25_KEY)); + private static final Set _ALLOWED_KEYS = new HashSet<>(Arrays.asList(StagingData.PRIMARY_SITE_KEY, StagingData.HISTOLOGY_KEY, CsStagingData.SSF25_KEY)); /** * Default constructor diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java index 91e4f1d..d7806dd 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodSchemaLookup.java @@ -9,13 +9,14 @@ import java.util.Set; import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.StagingData; import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodInput; public class EodSchemaLookup extends SchemaLookup { private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( - EodStagingData.PRIMARY_SITE_KEY, - EodStagingData.HISTOLOGY_KEY, + StagingData.PRIMARY_SITE_KEY, + StagingData.HISTOLOGY_KEY, EodInput.SEX.toString(), EodInput.DISCRIMINATOR_1.toString(), EodInput.DISCRIMINATOR_2.toString()))); diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index e7043e6..eed2e39 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -159,11 +159,11 @@ public void testGlossaryMatch() throws IOException { Set matches = _GLOSSARY.match(text, null, true).execute().body(); Assert.assertNotNull(matches); - Assert.assertEquals(matches.size(), 1); + Assert.assertEquals(1, matches.size()); matches = _GLOSSARY.match(text, EnumSet.of(GENERAL), true).execute().body(); Assert.assertNotNull(matches); - Assert.assertEquals(matches.size(), 0); + Assert.assertEquals(0, matches.size()); } } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java index c683776..6466eb8 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -43,7 +43,7 @@ public void testGetProcedureByCode() throws IOException { assertThat(proc.getCategories()).containsExactly(Category.IMMUNOTHERAPY); assertThat(proc.getMajorDrugClass()).isEqualTo("Monoclonal Antibody"); assertThat(proc.getMinorDrugClass()).isEqualTo("CD52"); - assertThat(proc.getOral()).isEqualTo(false); + assertThat(proc.getOral()).isFalse(); assertThat(proc.getDateAdded()).isNotNull(); assertThat(proc.getDateModified()).isNotNull(); @@ -69,7 +69,7 @@ public void testSearch() throws IOException { // test page out of range params.put("page", "1000"); - assertThat(_HCPCS.search(params).execute().body()).hasSize(0); + assertThat(_HCPCS.search(params).execute().body()).isEmpty(); // test searching params.clear(); @@ -88,6 +88,6 @@ public void testSearch() throws IOException { assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); params.put("category", Category.IMMUNOTHERAPY.toString()); - assertThat(_HCPCS.search(params).execute().body()).hasSize(0); + assertThat(_HCPCS.search(params).execute().body()).isEmpty(); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index bfb9b19..413e718 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -61,7 +61,7 @@ public void testNaaccrFlatFieldNames() throws IOException { assertThat(names).isNotNull(); for (NaaccrFieldName name : names) { - assertThat(name.getItemNum()).isGreaterThan(0); + assertThat(name.getItemNum()).isPositive(); assertThat(name.getName()).isNotEmpty(); } } @@ -73,7 +73,7 @@ public void testNaaccrXmlFieldNames() throws IOException { assertThat(names).isNotNull(); for (NaaccrFieldName name : names) { assertThat(name.getNaaccrId()).isNotEmpty(); - assertThat(name.getItemNum()).isGreaterThan(0); + assertThat(name.getItemNum()).isPositive(); assertThat(name.getName()).isNotEmpty(); } } @@ -126,13 +126,13 @@ public void testNaaccrXmlField() throws IOException { assertThat(name.getLength()).isEqualTo(2); assertThat(name.getPadType()).isEqualTo("rightBlank"); assertThat(name.getTrimType()).isEqualTo("all"); - assertThat(name.getAllowUnlimitedText()).isEqualTo(false); + assertThat(name.getAllowUnlimitedText()).isFalse(); assertThat(name.getDocumentation()).isNotEmpty(); } // these two tests are slow so don't run them all the time; they verify that all the items from flat and NAACR can be read without error - @Ignore + @Ignore("Slow test so do not run all the time") public void loadAllFlat() throws IOException { for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.flatFieldNames("latest").execute().body())) { NaaccrFlatField field = _NAACCR.flatField("latest", name.getItemNum()).execute().body(); @@ -141,7 +141,7 @@ public void loadAllFlat() throws IOException { } } - @Ignore + @Ignore("Slow test so do not run all the time") public void loadAllXml() throws IOException { for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.xmlFieldNames("latest").execute().body())) { NaaccrXmlField field = _NAACCR.xmlField("latest", name.getNaaccrId()).execute().body(); diff --git a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java index f8d5566..61b8f95 100644 --- a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java @@ -26,8 +26,7 @@ public static void setup() { public void testSiteSpecificSurgeryTables() throws IOException { List titles = _SURGERY.tables("2014").execute().body(); - assertThat(titles).isNotEmpty(); - assertThat(titles).containsAnyOf("Oral Cavity"); + assertThat(titles).isNotEmpty().containsAnyOf("Oral Cavity"); } @Test From e4d822574653de636b17450a756b166da2d201b7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 09:07:51 -0400 Subject: [PATCH 172/243] More code cleanup --- .../java/com/imsweb/seerapi/client/mph/MphRule.java | 3 --- .../imsweb/seerapi/client/naaccr/NaaccrXmlField.java | 3 --- .../java/com/imsweb/seerapi/client/ndc/NdcSearch.java | 2 +- .../publishable/PublishableChangelogResults.java | 6 ------ src/main/java/com/imsweb/seerapi/client/rx/Rx.java | 6 ------ .../imsweb/seerapi/client/rx/RxChangelogResults.java | 6 ------ .../imsweb/seerapi/client/staging/SchemaLookup.java | 4 +++- .../client/staging/StagingMetadataDeserializer.java | 3 +-- .../imsweb/seerapi/client/staging/StagingSchema.java | 3 --- .../imsweb/seerapi/client/staging/StagingTable.java | 3 --- .../seerapi/client/staging/cs/CsStagingData.java | 3 +-- .../seerapi/client/staging/tnm/TnmSchemaLookup.java | 5 +++-- .../seerapi/client/staging/tnm/TnmStagingData.java | 3 +-- .../com/imsweb/seerapi/client/disease/DiseaseTest.java | 1 + .../java/com/imsweb/seerapi/client/ndc/NdcTest.java | 10 +++++----- 15 files changed, 16 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java b/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java index e3dab15..329cb26 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphRule.java @@ -22,9 +22,6 @@ public class MphRule { @JsonProperty("examples") private List _examples; - public MphRule() { - } - public String getGroupId() { return _groupId; } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java index cbd8dd3..f9ba8c7 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java @@ -39,9 +39,6 @@ public class NaaccrXmlField { @JsonProperty("documentation") protected String _documentation; - public NaaccrXmlField() { - } - public String getNaaccrId() { return _naaccrId; } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java index c0306e9..edba4f2 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java @@ -115,7 +115,7 @@ public Map paramMap() { if (getHasSeerInfo() != null) params.put("has_seer_info", getHasSeerInfo().toString()); if (getIncludeRemoved() != null) - params.put("include_removed", getIncludeRemoved() ? "true" : "false"); + params.put("include_removed", Boolean.TRUE.equals(getIncludeRemoved()) ? "true" : "false"); if (getAddedSince() != null) params.put("added_since", getAddedSince()); if (getModifiedSince() != null) diff --git a/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java index e917d0e..3518a44 100644 --- a/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/publishable/PublishableChangelogResults.java @@ -11,12 +11,6 @@ public class PublishableChangelogResults { protected Integer _count; protected Integer _offset; - /** - * Default constructor - */ - public PublishableChangelogResults() { - } - @JsonProperty("total") public Long getTotal() { return _total; diff --git a/src/main/java/com/imsweb/seerapi/client/rx/Rx.java b/src/main/java/com/imsweb/seerapi/client/rx/Rx.java index bc84885..c109c6c 100644 --- a/src/main/java/com/imsweb/seerapi/client/rx/Rx.java +++ b/src/main/java/com/imsweb/seerapi/client/rx/Rx.java @@ -40,12 +40,6 @@ public class Rx extends Publishable { @JsonProperty("radiation") protected String _radiation; - /** - * Default constructor - */ - public Rx() { - } - public List getHistory() { return _history; } diff --git a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java index 1b6d5ff..9381302 100644 --- a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java +++ b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelogResults.java @@ -13,12 +13,6 @@ public class RxChangelogResults extends PublishableChangelogResults { protected List _changelogs; - /** - * Default constructor - */ - public RxChangelogResults() { - } - @JsonProperty("changelogs") public List getChangelogs() { return _changelogs; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java index 4001202..aa2983f 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java @@ -3,6 +3,7 @@ */ package com.imsweb.seerapi.client.staging; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; @@ -41,7 +42,7 @@ public SchemaLookup(String site, String histology) { * @return a set of keys */ public Set getAllowedKeys() { - return null; + return Collections.emptySet(); } /** @@ -116,6 +117,7 @@ public void setHistology(String hist) { * Return true if the inputs contain a discriminator. A key that is not site or hist which has a non-null/non-empty value is considered a discriminator * @return true or false indicating whether a discriminator exists */ + @SuppressWarnings("java:S135") public boolean hasDiscriminator() { boolean hasDiscriminator = false; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java index a218462..089cb81 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingMetadataDeserializer.java @@ -3,7 +3,6 @@ import java.io.IOException; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; @@ -19,7 +18,7 @@ protected StagingMetadataDeserializer(Class vc) { } @Override - public StagingMetadata deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { + public StagingMetadata deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode node = jp.getCodec().readTree(jp); if (node.isNull()) diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java index 7d5a105..2fce171 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingSchema.java @@ -46,9 +46,6 @@ public enum StagingInputErrorHandler { private Set _involvedTables; private StagingInputErrorHandler _onInvalidInput; - public StagingSchema() { - } - @JsonProperty("id") public String getId() { return _displayId; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java index 30f281b..8974947 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java @@ -27,9 +27,6 @@ public class StagingTable { private Set _extraInput; private List> _rows; - public StagingTable() { - } - @JsonProperty("id") public String getId() { return _displayId; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java index db4d9c9..919772b 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java @@ -57,8 +57,7 @@ public enum CsInput { SSF21("ssf21"), SSF22("ssf22"), SSF23("ssf23"), - SSF24("ssf24"), - SSF25("ssf25"); + SSF24("ssf24"); private final String _name; diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java index fb75680..eac6b13 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmSchemaLookup.java @@ -9,11 +9,12 @@ import java.util.Set; import com.imsweb.seerapi.client.staging.SchemaLookup; +import com.imsweb.seerapi.client.staging.StagingData; public class TnmSchemaLookup extends SchemaLookup { - private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(TnmStagingData.PRIMARY_SITE_KEY, - TnmStagingData.HISTOLOGY_KEY, TnmStagingData.SSF25_KEY, TnmStagingData.SEX_KEY))); + private static final Set _ALLOWED_KEYS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(StagingData.PRIMARY_SITE_KEY, + StagingData.HISTOLOGY_KEY, TnmStagingData.SSF25_KEY, TnmStagingData.SEX_KEY))); /** * Constructor diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java index e4c9172..99069ef 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java @@ -57,8 +57,7 @@ public enum TnmInput { SSF21("ssf21"), SSF22("ssf22"), SSF23("ssf23"), - SSF24("ssf24"), - SSF25("ssf25"); + SSF24("ssf24"); private final String _name; diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index f4416d8..9c37942 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -74,6 +74,7 @@ public void testDiseaseSiteCateogires() throws IOException { assertEquals("C148", categories.get(0).getSites().get(0).getHigh()); } + @SuppressWarnings("java:S5961") @Test public void testDiseaseById() throws IOException { Disease disease = _DISEASE.getById("latest", "51f6cf58e3e27c3994bd5408").execute().body(); diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 01296a0..14fbc2f 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -92,7 +92,7 @@ public void testNdcSearch() throws IOException { search.setQuery("daklinza"); products = _NDC.search(search.paramMap()).execute().body(); - assertThat(products.size()).isGreaterThan(1); + assertThat(products).hasSizeGreaterThan(1); search.setRemovedSince("2020-10-01"); products = _NDC.search(search.paramMap()).execute().body(); @@ -114,7 +114,7 @@ public void testNdcSearchByCategory() throws IOException { Response> response = _NDC.search(search.paramMap()).execute(); - assertThat(Integer.valueOf(response.headers().get("X-Total-Count"))).isGreaterThan(0); + assertThat(Integer.valueOf(response.headers().get("X-Total-Count"))).isPositive(); List products = response.body(); assertThat(products).isNotEmpty(); @@ -132,19 +132,19 @@ public void testNdcHasSeerInfo() throws IOException { // get count of all drugs Response> response = _NDC.search(search.paramMap()).execute(); Integer totalCount = Integer.parseInt(response.headers().get("X-Total-Count")); - assertThat(totalCount).isGreaterThan(0); + assertThat(totalCount).isPositive(); // get count of seer-info drugs search.setHasSeerInfo(true); response = _NDC.search(search.paramMap()).execute(); Integer withCount = Integer.parseInt(response.headers().get("X-Total-Count")); - assertThat(withCount).isGreaterThan(0).isLessThan(totalCount); + assertThat(withCount).isPositive().isLessThan(totalCount); // get count of non seer-info drugs search.setHasSeerInfo(false); response = _NDC.search(search.paramMap()).execute(); Integer withoutCount = Integer.parseInt(response.headers().get("X-Total-Count")); - assertThat(withCount).isGreaterThan(0).isLessThan(totalCount); + assertThat(withCount).isPositive().isLessThan(totalCount); assertThat(totalCount).isEqualTo(withCount + withoutCount); } From 1c850ff4c5c6b0fea083351a657f5929814cea24 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 09:10:11 -0400 Subject: [PATCH 173/243] Fix fetch depth --- .github/workflows/integration.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 1289f06..1c787bc 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -12,6 +12,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: Set up JDK uses: actions/setup-java@v2 with: From 93e5404aad094a0c8b7d1269a783f925976fa036 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 09:13:43 -0400 Subject: [PATCH 174/243] Fixed unit test --- .../java/com/imsweb/seerapi/client/staging/SchemaLookup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java index aa2983f..8735a83 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/SchemaLookup.java @@ -68,7 +68,7 @@ public String getInput(String key) { * @param value value of input */ public void setInput(String key, String value) { - if (getAllowedKeys() != null && !getAllowedKeys().contains(key)) + if (!getAllowedKeys().isEmpty() && !getAllowedKeys().contains(key)) throw new IllegalStateException("The input key " + key + " is not allowed for lookups"); _inputs.put(key, value); From 3bd50e1cad4cda1c4d3bdbd0a42252cba3bf7fd9 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 10:03:31 -0400 Subject: [PATCH 175/243] Fix some code duplications --- .../client/disease/DiseaseChangelog.java | 44 ++-------------- .../client/glossary/GlossaryChangelog.java | 44 ++-------------- .../imsweb/seerapi/client/rx/RxChangelog.java | 44 ++-------------- .../seerapi/client/shared/Changelog.java | 52 +++++++++++++++++++ 4 files changed, 61 insertions(+), 123 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/shared/Changelog.java diff --git a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java index a74368f..0ddba06 100644 --- a/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java +++ b/src/main/java/com/imsweb/seerapi/client/disease/DiseaseChangelog.java @@ -3,12 +3,13 @@ */ package com.imsweb.seerapi.client.disease; -import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; -public class DiseaseChangelog { +import com.imsweb.seerapi.client.shared.Changelog; + +public class DiseaseChangelog extends Changelog { @JsonProperty("adds") private List _adds; @@ -16,14 +17,6 @@ public class DiseaseChangelog { private List _deletes; @JsonProperty("mods") private List _mods; - @JsonProperty("user") - private String _user; - @JsonProperty("date") - private Date _date; - @JsonProperty("version") - private String _version; - @JsonProperty("description") - private String _description; public List getAdds() { return _adds; @@ -49,35 +42,4 @@ public void setMods(List mods) { _mods = mods; } - public String getUser() { - return _user; - } - - public void setUser(String user) { - _user = user; - } - - public Date getDate() { - return _date; - } - - public void setDate(Date date) { - _date = date; - } - - public String getVersion() { - return _version; - } - - public void setVersion(String version) { - _version = version; - } - - public String getDescription() { - return _description; - } - - public void setDescription(String description) { - _description = description; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java index cb57e53..efa9ecd 100644 --- a/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java +++ b/src/main/java/com/imsweb/seerapi/client/glossary/GlossaryChangelog.java @@ -3,12 +3,13 @@ */ package com.imsweb.seerapi.client.glossary; -import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; -public class GlossaryChangelog { +import com.imsweb.seerapi.client.shared.Changelog; + +public class GlossaryChangelog extends Changelog { @JsonProperty("adds") private List _adds; @@ -16,14 +17,6 @@ public class GlossaryChangelog { private List _deletes; @JsonProperty("mods") private List _mods; - @JsonProperty("user") - private String _user; - @JsonProperty("date") - private Date _date; - @JsonProperty("version") - private String _version; - @JsonProperty("description") - private String _description; public List getAdds() { return _adds; @@ -49,35 +42,4 @@ public void setMods(List mods) { _mods = mods; } - public String getUser() { - return _user; - } - - public void setUser(String user) { - _user = user; - } - - public Date getDate() { - return _date; - } - - public void setDate(Date date) { - _date = date; - } - - public String getVersion() { - return _version; - } - - public void setVersion(String version) { - _version = version; - } - - public String getDescription() { - return _description; - } - - public void setDescription(String description) { - _description = description; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java index 0e88953..5c0aa4c 100644 --- a/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java +++ b/src/main/java/com/imsweb/seerapi/client/rx/RxChangelog.java @@ -3,12 +3,13 @@ */ package com.imsweb.seerapi.client.rx; -import java.util.Date; import java.util.List; import com.fasterxml.jackson.annotation.JsonProperty; -public class RxChangelog { +import com.imsweb.seerapi.client.shared.Changelog; + +public class RxChangelog extends Changelog { @JsonProperty("adds") private List _adds; @@ -16,14 +17,6 @@ public class RxChangelog { private List _deletes; @JsonProperty("mods") private List _mods; - @JsonProperty("user") - private String _user; - @JsonProperty("date") - private Date _date; - @JsonProperty("version") - private String _version; - @JsonProperty("description") - private String _description; public List getAdds() { return _adds; @@ -49,35 +42,4 @@ public void setMods(List mods) { _mods = mods; } - public String getUser() { - return _user; - } - - public void setUser(String user) { - _user = user; - } - - public Date getDate() { - return _date; - } - - public void setDate(Date date) { - _date = date; - } - - public String getVersion() { - return _version; - } - - public void setVersion(String version) { - _version = version; - } - - public String getDescription() { - return _description; - } - - public void setDescription(String description) { - _description = description; - } } diff --git a/src/main/java/com/imsweb/seerapi/client/shared/Changelog.java b/src/main/java/com/imsweb/seerapi/client/shared/Changelog.java new file mode 100644 index 0000000..db7b652 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/shared/Changelog.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.shared; + +import java.util.Date; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Changelog { + + @JsonProperty("user") + private String _user; + @JsonProperty("date") + private Date _date; + @JsonProperty("version") + private String _version; + @JsonProperty("description") + private String _description; + + public String getUser() { + return _user; + } + + public void setUser(String user) { + _user = user; + } + + public Date getDate() { + return _date; + } + + public void setDate(Date date) { + _date = date; + } + + public String getVersion() { + return _version; + } + + public void setVersion(String version) { + _version = version; + } + + public String getDescription() { + return _description; + } + + public void setDescription(String description) { + _description = description; + } +} From 29cd46dd374ac6718b2c3f041b9f493d8147455c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 10:50:44 -0400 Subject: [PATCH 176/243] More cleanup --- .../client/staging/cs/CsStagingData.java | 2 +- .../client/staging/eod/EodStagingData.java | 2 +- .../client/staging/tnm/TnmStagingData.java | 2 +- .../java/com/imsweb/seerapi/client/Range.java | 3 - .../seerapi/client/glossary/GlossaryTest.java | 70 ++++++++++--------- .../client/{ => hcpcs}/mph/MphTest.java | 6 +- .../com/imsweb/seerapi/client/rx/RxTest.java | 1 + .../client/siterecode/SiteRecodeTest.java | 1 + .../seerapi/client/surgery/SurgeryTest.java | 1 + 9 files changed, 47 insertions(+), 41 deletions(-) rename src/test/java/com/imsweb/seerapi/client/{ => hcpcs}/mph/MphTest.java (96%) diff --git a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java index 919772b..f6ef98a 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/cs/CsStagingData.java @@ -211,7 +211,7 @@ public void setSsf(Integer id, String ssf) { */ public static class CsStagingInputBuilder { - private CsStagingData _data; + private final CsStagingData _data; public CsStagingInputBuilder() { _data = new CsStagingData(); diff --git a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java index 6f8854a..afb4f67 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/eod/EodStagingData.java @@ -159,7 +159,7 @@ public String toString() { */ public static class EodStagingInputBuilder { - private EodStagingData _data; + private final EodStagingData _data; public EodStagingInputBuilder() { _data = new EodStagingData(); diff --git a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java index 99069ef..e16163c 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/tnm/TnmStagingData.java @@ -180,7 +180,7 @@ public void setSsf(Integer id, String ssf) { */ public static class TnmStagingInputBuilder { - private TnmStagingData _data; + private final TnmStagingData _data; public TnmStagingInputBuilder() { _data = new TnmStagingData(); diff --git a/src/test/java/com/imsweb/seerapi/client/Range.java b/src/test/java/com/imsweb/seerapi/client/Range.java index 804f745..eb06d24 100644 --- a/src/test/java/com/imsweb/seerapi/client/Range.java +++ b/src/test/java/com/imsweb/seerapi/client/Range.java @@ -12,9 +12,6 @@ public class Range { @JsonProperty("high") protected String _highValue; - public Range() { - } - public Range(String low, String high) { setLowValue(low); setHighValue(high); diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index eed2e39..ba8e886 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Set; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -21,6 +20,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; public class GlossaryTest { @@ -33,13 +33,14 @@ public static void setup() { @Test public void testGlossaryCategory() { - Assert.assertEquals(Glossary.Category.SOLID_TUMOR, Glossary.Category.valueOf("SOLID_TUMOR")); + assertEquals(Glossary.Category.SOLID_TUMOR, Glossary.Category.valueOf("SOLID_TUMOR")); } @Test public void testGlossaryVersions() throws IOException { List versions = _GLOSSARY.versions().execute().body(); + assertNotNull(versions); assertEquals(1, versions.size()); GlossaryVersion version = versions.get(0); assertEquals("latest", version.getName()); @@ -51,26 +52,27 @@ public void testGlossaryVersions() throws IOException { @Test public void testGlossaryById() throws IOException { GlossarySearchResults results = _GLOSSARY.search("latest", "Lymphangiogram").execute().body(); - Assert.assertTrue(results.getCount() > 0); + assertNotNull(results); + assertTrue(results.getCount() > 0); Glossary glossary = _GLOSSARY.getById("latest", results.getResults().get(0).getId()).execute().body(); - Assert.assertNotNull(glossary); - Assert.assertEquals("Lymphangiogram", glossary.getName()); - Assert.assertEquals(Collections.singletonList(GENERAL), glossary.getCategories()); - Assert.assertNull(glossary.getPrimarySite()); + assertNotNull(glossary); + assertEquals("Lymphangiogram", glossary.getName()); + assertEquals(Collections.singletonList(GENERAL), glossary.getCategories()); + assertNull(glossary.getPrimarySite()); - Assert.assertNull(glossary.getHistology()); - Assert.assertTrue(glossary.getDefinition().startsWith("An x-ray of the lymphatic system.")); - Assert.assertNull(glossary.getAlternateName()); - Assert.assertNull(glossary.getHistory()); + assertNull(glossary.getHistology()); + assertTrue(glossary.getDefinition().startsWith("An x-ray of the lymphatic system.")); + assertNull(glossary.getAlternateName()); + assertNull(glossary.getHistory()); } @Test public void testGlossaryChangelog() throws IOException { GlossaryChangelogResults results = _GLOSSARY.changelogs("latest", null, null, 1).execute().body(); - Assert.assertNotNull(results); + assertNotNull(results); // TODO since all the glossary items were removed from the production database, this needs to be commented out; it will return when they are published again @@ -104,28 +106,28 @@ public void testGlossarySearch() throws IOException { GlossarySearchResults results = _GLOSSARY.search("latest", search.paramMap()).execute().body(); - Assert.assertNotNull(results); - Assert.assertEquals(25, results.getCount().longValue()); - Assert.assertTrue(results.getTotal().longValue() > 0); - Assert.assertTrue(results.getResults().size() > 0); - Assert.assertEquals(Collections.singletonList(term), results.getTerms()); + assertNotNull(results); + assertEquals(25, results.getCount().longValue()); + assertTrue(results.getTotal().longValue() > 0); + assertTrue(results.getResults().size() > 0); + assertEquals(Collections.singletonList(term), results.getTerms()); // add the category and verify there are no results results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.SOLID_TUMOR)).execute().body(); - Assert.assertNotNull(results); - Assert.assertEquals(25, results.getCount().longValue()); - Assert.assertEquals(0, results.getTotal().longValue()); - Assert.assertNull(results.getResults()); + assertNotNull(results); + assertEquals(25, results.getCount().longValue()); + assertEquals(0, results.getTotal().longValue()); + assertNull(results.getResults()); // add a second category and verify there are we get the results again results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.SOLID_TUMOR, Glossary.Category.HEMATO)).execute().body(); - Assert.assertNotNull(results); - Assert.assertEquals(25, results.getCount().longValue()); - Assert.assertTrue(results.getTotal().longValue() > 0); - Assert.assertTrue(results.getResults().size() > 0); - Assert.assertEquals(Collections.singletonList(term), results.getTerms()); + assertNotNull(results); + assertEquals(25, results.getCount().longValue()); + assertTrue(results.getTotal().longValue() > 0); + assertTrue(results.getResults().size() > 0); + assertEquals(Collections.singletonList(term), results.getTerms()); } @Test @@ -139,9 +141,9 @@ public void testGlossarySearchIterate() throws IOException { while (total == null || search.getOffset() < total) { GlossarySearchResults results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.HEMATO)).execute().body(); - Assert.assertNotNull(results); - Assert.assertTrue(results.getTotal() > 0); - Assert.assertTrue(results.getResults().size() > 0); + assertNotNull(results); + assertTrue(results.getTotal() > 0); + assertTrue(results.getResults().size() > 0); // the first time through, set the total if (total == null) @@ -150,7 +152,7 @@ public void testGlossarySearchIterate() throws IOException { search.setOffset(search.getOffset() + results.getResults().size()); } - Assert.assertTrue(total > 100); + assertTrue(total > 100); } @Test @@ -158,12 +160,12 @@ public void testGlossaryMatch() throws IOException { String text = "This text contains summary stage which should be found."; Set matches = _GLOSSARY.match(text, null, true).execute().body(); - Assert.assertNotNull(matches); - Assert.assertEquals(1, matches.size()); + assertNotNull(matches); + assertEquals(1, matches.size()); matches = _GLOSSARY.match(text, EnumSet.of(GENERAL), true).execute().body(); - Assert.assertNotNull(matches); - Assert.assertEquals(0, matches.size()); + assertNotNull(matches); + assertEquals(0, matches.size()); } } diff --git a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java similarity index 96% rename from src/test/java/com/imsweb/seerapi/client/mph/MphTest.java rename to src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 82ded4e..6cad0e1 100644 --- a/src/test/java/com/imsweb/seerapi/client/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -1,4 +1,4 @@ -package com.imsweb.seerapi.client.mph; +package com.imsweb.seerapi.client.hcpcs.mph; import java.io.IOException; @@ -7,6 +7,10 @@ import com.imsweb.seerapi.client.BadRequestException; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.mph.MphInput; +import com.imsweb.seerapi.client.mph.MphInputPair; +import com.imsweb.seerapi.client.mph.MphOutput; +import com.imsweb.seerapi.client.mph.MphService; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index f81f98a..924bc91 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -33,6 +33,7 @@ public static void setup() { public void testRxVersions() throws IOException { List versions = _RX.versions().execute().body(); + assertNotNull(versions); assertEquals(1, versions.size()); RxVersion version = versions.get(0); assertEquals("latest", version.getName()); diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index d2f6bd7..30cd173 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -62,6 +62,7 @@ public void testSiteRecode() throws IOException { Call call = _SITE_RECODE.siteGroup("C379", "9650"); SiteRecode recode = call.execute().body(); + assertNotNull(recode); assertEquals("C379", recode.getSite()); assertEquals("9650", recode.getHist()); assertEquals("33011", recode.getSiteGroup()); diff --git a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java index 61b8f95..1c49860 100644 --- a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java @@ -48,6 +48,7 @@ public void testSiteSpecificSurgeryTable() throws IOException { assertThat(row.getLineBreak()).isFalse(); table = _SURGERY.table("2014", null, "C001", "8000").execute().body(); + assertThat(table).isNotNull(); assertThat(table.getTitle()).isEqualTo("Oral Cavity"); } } From 9f879bb0c08687af9952280540f1010d049e8396 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Mon, 6 Jun 2022 10:54:08 -0400 Subject: [PATCH 177/243] Fixed unit test --- src/test/java/com/imsweb/seerapi/client/Range.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/client/Range.java b/src/test/java/com/imsweb/seerapi/client/Range.java index eb06d24..6cfd17b 100644 --- a/src/test/java/com/imsweb/seerapi/client/Range.java +++ b/src/test/java/com/imsweb/seerapi/client/Range.java @@ -12,6 +12,10 @@ public class Range { @JsonProperty("high") protected String _highValue; + public Range() { + // the object mapper needs this defined + } + public Range(String low, String high) { setLowValue(low); setHighValue(high); From e2544e032009281c3f63eb3237af29cffb065ce6 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 7 Jun 2022 14:27:44 -0400 Subject: [PATCH 178/243] Starting to improve code coverage --- .../seerapi/client/staging/StagingTest.java | 167 +++++++++++------- 1 file changed, 105 insertions(+), 62 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index e81cbc4..d2285cf 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -15,7 +15,50 @@ import com.imsweb.seerapi.client.glossary.Glossary.Category; import com.imsweb.seerapi.client.shared.KeywordMatch; import com.imsweb.seerapi.client.staging.cs.CsSchemaLookup; - +import com.imsweb.seerapi.client.staging.cs.CsStagingData; +import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsInput; +import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsStagingInputBuilder; + +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC7_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.CSVER_DERIVED; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SCHEMA_NUMBER; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS1977_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.SS2000_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC6_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_M; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_MDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_N; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_NDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_T; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_AJCC7_TDESCRIPTOR; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_SS1977_STAGE; +import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_SS2000_STAGE; import static org.assertj.core.api.Assertions.assertThat; public class StagingTest { @@ -143,27 +186,27 @@ public void testTableInvoledSchemas() throws IOException { } @Test - public void testStaging() throws IOException { - // test this case: http://seer.cancer.gov/seertools/cstest/?mets=10&lnexam=99&diagnosis_year=2013&grade=9&exteval=9&age=060&site=C680&metseval=9&hist=8000&ext=100&version=020550&nodeseval=9&behav=3&lnpos=99&nodes=100&csver_original=020440&lvi=9&ssf1=020&size=075 - StagingData data = new StagingData(); - data.setInput("site", "C680"); - data.setInput("hist", "8000"); - data.setInput("behavior", "3"); - data.setInput("grade", "9"); - data.setInput("year_dx", "2013"); - data.setInput("cs_input_version_original", "020550"); - data.setInput("size", "075"); - data.setInput("extension", "100"); - data.setInput("extension_eval", "9"); - data.setInput("nodes", "100"); - data.setInput("nodes_eval", "9"); - data.setInput("nodes_pos", "99"); - data.setInput("nodes_exam", "99"); - data.setInput("mets", "10"); - data.setInput("mets_eval", "9"); - data.setInput("lvi", "9"); - data.setInput("age_dx", "060"); - data.setInput("ssf1", "020"); + public void testCsStaging() throws IOException { + CsStagingData data = new CsStagingInputBuilder() + .withInput(CsInput.PRIMARY_SITE, "C680") + .withInput(CsInput.HISTOLOGY, "8000") + .withInput(CsInput.BEHAVIOR, "3") + .withInput(CsInput.GRADE, "9") + .withInput(CsInput.DX_YEAR, "2013") + .withInput(CsInput.CS_VERSION_ORIGINAL, "020550") + .withInput(CsInput.TUMOR_SIZE, "075") + .withInput(CsInput.EXTENSION, "100") + .withInput(CsInput.EXTENSION_EVAL, "9") + .withInput(CsInput.LYMPH_NODES, "100") + .withInput(CsInput.LYMPH_NODES_EVAL, "9") + .withInput(CsInput.REGIONAL_NODES_POSITIVE, "99") + .withInput(CsInput.REGIONAL_NODES_EXAMINED, "99") + .withInput(CsInput.METS_AT_DX, "10") + .withInput(CsInput.METS_EVAL, "9") + .withInput(CsInput.LVI, "9") + .withInput(CsInput.AGE_AT_DX, "060") + .withSsf(1, "020") + .build(); // perform the staging StagingData output = _STAGING.stage(_ALGORITHM, _VERSION, data.getInput()).execute().body(); @@ -174,53 +217,53 @@ public void testStaging() throws IOException { assertThat(output.getPath()).hasSize(37); // check output - assertThat(output.getOutput("schema_number")).isEqualTo("129"); + assertThat(output.getOutput(SCHEMA_NUMBER.toString())).isEqualTo("129"); assertThat(output.getSchemaId()).isEqualTo("urethra"); - assertThat(output.getOutput("csver_derived")).isEqualTo("020550"); + assertThat(output.getOutput(CSVER_DERIVED.toString())).isEqualTo("020550"); // AJCC 6 - assertThat(output.getOutput("ajcc6_t")).isEqualTo("T1"); - assertThat(output.getOutput("stor_ajcc6_t")).isEqualTo("10"); - assertThat(output.getOutput("ajcc6_tdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("stor_ajcc6_tdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("ajcc6_n")).isEqualTo("N1"); - assertThat(output.getOutput("stor_ajcc6_n")).isEqualTo("10"); - assertThat(output.getOutput("ajcc6_ndescriptor")).isEqualTo("c"); - assertThat(output.getOutput("stor_ajcc6_ndescriptor")).isEqualTo("c"); - assertThat(output.getOutput("ajcc6_m")).isEqualTo("M1"); - assertThat(output.getOutput("stor_ajcc6_m")).isEqualTo("10"); - assertThat(output.getOutput("ajcc6_mdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("stor_ajcc6_mdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("ajcc6_stage")).isEqualTo("IV"); - assertThat(output.getOutput("stor_ajcc6_stage")).isEqualTo("70"); + assertThat(output.getOutput(AJCC6_T.toString())).isEqualTo("T1"); + assertThat(output.getOutput(STOR_AJCC6_T.toString())).isEqualTo("10"); + assertThat(output.getOutput(AJCC6_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC6_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC6_N.toString())).isEqualTo("N1"); + assertThat(output.getOutput(STOR_AJCC6_N.toString())).isEqualTo("10"); + assertThat(output.getOutput(AJCC6_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC6_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC6_M.toString())).isEqualTo("M1"); + assertThat(output.getOutput(STOR_AJCC6_M.toString())).isEqualTo("10"); + assertThat(output.getOutput(AJCC6_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC6_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC6_STAGE.toString())).isEqualTo("IV"); + assertThat(output.getOutput(STOR_AJCC6_STAGE.toString())).isEqualTo("70"); // AJCC 7 - assertThat(output.getOutput("ajcc7_t")).isEqualTo("T1"); - assertThat(output.getOutput("stor_ajcc7_t")).isEqualTo("100"); - assertThat(output.getOutput("ajcc7_tdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("stor_ajcc7_tdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("ajcc7_n")).isEqualTo("N1"); - assertThat(output.getOutput("stor_ajcc7_n")).isEqualTo("100"); - assertThat(output.getOutput("ajcc7_ndescriptor")).isEqualTo("c"); - assertThat(output.getOutput("stor_ajcc7_ndescriptor")).isEqualTo("c"); - assertThat(output.getOutput("ajcc7_m")).isEqualTo("M1"); - assertThat(output.getOutput("stor_ajcc7_m")).isEqualTo("100"); - assertThat(output.getOutput("ajcc7_mdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("stor_ajcc7_mdescriptor")).isEqualTo("c"); - assertThat(output.getOutput("ajcc7_stage")).isEqualTo("IV"); - assertThat(output.getOutput("stor_ajcc7_stage")).isEqualTo("700"); + assertThat(output.getOutput(AJCC7_T.toString())).isEqualTo("T1"); + assertThat(output.getOutput(STOR_AJCC7_T.toString())).isEqualTo("100"); + assertThat(output.getOutput(AJCC7_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC7_TDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC7_N.toString())).isEqualTo("N1"); + assertThat(output.getOutput(STOR_AJCC7_N.toString())).isEqualTo("100"); + assertThat(output.getOutput(AJCC7_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC7_NDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC7_M.toString())).isEqualTo("M1"); + assertThat(output.getOutput(STOR_AJCC7_M.toString())).isEqualTo("100"); + assertThat(output.getOutput(AJCC7_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(STOR_AJCC7_MDESCRIPTOR.toString())).isEqualTo("c"); + assertThat(output.getOutput(AJCC7_STAGE.toString())).isEqualTo("IV"); + assertThat(output.getOutput(STOR_AJCC7_STAGE.toString())).isEqualTo("700"); // Summary Stage - assertThat(output.getOutput("t77")).isEqualTo("L"); - assertThat(output.getOutput("n77")).isEqualTo("RN"); - assertThat(output.getOutput("m77")).isEqualTo("D"); - assertThat(output.getOutput("ss77")).isEqualTo("D"); - assertThat(output.getOutput("stor_ss77")).isEqualTo("7"); - assertThat(output.getOutput("t2000")).isEqualTo("L"); - assertThat(output.getOutput("n2000")).isEqualTo("RN"); - assertThat(output.getOutput("m2000")).isEqualTo("D"); - assertThat(output.getOutput("ss2000")).isEqualTo("D"); - assertThat(output.getOutput("stor_ss2000")).isEqualTo("7"); + assertThat(output.getOutput(SS1977_T.toString())).isEqualTo("L"); + assertThat(output.getOutput(SS1977_N.toString())).isEqualTo("RN"); + assertThat(output.getOutput(SS1977_M.toString())).isEqualTo("D"); + assertThat(output.getOutput(SS1977_STAGE.toString())).isEqualTo("D"); + assertThat(output.getOutput(STOR_SS1977_STAGE.toString())).isEqualTo("7"); + assertThat(output.getOutput(SS2000_T.toString())).isEqualTo("L"); + assertThat(output.getOutput(SS2000_N.toString())).isEqualTo("RN"); + assertThat(output.getOutput(SS2000_M.toString())).isEqualTo("D"); + assertThat(output.getOutput(SS2000_STAGE.toString())).isEqualTo("D"); + assertThat(output.getOutput(STOR_SS2000_STAGE.toString())).isEqualTo("7"); } @Test From 1e305a85e928f752a041e68990a62c2be9677592 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 7 Jun 2022 16:31:49 -0400 Subject: [PATCH 179/243] More coverage --- .../seerapi/client/staging/StagingTest.java | 137 +++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index d2285cf..b9f9740 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -18,6 +18,10 @@ import com.imsweb.seerapi.client.staging.cs.CsStagingData; import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsInput; import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsStagingInputBuilder; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmInput; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmOutput; +import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmStagingInputBuilder; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_M; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_MDESCRIPTOR; @@ -185,6 +189,52 @@ public void testTableInvoledSchemas() throws IOException { assertThat(schemas).isNotEmpty(); } + @Test + public void testCsInputBuilder() { + CsStagingData data1 = new CsStagingData(); + data1.setInput(CsInput.PRIMARY_SITE, "C680"); + data1.setInput(CsInput.HISTOLOGY, "8000"); + data1.setInput(CsInput.BEHAVIOR, "3"); + data1.setInput(CsInput.GRADE, "9"); + data1.setInput(CsInput.DX_YEAR, "2013"); + data1.setInput(CsInput.CS_VERSION_ORIGINAL, "020550"); + data1.setInput(CsInput.TUMOR_SIZE, "075"); + data1.setInput(CsInput.EXTENSION, "100"); + data1.setInput(CsInput.EXTENSION_EVAL, "9"); + data1.setInput(CsInput.LYMPH_NODES, "100"); + data1.setInput(CsInput.LYMPH_NODES_EVAL, "9"); + data1.setInput(CsInput.REGIONAL_NODES_POSITIVE, "99"); + data1.setInput(CsInput.REGIONAL_NODES_EXAMINED, "99"); + data1.setInput(CsInput.METS_AT_DX, "10"); + data1.setInput(CsInput.METS_EVAL, "9"); + data1.setInput(CsInput.LVI, "9"); + data1.setInput(CsInput.AGE_AT_DX, "060"); + data1.setSsf(1, "020"); + + CsStagingData data2 = new CsStagingInputBuilder() + .withInput(CsStagingData.CsInput.PRIMARY_SITE, "C680") + .withInput(CsStagingData.CsInput.HISTOLOGY, "8000") + .withInput(CsStagingData.CsInput.BEHAVIOR, "3") + .withInput(CsStagingData.CsInput.GRADE, "9") + .withInput(CsStagingData.CsInput.DX_YEAR, "2013") + .withInput(CsStagingData.CsInput.CS_VERSION_ORIGINAL, "020550") + .withInput(CsStagingData.CsInput.TUMOR_SIZE, "075") + .withInput(CsStagingData.CsInput.EXTENSION, "100") + .withInput(CsStagingData.CsInput.EXTENSION_EVAL, "9") + .withInput(CsStagingData.CsInput.LYMPH_NODES, "100") + .withInput(CsStagingData.CsInput.LYMPH_NODES_EVAL, "9") + .withInput(CsStagingData.CsInput.REGIONAL_NODES_POSITIVE, "99") + .withInput(CsStagingData.CsInput.REGIONAL_NODES_EXAMINED, "99") + .withInput(CsStagingData.CsInput.METS_AT_DX, "10") + .withInput(CsStagingData.CsInput.METS_EVAL, "9") + .withInput(CsStagingData.CsInput.LVI, "9") + .withInput(CsStagingData.CsInput.AGE_AT_DX, "060") + .withSsf(1, "020") + .build(); + + assertThat(data1.getInput()).isEqualTo(data2.getInput()); + } + @Test public void testCsStaging() throws IOException { CsStagingData data = new CsStagingInputBuilder() @@ -209,7 +259,7 @@ public void testCsStaging() throws IOException { .build(); // perform the staging - StagingData output = _STAGING.stage(_ALGORITHM, _VERSION, data.getInput()).execute().body(); + StagingData output = _STAGING.stage("cs", "02.05.50", data.getInput()).execute().body(); assertThat(output).isNotNull(); assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); @@ -266,6 +316,91 @@ public void testCsStaging() throws IOException { assertThat(output.getOutput(STOR_SS2000_STAGE.toString())).isEqualTo("7"); } + @Test + public void testTnmInputBuilder() { + TnmStagingData data1 = new TnmStagingData(); + data1.setInput(TnmInput.PRIMARY_SITE, "C680"); + data1.setInput(TnmInput.HISTOLOGY, "8000"); + data1.setInput(TnmInput.BEHAVIOR, "3"); + data1.setInput(TnmInput.GRADE, "9"); + data1.setInput(TnmInput.DX_YEAR, "2013"); + data1.setInput(TnmInput.REGIONAL_NODES_POSITIVE, "99"); + data1.setInput(TnmInput.AGE_AT_DX, "060"); + data1.setInput(TnmInput.SEX, "1"); + data1.setInput(TnmInput.RX_SUMM_SURGERY, "8"); + data1.setInput(TnmInput.RX_SUMM_RADIATION, "9"); + data1.setInput(TnmInput.CLIN_T, "1"); + data1.setInput(TnmInput.CLIN_N, "2"); + data1.setInput(TnmInput.CLIN_M, "3"); + data1.setInput(TnmInput.PATH_T, "4"); + data1.setInput(TnmInput.PATH_N, "5"); + data1.setInput(TnmInput.PATH_M, "6"); + data1.setSsf(1, "020"); + + TnmStagingData data2 = new TnmStagingData.TnmStagingInputBuilder() + .withInput(TnmInput.PRIMARY_SITE, "C680") + .withInput(TnmInput.HISTOLOGY, "8000") + .withInput(TnmInput.BEHAVIOR, "3") + .withInput(TnmInput.GRADE, "9") + .withInput(TnmInput.DX_YEAR, "2013") + .withInput(TnmInput.REGIONAL_NODES_POSITIVE, "99") + .withInput(TnmInput.AGE_AT_DX, "060") + .withInput(TnmInput.SEX, "1") + .withInput(TnmInput.RX_SUMM_SURGERY, "8") + .withInput(TnmInput.RX_SUMM_RADIATION, "9") + .withInput(TnmInput.CLIN_T, "1") + .withInput(TnmInput.CLIN_N, "2") + .withInput(TnmInput.CLIN_M, "3") + .withInput(TnmInput.PATH_T, "4") + .withInput(TnmInput.PATH_N, "5") + .withInput(TnmInput.PATH_M, "6") + .withSsf(1, "020").build(); + + assertThat(data1.getInput()).isEqualTo(data2.getInput()); + } + + @Test + public void testTnmStaging() throws IOException { + TnmStagingData data = new TnmStagingInputBuilder() + .withInput(TnmInput.PRIMARY_SITE, "C680") + .withInput(TnmInput.HISTOLOGY, "8000") + .withInput(TnmInput.BEHAVIOR, "3") + .withInput(TnmInput.DX_YEAR, "2016") + .withInput(TnmInput.RX_SUMM_SURGERY, "2") + .withInput(TnmInput.RX_SUMM_RADIATION, "4") + .withInput(TnmInput.REGIONAL_NODES_POSITIVE, "02") + .withInput(TnmInput.CLIN_T, "c0") + .withInput(TnmInput.CLIN_N, "c1") + .withInput(TnmInput.CLIN_M, "c0") + .withInput(TnmInput.PATH_T, "p0") + .withInput(TnmInput.PATH_N, "p1") + .withInput(TnmInput.PATH_M, "p1") + .build(); + + // perform the staging + StagingData output = _STAGING.stage("tnm", "1.9", data.getInput()).execute().body(); + + // check output + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getSchemaId()).isEqualTo("urethra"); + assertThat(output.getErrors()).isEmpty(); + assertThat(output.getPath()).hasSize(25); + assertThat(output.getOutput()).hasSize(10); + + // check outputs + assertThat(output.getOutput(TnmOutput.DERIVED_VERSION.toString())).isEqualTo("1.9"); + assertThat(output.getOutput(TnmOutput.CLIN_STAGE_GROUP.toString())).isEqualTo("3"); + assertThat(output.getOutput(TnmOutput.PATH_STAGE_GROUP.toString())).isEqualTo("4"); + assertThat(output.getOutput(TnmOutput.COMBINED_STAGE_GROUP.toString())).isEqualTo("4"); + assertThat(output.getOutput(TnmOutput.COMBINED_T.toString())).isEqualTo("c0"); + assertThat(output.getOutput(TnmOutput.SOURCE_T.toString())).isEqualTo("1"); + assertThat(output.getOutput(TnmOutput.COMBINED_N.toString())).isEqualTo("c1"); + assertThat(output.getOutput(TnmOutput.SOURCE_N.toString())).isEqualTo("1"); + assertThat(output.getOutput(TnmOutput.COMBINED_M.toString())).isEqualTo("p1"); + assertThat(output.getOutput(TnmOutput.SOURCE_M.toString())).isEqualTo("2"); + } + @Test public void testStagingWithErrors() throws IOException { StagingData data = new StagingData(); From c7554c9ad7ac1ef7ef9fdac1873654ce115785c3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 7 Jun 2022 16:46:17 -0400 Subject: [PATCH 180/243] More coverage --- .../seerapi/client/staging/StagingTest.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index b9f9740..97983a2 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -18,6 +18,10 @@ import com.imsweb.seerapi.client.staging.cs.CsStagingData; import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsInput; import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsStagingInputBuilder; +import com.imsweb.seerapi.client.staging.eod.EodStagingData; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodInput; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodOutput; +import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodStagingInputBuilder; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmInput; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmOutput; @@ -401,6 +405,68 @@ public void testTnmStaging() throws IOException { assertThat(output.getOutput(TnmOutput.SOURCE_M.toString())).isEqualTo("2"); } + @Test + public void testEodInputBuilder() { + EodStagingData data1 = new EodStagingData(); + data1.setInput(EodInput.PRIMARY_SITE, "C250"); + data1.setInput(EodInput.HISTOLOGY, "8154"); + data1.setInput(EodInput.DX_YEAR, "2018"); + data1.setInput(EodInput.AGE_AT_DX, "060"); + data1.setInput(EodInput.SEX, "1"); + data1.setInput(EodInput.TUMOR_SIZE_SUMMARY, "004"); + data1.setInput(EodInput.NODES_POS, "03"); + data1.setInput(EodInput.EOD_PRIMARY_TUMOR, "500"); + data1.setInput(EodInput.EOD_REGIONAL_NODES, "300"); + data1.setInput(EodInput.EOD_METS, "10"); + + EodStagingData data2 = new EodStagingInputBuilder() + .withInput(EodInput.PRIMARY_SITE, "C250") + .withInput(EodInput.HISTOLOGY, "8154") + .withInput(EodInput.DX_YEAR, "2018") + .withInput(EodInput.AGE_AT_DX, "060") + .withInput(EodInput.SEX, "1") + .withInput(EodInput.TUMOR_SIZE_SUMMARY, "004") + .withInput(EodInput.NODES_POS, "03") + .withInput(EodInput.EOD_PRIMARY_TUMOR, "500") + .withInput(EodInput.EOD_REGIONAL_NODES, "300") + .withInput(EodInput.EOD_METS, "10").build(); + + assertThat(data1.getInput()).isEqualTo(data2.getInput()); + } + + @Test + public void testEodStaging() throws IOException { + EodStagingData data = new EodStagingInputBuilder() + .withInput(EodInput.PRIMARY_SITE, "C250") + .withInput(EodInput.HISTOLOGY, "8154") + .withInput(EodInput.DX_YEAR, "2018") + .withInput(EodInput.TUMOR_SIZE_SUMMARY, "004") + .withInput(EodInput.NODES_POS, "03") + .withInput(EodInput.EOD_PRIMARY_TUMOR, "500") + .withInput(EodInput.EOD_REGIONAL_NODES, "300") + .withInput(EodInput.EOD_METS, "10").build(); + + // perform the staging + StagingData output = _STAGING.stage("eod_public", "2.1", data.getInput()).execute().body(); + + assertThat(output).isNotNull(); + assertThat(output.getResult()).isEqualTo(StagingData.Result.STAGED); + assertThat(output.getSchemaId()).isEqualTo("pancreas"); + assertThat(output.getErrors()).isEmpty(); + assertThat(output.getPath()).hasSize(12); + assertThat(output.getOutput()).hasSize(9); + + // check outputs + assertThat(output.getOutput(EodOutput.DERIVED_VERSION.toString())).isEqualTo("2.1"); + assertThat(output.getOutput(EodOutput.SS_2018_DERIVED.toString())).isEqualTo("7"); + assertThat(output.getOutput(EodOutput.NAACCR_SCHEMA_ID.toString())).isEqualTo("00280"); + assertThat(output.getOutput(EodOutput.EOD_2018_STAGE_GROUP.toString())).isEqualTo("4"); + assertThat(output.getOutput(EodOutput.EOD_2018_T.toString())).isEqualTo("T1a"); + assertThat(output.getOutput(EodOutput.EOD_2018_N.toString())).isEqualTo("N1"); + assertThat(output.getOutput(EodOutput.EOD_2018_M.toString())).isEqualTo("M1"); + assertThat(output.getOutput(EodOutput.AJCC_ID.toString())).isEqualTo("28"); + } + @Test public void testStagingWithErrors() throws IOException { StagingData data = new StagingData(); From 86911318694a5756a3febdf2af1575cf17f266de Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 09:12:11 -0400 Subject: [PATCH 181/243] Improve coverage --- .../seerapi/client/staging/StagingTest.java | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 97983a2..3593e21 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -5,7 +5,9 @@ import java.io.IOException; import java.util.EnumSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import org.junit.BeforeClass; @@ -18,15 +20,19 @@ import com.imsweb.seerapi.client.staging.cs.CsStagingData; import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsInput; import com.imsweb.seerapi.client.staging.cs.CsStagingData.CsStagingInputBuilder; +import com.imsweb.seerapi.client.staging.eod.EodSchemaLookup; import com.imsweb.seerapi.client.staging.eod.EodStagingData; import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodInput; import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodOutput; import com.imsweb.seerapi.client.staging.eod.EodStagingData.EodStagingInputBuilder; +import com.imsweb.seerapi.client.staging.tnm.TnmSchemaLookup; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmInput; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmOutput; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmStagingInputBuilder; +import static com.imsweb.seerapi.client.staging.StagingData.HISTOLOGY_KEY; +import static com.imsweb.seerapi.client.staging.StagingData.PRIMARY_SITE_KEY; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_M; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_MDESCRIPTOR; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_N; @@ -68,6 +74,7 @@ import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_SS1977_STAGE; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.STOR_SS2000_STAGE; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; public class StagingTest { @@ -112,7 +119,7 @@ public void testSchemaLookup() throws IOException { // now test just site SchemaLookup data = new SchemaLookup(); - data.setInput(StagingData.PRIMARY_SITE_KEY, "C111"); + data.setInput(PRIMARY_SITE_KEY, "C111"); assertThat(_STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body()).hasSize(7); // add histology @@ -124,9 +131,42 @@ public void testSchemaLookup() throws IOException { schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, data.getInputs()).execute().body(); assertThat(schemas).hasSize(1).extracting("id").contains("nasopharynx"); - // test with the CsStaging class + // test with the CS schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new CsSchemaLookup("C111", "8000", "010").getInputs()).execute().body(); assertThat(schemas).hasSize(1).extracting("id").contains("nasopharynx"); + + // test with the TNM + schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new TnmSchemaLookup("C680", "8000").getInputs()).execute().body(); + assertThat(schemas).hasSize(1).extracting("id").contains("urethra"); + + // test with the EOD + schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new EodSchemaLookup("C680", "8000").getInputs()).execute().body(); + assertThat(schemas).hasSize(1).extracting("id").contains("urethra"); + + Map values = new HashMap<>(); + values.put(PRIMARY_SITE_KEY, "C680"); + values.put(HISTOLOGY_KEY, "8000"); + SchemaLookup schemaLookup = new SchemaLookup(values); + assertThat(schemaLookup.getInput(PRIMARY_SITE_KEY)).isEqualTo("C680"); + assertThat(schemaLookup.getSite()).isEqualTo("C680"); + assertThat(schemaLookup.getHistology()).isEqualTo("8000"); + assertThat(schemaLookup.hasDiscriminator()).isFalse(); + + assertThat(schemaLookup).isEqualTo(new SchemaLookup("C680", "8000")); + + // test invalid input + CsSchemaLookup csLookup = new CsSchemaLookup(); + csLookup.setSite("C111"); + csLookup.setHistology("8000"); + csLookup.setInput(CsStagingData.SSF25_KEY, "010"); + assertThatExceptionOfType(IllegalStateException.class) + .isThrownBy(() -> csLookup.setInput("bad_key", "1")) + .withMessageContaining("is not allowed for lookups"); + assertThat(csLookup.hasDiscriminator()).isEqualTo(true); + + // test clearning inpuyts + schemaLookup.clearInputs(); + assertThat(schemaLookup.getInput(PRIMARY_SITE_KEY)).isNull(); } @Test From 0809c8aeea01871389138379b9f707d46a95b03c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 09:12:26 -0400 Subject: [PATCH 182/243] Improve coverage --- .../java/com/imsweb/seerapi/client/staging/StagingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 3593e21..0071f21 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -162,7 +162,7 @@ public void testSchemaLookup() throws IOException { assertThatExceptionOfType(IllegalStateException.class) .isThrownBy(() -> csLookup.setInput("bad_key", "1")) .withMessageContaining("is not allowed for lookups"); - assertThat(csLookup.hasDiscriminator()).isEqualTo(true); + assertThat(csLookup.hasDiscriminator()).isTrue(); // test clearning inpuyts schemaLookup.clearInputs(); From d0cb25650e6303a1de3cee719605b5da4b7331d7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 09:51:09 -0400 Subject: [PATCH 183/243] Improve coverage --- build.gradle | 1 + .../imsweb/seerapi/client/disease/DiseaseTest.java | 12 ++++++++++++ .../imsweb/seerapi/client/glossary/GlossaryTest.java | 11 +++++++++++ .../java/com/imsweb/seerapi/client/rx/RxTest.java | 12 ++++++++++++ 4 files changed, 36 insertions(+) diff --git a/build.gradle b/build.gradle index 2b7b23a..0af450a 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.23.1' + testImplementation 'com.google.code.bean-matchers:bean-matchers:0.13' } jar { diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 9c37942..a1c5a0c 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -7,12 +7,16 @@ import java.util.Collections; import java.util.List; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -274,4 +278,12 @@ public void testDiseaseChangelog() throws IOException { assertNull(entry.getNewVersion()); } + @Test + public void testBeans() { + MatcherAssert.assertThat(DiseaseHistoryEvent.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + } + } diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index ba8e886..faabecf 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -9,6 +9,8 @@ import java.util.List; import java.util.Set; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; @@ -16,6 +18,8 @@ import com.imsweb.seerapi.client.publishable.PublishableSearch; import com.imsweb.seerapi.client.shared.KeywordMatch; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static com.imsweb.seerapi.client.glossary.Glossary.Category.GENERAL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -168,4 +172,11 @@ public void testGlossaryMatch() throws IOException { assertEquals(0, matches.size()); } + @Test + public void testBeans() { + MatcherAssert.assertThat(GlossaryHistoryEvent.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + } } diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 924bc91..6186b58 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -9,12 +9,16 @@ import java.util.HashSet; import java.util.List; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -154,4 +158,12 @@ public void testRxSearchIterate() throws IOException { search.setOffset(search.getOffset() + results.getResults().size()); } } + + @Test + public void testBeans() { + MatcherAssert.assertThat(RxHistoryEvent.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + } } From a4d5308c2767fffd2565ca3844ef428d4c5b45be Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 10:23:02 -0400 Subject: [PATCH 184/243] Improve coverage --- .../client/disease/YearRangeBoolean.java | 20 ------- .../seerapi/client/staging/StagingCode.java | 57 ------------------ .../client/staging/StagingEndpoint.java | 59 ------------------- .../seerapi/client/disease/DiseaseTest.java | 8 +++ .../seerapi/client/glossary/GlossaryTest.java | 20 +++++++ .../seerapi/client/hcpcs/mph/MphTest.java | 13 ++++ .../com/imsweb/seerapi/client/rx/RxTest.java | 4 ++ .../seerapi/client/staging/StagingTest.java | 22 +++++++ 8 files changed, 67 insertions(+), 136 deletions(-) delete mode 100644 src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java delete mode 100644 src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java delete mode 100644 src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java diff --git a/src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java b/src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java deleted file mode 100644 index 03456bf..0000000 --- a/src/main/java/com/imsweb/seerapi/client/disease/YearRangeBoolean.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2013 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.disease; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class YearRangeBoolean extends YearRange { - - @JsonProperty("value") - protected Boolean _value; - - public Boolean getValue() { - return _value; - } - - public void setValue(Boolean value) { - _value = value; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java deleted file mode 100644 index 6340bb7..0000000 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingCode.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.imsweb.seerapi.client.staging; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -@JsonPropertyOrder({"table", "code", "is_valid"}) -public class StagingCode { - - protected String _table; - protected String _code; - protected Boolean _isValid; - - /** - * Default constructor - */ - public StagingCode() { - setIsValid(false); - } - - /** - * @param table Table identifier - * @param code Code - * @param isValid Boolean indicating whether code is value - */ - public StagingCode(String table, String code, Boolean isValid) { - setTable(table); - setCode(code); - setIsValid(isValid); - } - - @JsonProperty("table") - public String getTable() { - return _table; - } - - public void setTable(String table) { - _table = table; - } - - @JsonProperty("code") - public String getCode() { - return _code; - } - - public void setCode(String code) { - _code = code; - } - - @JsonProperty("is_valid") - public Boolean getIsValid() { - return _isValid; - } - - public void setIsValid(Boolean isValid) { - _isValid = isValid; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java deleted file mode 100644 index d9328ef..0000000 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingEndpoint.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2014 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.staging; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -@JsonPropertyOrder({"type", "value", "result_key"}) -public class StagingEndpoint { - - private EndpointType _type; - private String _value; - private String _resultKey; - - enum EndpointType { - JUMP, - VALUE, - MATCH, - STOP, - ERROR - } - - public StagingEndpoint() { - } - - public StagingEndpoint(EndpointType type, String value) { - _type = type; - _value = value; - } - - @JsonProperty("type") - public EndpointType getType() { - return _type; - } - - public void setType(EndpointType type) { - _type = type; - } - - @JsonProperty("value") - public String getValue() { - return _value; - } - - public void setValue(String value) { - _value = value; - } - - @JsonProperty("result_key") - public String getResultKey() { - return _resultKey; - } - - public void setResultKey(String resultKey) { - _resultKey = resultKey; - } - -} diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index a1c5a0c..856879a 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -284,6 +284,14 @@ public void testBeans() { hasValidBeanConstructor(), hasValidGettersAndSetters() )); + MatcherAssert.assertThat(DiseaseSearchResults.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + MatcherAssert.assertThat(DiseaseSource.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); } } diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index faabecf..45a9559 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -174,9 +174,29 @@ public void testGlossaryMatch() throws IOException { @Test public void testBeans() { + MatcherAssert.assertThat(GlossaryResource.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + MatcherAssert.assertThat(GlossaryChangelogEntry.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + MatcherAssert.assertThat(GlossarySearchResults.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + MatcherAssert.assertThat(GlossaryChangelogResults.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); MatcherAssert.assertThat(GlossaryHistoryEvent.class, CoreMatchers.allOf( hasValidBeanConstructor(), hasValidGettersAndSetters() )); + MatcherAssert.assertThat(KeywordMatch.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); } } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 6cad0e1..4974e36 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -2,6 +2,8 @@ import java.io.IOException; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; @@ -10,8 +12,11 @@ import com.imsweb.seerapi.client.mph.MphInput; import com.imsweb.seerapi.client.mph.MphInputPair; import com.imsweb.seerapi.client.mph.MphOutput; +import com.imsweb.seerapi.client.mph.MphRule; import com.imsweb.seerapi.client.mph.MphService; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -147,4 +152,12 @@ public void testInvalidInput() throws IOException { _MPH.mph(new MphInputPair(i1, i2)).execute().body(); } + @Test + public void testBeans() { + MatcherAssert.assertThat(MphRule.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + } + } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 6186b58..3bcd61e 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -165,5 +165,9 @@ public void testBeans() { hasValidBeanConstructor(), hasValidGettersAndSetters() )); + MatcherAssert.assertThat(RxSearchResults.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); } } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 0071f21..c1ab42a 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -10,10 +10,14 @@ import java.util.Map; import java.util.Set; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.disease.DateRange; +import com.imsweb.seerapi.client.disease.DateRangeString; import com.imsweb.seerapi.client.glossary.Glossary.Category; import com.imsweb.seerapi.client.shared.KeywordMatch; import com.imsweb.seerapi.client.staging.cs.CsSchemaLookup; @@ -31,6 +35,8 @@ import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmOutput; import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmStagingInputBuilder; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static com.imsweb.seerapi.client.staging.StagingData.HISTOLOGY_KEY; import static com.imsweb.seerapi.client.staging.StagingData.PRIMARY_SITE_KEY; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_M; @@ -547,4 +553,20 @@ public void testStagingMetadata() throws IOException { assertThat(mgmt.getMetadata()).extracting("name").containsExactlyInAnyOrder("COC_REQUIRED", "SEER_REQUIRED", "SSDI"); } + @Test + public void testBeans() { + MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + MatcherAssert.assertThat(DateRange.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + MatcherAssert.assertThat(DateRangeString.class, CoreMatchers.allOf( + hasValidBeanConstructor(), + hasValidGettersAndSetters() + )); + } + } From e02347baa53dc2343fcdfd3beb745a8bb84b64cb Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 10:50:50 -0400 Subject: [PATCH 185/243] Improve coverage --- .../imsweb/seerapi/client/ndc/NdcPackage.java | 15 ++++ .../imsweb/seerapi/client/ndc/NdcProduct.java | 84 +++++++++++++++++++ .../imsweb/seerapi/client/ndc/NdcSearch.java | 6 +- .../seerapi/client/disease/DiseaseTest.java | 21 ++--- .../seerapi/client/glossary/GlossaryTest.java | 33 ++------ .../seerapi/client/hcpcs/mph/MphTest.java | 7 +- .../imsweb/seerapi/client/ndc/NdcTest.java | 12 +++ .../com/imsweb/seerapi/client/rx/RxTest.java | 15 ++-- .../client/siterecode/SiteRecodeTest.java | 9 ++ .../seerapi/client/staging/StagingTest.java | 35 +++++--- .../seerapi/client/surgery/SurgeryTest.java | 10 +++ 11 files changed, 184 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java index 8d0f2b5..5521536 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcPackage.java @@ -22,16 +22,31 @@ public String getCode() { return code; } + public void setCode(String code) { + this.code = code; + } + public String getDescription() { return description; } + public void setDescription(String description) { + this.description = description; + } + public String getStartMarketingDate() { return startMarketingDate; } + public void setStartMarketingDate(String startMarketingDate) { + this.startMarketingDate = startMarketingDate; + } + public String getEndMarketingDate() { return endMarketingDate; } + public void setEndMarketingDate(String endMarketingDate) { + this.endMarketingDate = endMarketingDate; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java index 6bba746..e9510d3 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcProduct.java @@ -61,83 +61,167 @@ public String getNdc() { return ndc; } + public void setNdc(String ndc) { + this.ndc = ndc; + } + public String getTypeName() { return typeName; } + public void setTypeName(String typeName) { + this.typeName = typeName; + } + public String getProprietaryName() { return proprietaryName; } + public void setProprietaryName(String proprietaryName) { + this.proprietaryName = proprietaryName; + } + public String getProprietaryNameSuffix() { return proprietaryNameSuffix; } + public void setProprietaryNameSuffix(String proprietaryNameSuffix) { + this.proprietaryNameSuffix = proprietaryNameSuffix; + } + public List getNonProprietaryName() { return nonProprietaryName; } + public void setNonProprietaryName(List nonProprietaryName) { + this.nonProprietaryName = nonProprietaryName; + } + public String getDosageFormName() { return dosageFormName; } + public void setDosageFormName(String dosageFormName) { + this.dosageFormName = dosageFormName; + } + public List getRouteName() { return routeName; } + public void setRouteName(List routeName) { + this.routeName = routeName; + } + public String getStartMarketingDate() { return startMarketingDate; } + public void setStartMarketingDate(String startMarketingDate) { + this.startMarketingDate = startMarketingDate; + } + public String getEndMarketingDate() { return endMarketingDate; } + public void setEndMarketingDate(String endMarketingDate) { + this.endMarketingDate = endMarketingDate; + } + public String getMarketingCategoryName() { return marketingCategoryName; } + public void setMarketingCategoryName(String marketingCategoryName) { + this.marketingCategoryName = marketingCategoryName; + } + public String getApplicationNumber() { return applicationNumber; } + public void setApplicationNumber(String applicationNumber) { + this.applicationNumber = applicationNumber; + } + public String getLabelerName() { return labelerName; } + public void setLabelerName(String labelerName) { + this.labelerName = labelerName; + } + public String getDeaSchedule() { return deaSchedule; } + public void setDeaSchedule(String deaSchedule) { + this.deaSchedule = deaSchedule; + } + public List getSubstances() { return substances; } + public void setSubstances(List substances) { + this.substances = substances; + } + public List getPharmClass() { return pharmClass; } + public void setPharmClass(List pharmClass) { + this.pharmClass = pharmClass; + } + public List getPackages() { return packages; } + public void setPackages(List packages) { + this.packages = packages; + } + public Date getDateAdded() { return dateAdded; } + public void setDateAdded(Date dateAdded) { + this.dateAdded = dateAdded; + } + public Date getDateModified() { return dateModified; } + public void setDateModified(Date dateModified) { + this.dateModified = dateModified; + } + public Date getDateRemoved() { return dateRemoved; } + public void setDateRemoved(Date dateRemoved) { + this.dateRemoved = dateRemoved; + } + public NdcSeerInfo getSeerInfo() { return seerInfo; } + public void setSeerInfo(NdcSeerInfo seerInfo) { + this.seerInfo = seerInfo; + } + public Double getScore() { return score; } + + public void setScore(Double score) { + this.score = score; + } } diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java index edba4f2..37441c8 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSearch.java @@ -50,7 +50,7 @@ public Boolean getIncludeRemoved() { } public void setIncludeRemoved(Boolean includeRemoved) { - this._includeRemoved = includeRemoved; + _includeRemoved = includeRemoved; } public String getAddedSince() { @@ -97,8 +97,8 @@ public String getOrder() { return _order; } - public void setOrder(String orderBy) { - _order = orderBy; + public void setOrder(String order) { + _order = order; } /** diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 856879a..dd99177 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -280,18 +280,15 @@ public void testDiseaseChangelog() throws IOException { @Test public void testBeans() { - MatcherAssert.assertThat(DiseaseHistoryEvent.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(DiseaseSearchResults.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(DiseaseSource.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); + MatcherAssert.assertThat(Disease.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseChangelogResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseHistoryEvent.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseSearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DiseaseSource.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SiteCategory.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index 45a9559..dea1cf5 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -174,29 +174,14 @@ public void testGlossaryMatch() throws IOException { @Test public void testBeans() { - MatcherAssert.assertThat(GlossaryResource.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(GlossaryChangelogEntry.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(GlossarySearchResults.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(GlossaryChangelogResults.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(GlossaryHistoryEvent.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(KeywordMatch.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); + MatcherAssert.assertThat(Glossary.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryResource.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossarySearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryChangelogResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(GlossaryHistoryEvent.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(KeywordMatch.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 4974e36..77e5cf5 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -154,10 +154,9 @@ public void testInvalidInput() throws IOException { @Test public void testBeans() { - MatcherAssert.assertThat(MphRule.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); + MatcherAssert.assertThat(MphRule.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(MphInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(MphInputPair.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 14fbc2f..e47b6ae 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.util.List; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; @@ -14,6 +16,8 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.ndc.NdcSeerInfo.Category; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.assertj.core.api.Assertions.assertThat; @SuppressWarnings("ConstantConditions") @@ -149,4 +153,12 @@ public void testNdcHasSeerInfo() throws IOException { assertThat(totalCount).isEqualTo(withCount + withoutCount); } + @Test + public void testBeans() { + MatcherAssert.assertThat(NdcProduct.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcPackage.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcSubstance.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(NdcSearch.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + + } } diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 3bcd61e..42d16cd 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -161,13 +161,12 @@ public void testRxSearchIterate() throws IOException { @Test public void testBeans() { - MatcherAssert.assertThat(RxHistoryEvent.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(RxSearchResults.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); + MatcherAssert.assertThat(Rx.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxChangelogResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxHistoryEvent.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(RxSearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index 30cd173..980cf92 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -5,6 +5,8 @@ import java.io.IOException; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; @@ -14,6 +16,8 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.shared.Version; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -68,4 +72,9 @@ public void testSiteRecode() throws IOException { assertEquals("33011", recode.getSiteGroup()); } + @Test + public void testBeans() { + MatcherAssert.assertThat(Version.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } + } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index c1ab42a..51cce56 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -18,6 +18,9 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.disease.DateRange; import com.imsweb.seerapi.client.disease.DateRangeString; +import com.imsweb.seerapi.client.disease.YearRange; +import com.imsweb.seerapi.client.disease.YearRangeInteger; +import com.imsweb.seerapi.client.disease.YearRangeString; import com.imsweb.seerapi.client.glossary.Glossary.Category; import com.imsweb.seerapi.client.shared.KeywordMatch; import com.imsweb.seerapi.client.staging.cs.CsSchemaLookup; @@ -37,6 +40,7 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSettersExcluding; import static com.imsweb.seerapi.client.staging.StagingData.HISTOLOGY_KEY; import static com.imsweb.seerapi.client.staging.StagingData.PRIMARY_SITE_KEY; import static com.imsweb.seerapi.client.staging.cs.CsStagingData.CsOutput.AJCC6_M; @@ -555,18 +559,25 @@ public void testStagingMetadata() throws IOException { @Test public void testBeans() { - MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(DateRange.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); - MatcherAssert.assertThat(DateRangeString.class, CoreMatchers.allOf( - hasValidBeanConstructor(), - hasValidGettersAndSetters() - )); + MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSettersExcluding("production", "beta", "development"))); + MatcherAssert.assertThat(StagingSchema.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaInfo.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingTable.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingTablePath.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingColumnDefinition.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingSchemaOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingKeyMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingKeyValue.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(YearRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(YearRangeString.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(YearRangeInteger.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DateRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(DateRangeString.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java index 1c49860..3ec9c38 100644 --- a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java @@ -6,11 +6,15 @@ import java.io.IOException; import java.util.List; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; import com.imsweb.seerapi.client.SeerApi; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.assertj.core.api.Assertions.assertThat; public class SurgeryTest { @@ -51,4 +55,10 @@ public void testSiteSpecificSurgeryTable() throws IOException { assertThat(table).isNotNull(); assertThat(table.getTitle()).isEqualTo("Oral Cavity"); } + + @Test + public void testBeans() { + MatcherAssert.assertThat(SurgeryTable.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SurgeryRow.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } } From 8f541bccf068e3b813b30c1b51f14561a1ef9bc1 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 11:00:15 -0400 Subject: [PATCH 186/243] Finishing up coverage improvements --- .../seerapi/client/ndc/NdcSeerInfo.java | 28 +++++++++++++++++++ .../seerapi/client/disease/DiseaseTest.java | 3 ++ .../seerapi/client/hcpcs/mph/MphTest.java | 1 + .../imsweb/seerapi/client/ndc/NdcTest.java | 2 +- .../client/siterecode/SiteRecodeTest.java | 1 + .../seerapi/client/staging/StagingTest.java | 2 ++ 6 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java index 68c0cd0..a8c5d8f 100644 --- a/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java +++ b/src/main/java/com/imsweb/seerapi/client/ndc/NdcSeerInfo.java @@ -33,30 +33,58 @@ public String getSeerRxId() { return seerRxId; } + public void setSeerRxId(String seerRxId) { + this.seerRxId = seerRxId; + } + public List getCategories() { return categories; } + public void setCategories(List categories) { + this.categories = categories; + } + public String getMajorDrugClass() { return majorDrugClass; } + public void setMajorDrugClass(String majorDrugClass) { + this.majorDrugClass = majorDrugClass; + } + public String getMinorDrugClass() { return minorDrugClass; } + public void setMinorDrugClass(String minorDrugClass) { + this.minorDrugClass = minorDrugClass; + } + public Boolean getOrphanDrug() { return orphanDrug; } + public void setOrphanDrug(Boolean orphanDrug) { + this.orphanDrug = orphanDrug; + } + public Boolean getExclusiveAgent() { return exclusiveAgent; } + public void setExclusiveAgent(Boolean exclusiveAgent) { + this.exclusiveAgent = exclusiveAgent; + } + public Date getDateModified() { return dateModified; } + public void setDateModified(Date dateModified) { + this.dateModified = dateModified; + } + // drug categories public enum Category { HORMONAL_THERAPY, diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index dd99177..490574c 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -289,6 +289,9 @@ public void testBeans() { MatcherAssert.assertThat(DiseaseSearchResults.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(DiseaseSource.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(SiteCategory.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SamePrimaries.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(PrimarySite.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SiteRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 77e5cf5..799b7f6 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -157,6 +157,7 @@ public void testBeans() { MatcherAssert.assertThat(MphRule.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(MphInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(MphInputPair.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(MphOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index e47b6ae..0825c97 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -159,6 +159,6 @@ public void testBeans() { MatcherAssert.assertThat(NdcPackage.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(NdcSubstance.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(NdcSearch.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); - + MatcherAssert.assertThat(NdcSeerInfo.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index 980cf92..416320a 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -75,6 +75,7 @@ public void testSiteRecode() throws IOException { @Test public void testBeans() { MatcherAssert.assertThat(Version.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(SiteRecode.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 51cce56..5810070 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -559,6 +559,7 @@ public void testStagingMetadata() throws IOException { @Test public void testBeans() { + MatcherAssert.assertThat(StagingAlgorithm.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSettersExcluding("production", "beta", "development"))); MatcherAssert.assertThat(StagingSchema.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); @@ -573,6 +574,7 @@ public void testBeans() { MatcherAssert.assertThat(StagingMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingKeyMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingKeyValue.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingError.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(YearRange.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(YearRangeString.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(YearRangeInteger.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); From d2208adf1ba4dcbc116ec7d2b0e6fcc0ba1cef72 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 11:02:07 -0400 Subject: [PATCH 187/243] Finishing up coverage improvements --- .../java/com/imsweb/seerapi/client/staging/StagingTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 5810070..8f4f3c2 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -39,6 +39,7 @@ import com.imsweb.seerapi.client.staging.tnm.TnmStagingData.TnmStagingInputBuilder; import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanEquals; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSettersExcluding; import static com.imsweb.seerapi.client.staging.StagingData.HISTOLOGY_KEY; @@ -560,7 +561,7 @@ public void testStagingMetadata() throws IOException { @Test public void testBeans() { MatcherAssert.assertThat(StagingAlgorithm.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); - MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters(), hasValidBeanEquals())); MatcherAssert.assertThat(StagingVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSettersExcluding("production", "beta", "development"))); MatcherAssert.assertThat(StagingSchema.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingSchemaInfo.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); From 2e667cca11c3b25b7c35d063029bc46aab02f748 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 11:09:44 -0400 Subject: [PATCH 188/243] Finishing up coverage improvements --- .../imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java | 9 +++++++++ .../com/imsweb/seerapi/client/staging/StagingTest.java | 1 + 2 files changed, 10 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java index 6466eb8..91b5889 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -6,6 +6,8 @@ import java.util.Map; import java.util.Objects; +import org.hamcrest.CoreMatchers; +import org.hamcrest.MatcherAssert; import org.junit.BeforeClass; import org.junit.Test; @@ -15,6 +17,8 @@ import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.hcpcs.Hcpcs.Category; +import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; +import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; @@ -90,4 +94,9 @@ public void testSearch() throws IOException { params.put("category", Category.IMMUNOTHERAPY.toString()); assertThat(_HCPCS.search(params).execute().body()).isEmpty(); } + + @Test + public void testBeans() { + MatcherAssert.assertThat(Hcpcs.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 8f4f3c2..a63a614 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -572,6 +572,7 @@ public void testBeans() { MatcherAssert.assertThat(StagingColumnDefinition.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingSchemaInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingSchemaOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); + MatcherAssert.assertThat(StagingData.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingKeyMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingKeyValue.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); From 3b09b088b05bccc537d1eebe535c841d073f812d Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 8 Jun 2022 11:11:46 -0400 Subject: [PATCH 189/243] Finishing up coverage improvements --- .../imsweb/seerapi/client/hcpcs/Hcpcs.java | 60 +++++++++++++++++++ .../seerapi/client/staging/StagingTest.java | 1 - 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java b/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java index c9b0970..51876a6 100644 --- a/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java +++ b/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java @@ -48,62 +48,122 @@ public String getHcpcsCode() { return hcpcsCode; } + public void setHcpcsCode(String hcpcsCode) { + this.hcpcsCode = hcpcsCode; + } + public String getGenericName() { return genericName; } + public void setGenericName(String genericName) { + this.genericName = genericName; + } + public List getBrandNames() { return brandNames; } + public void setBrandNames(List brandNames) { + this.brandNames = brandNames; + } + public String getStrength() { return strength; } + public void setStrength(String strength) { + this.strength = strength; + } + public String getFdaApprovalYear() { return fdaApprovalYear; } + public void setFdaApprovalYear(String fdaApprovalYear) { + this.fdaApprovalYear = fdaApprovalYear; + } + public String getFdaDiscontinuationYear() { return fdaDiscontinuationYear; } + public void setFdaDiscontinuationYear(String fdaDiscontinuationYear) { + this.fdaDiscontinuationYear = fdaDiscontinuationYear; + } + public String getCmsApprovalDate() { return cmsApprovalDate; } + public void setCmsApprovalDate(String cmsApprovalDate) { + this.cmsApprovalDate = cmsApprovalDate; + } + public String getCmsDiscontinuationDate() { return cmsDiscontinuationDate; } + public void setCmsDiscontinuationDate(String cmsDiscontinuationDate) { + this.cmsDiscontinuationDate = cmsDiscontinuationDate; + } + public List getCategories() { return categories; } + public void setCategories(List categories) { + this.categories = categories; + } + public String getMajorDrugClass() { return majorDrugClass; } + public void setMajorDrugClass(String majorDrugClass) { + this.majorDrugClass = majorDrugClass; + } + public String getMinorDrugClass() { return minorDrugClass; } + public void setMinorDrugClass(String minorDrugClass) { + this.minorDrugClass = minorDrugClass; + } + public Boolean getOral() { return oral; } + public void setOral(Boolean oral) { + this.oral = oral; + } + public Date getDateAdded() { return dateAdded; } + public void setDateAdded(Date dateAdded) { + this.dateAdded = dateAdded; + } + public Date getDateModified() { return dateModified; } + public void setDateModified(Date dateModified) { + this.dateModified = dateModified; + } + public Double getScore() { return score; } + public void setScore(Double score) { + this.score = score; + } + // drug categories public enum Category { HORMONAL_THERAPY, diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index a63a614..8f4f3c2 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -572,7 +572,6 @@ public void testBeans() { MatcherAssert.assertThat(StagingColumnDefinition.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingSchemaInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingSchemaOutput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); - MatcherAssert.assertThat(StagingData.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingKeyMapping.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingKeyValue.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); From f9a0686e85b90609c8d80c59ee7ae1b6b1812f76 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 9 Jun 2022 14:05:48 -0400 Subject: [PATCH 190/243] Update okhttp to fix vulnerability --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 0af450a..d225342 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,9 @@ dependencies { api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' + // retrofit will not update these dependencies to fix vulnerabilities + api 'com.squareup.okhttp3:okhttp:4.9.3' + // newer version of dependency to fix vulnerability until converter-jackson is updated api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' From 976c3485d89ed57a2b222ab8c3e5458530aa55d3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 9 Jun 2022 14:13:44 -0400 Subject: [PATCH 191/243] Fix Spotbugs --- .../java/com/imsweb/seerapi/client/ErrorInterceptor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java b/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java index a5f60f2..0b2fda3 100644 --- a/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java +++ b/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java @@ -4,6 +4,9 @@ package com.imsweb.seerapi.client; import java.io.IOException; +import java.util.Objects; + +import org.jetbrains.annotations.NotNull; import com.fasterxml.jackson.databind.ObjectMapper; @@ -15,6 +18,7 @@ */ public class ErrorInterceptor implements Interceptor { + @NotNull @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); @@ -24,7 +28,7 @@ public Response intercept(Chain chain) throws IOException { ErrorResponse error = null; if (response.body() != null) { try { - error = new ObjectMapper().readValue(response.body().byteStream(), ErrorResponse.class); + error = new ObjectMapper().readValue(Objects.requireNonNull(response.body()).byteStream(), ErrorResponse.class); } catch (IOException e) { // sometimes the error message is not right format (like for 404 errors) From e7d0b2eada1fceec419237bbdbe47a6640f10e20 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 9 Jun 2022 14:33:55 -0400 Subject: [PATCH 192/243] Fix Spotbugs --- .../com/imsweb/seerapi/client/ErrorInterceptor.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java b/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java index 0b2fda3..35476e4 100644 --- a/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java +++ b/src/main/java/com/imsweb/seerapi/client/ErrorInterceptor.java @@ -4,7 +4,6 @@ package com.imsweb.seerapi.client; import java.io.IOException; -import java.util.Objects; import org.jetbrains.annotations.NotNull; @@ -12,6 +11,7 @@ import okhttp3.Interceptor; import okhttp3.Response; +import okhttp3.ResponseBody; /** * Interceptor to catch all non-200 responses and convert them to exceptions. @@ -24,11 +24,13 @@ public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); if (response.code() != 200) { - // convert body to error response ErrorResponse error = null; - if (response.body() != null) { + + // convert body to error response + ResponseBody body = response.body(); + if (body != null) { try { - error = new ObjectMapper().readValue(Objects.requireNonNull(response.body()).byteStream(), ErrorResponse.class); + error = new ObjectMapper().readValue(body.byteStream(), ErrorResponse.class); } catch (IOException e) { // sometimes the error message is not right format (like for 404 errors) From e2279378f0607932b1fe81c0f6d297004aa17392 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 9 Jun 2022 14:47:20 -0400 Subject: [PATCH 193/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 504ca02..4be664e 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.0 + 5.1 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.0' +compile 'com.imsweb:seerapi-client-java:5.1' ``` ## Usage diff --git a/build.gradle b/build.gradle index d225342..fa5810b 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.0' +version = '5.1' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 60df5cb8a3182419f5dcd19fcd7e6224f89449c0 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 7 Jul 2022 09:07:11 -0400 Subject: [PATCH 194/243] Update dependencies --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index fa5810b..53b95fa 100644 --- a/build.gradle +++ b/build.gradle @@ -2,14 +2,14 @@ plugins { id 'java-library' id 'checkstyle' id 'jacoco' - id "com.github.spotbugs" version "5.0.7" + id "com.github.spotbugs" version "5.0.9" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '3.2.0' id "com.github.ben-manes.versions" version "0.42.0" id 'org.sonatype.gradle.plugins.scan' version '2.3.0' - id "org.sonarqube" version "3.3" + id "org.sonarqube" version "3.4.0.2513" } group = 'com.imsweb' @@ -34,13 +34,13 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.7.0' + spotbugs 'com.github.spotbugs:spotbugs:4.7.1' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' // retrofit will not update these dependencies to fix vulnerabilities - api 'com.squareup.okhttp3:okhttp:4.9.3' + api 'com.squareup.okhttp3:okhttp:4.10.0' // newer version of dependency to fix vulnerability until converter-jackson is updated api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' From 7a8bece4e2e825276ed88a8b1f1bd019cbabcffa Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 7 Jul 2022 10:00:11 -0400 Subject: [PATCH 195/243] Update dependencies --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 53b95fa..8825e02 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,7 @@ dependencies { // retrofit will not update these dependencies to fix vulnerabilities api 'com.squareup.okhttp3:okhttp:4.10.0' + api 'com.squareup.okio:okio:3.2.0' // newer version of dependency to fix vulnerability until converter-jackson is updated api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' From e1597da997fbcd88e90ec3171117c5671db0015c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 27 Jul 2022 16:21:29 -0400 Subject: [PATCH 196/243] Add support for HCPCS description SEER*API does not support this yet but will very soon. --- .../java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java | 12 +++++++++++- .../seerapi/client/hcpcs/HcpcsServiceTest.java | 11 +++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java b/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java index 51876a6..13469da 100644 --- a/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java +++ b/src/main/java/com/imsweb/seerapi/client/hcpcs/Hcpcs.java @@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder({"hcpcs_code", "generic_name", "brand_names", "strength", "fda_approval_year", "fda_discontinuation_year", "cms_approval_date", +@JsonPropertyOrder({"hcpcs_code", "generic_name", "description", "brand_names", "strength", "fda_approval_year", "fda_discontinuation_year", "cms_approval_date", "cms_discontinuation_date", "categories", "major_drug_class", "minor_drug_class", "oral", "date_added", "date_modified", "score"}) public class Hcpcs { @@ -17,6 +17,8 @@ public class Hcpcs { private String hcpcsCode; @JsonProperty("generic_name") private String genericName; + @JsonProperty("description") + private String description; @JsonProperty("brand_names") private List brandNames; @JsonProperty("strength") @@ -60,6 +62,14 @@ public void setGenericName(String genericName) { this.genericName = genericName; } + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + public List getBrandNames() { return brandNames; } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java index 91b5889..fea3c2f 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -54,6 +54,17 @@ public void testGetProcedureByCode() throws IOException { assertThatExceptionOfType(NotFoundException.class) .isThrownBy(() -> _HCPCS.getProcedure("bad_code").execute()) .withMessage("HCPCS code '%s' does not exist.", "bad_code"); + + // test the new description field and + proc = _HCPCS.getProcedure("G6015").execute().body(); + assertThat(proc).isNotNull(); + assertThat(proc.getDescription()).contains("temporally modulated beams, binary, dynamic mlc, per treatment session"); + + // verify multiple categories are supported + proc = _HCPCS.getProcedure("A9545").execute().body(); + assertThat(proc).isNotNull(); + assertThat(proc.getCategories()).containsExactlyInAnyOrder(Category.IMMUNOTHERAPY, Category.RADIOPHARMACEUTICAL); + } @Test From 7d2a07a5199cdb2b33cdd6191cbcadcaaef897da Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 28 Jul 2022 08:16:09 -0400 Subject: [PATCH 197/243] Prepare for release --- README.md | 4 ++-- build.gradle | 6 +++--- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4be664e..428f152 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.1 + 5.2 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.1' +compile 'com.imsweb:seerapi-client-java:5.2' ``` ## Usage diff --git a/build.gradle b/build.gradle index 8825e02..fa55d43 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.1' +version = '5.2' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { @@ -48,7 +48,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.23.1' - testImplementation 'com.google.code.bean-matchers:bean-matchers:0.13' + testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } jar { @@ -106,7 +106,7 @@ ossIndexAudit { } wrapper { - gradleVersion = '7.4.2' + gradleVersion = '7.5' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 92f06b5..2ec77e5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 7ac5e6bd722c88fca383559b09dc39e418d2fb72 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 28 Jul 2022 09:31:58 -0400 Subject: [PATCH 198/243] Continue after failing unit tests --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index fa55d43..844963a 100644 --- a/build.gradle +++ b/build.gradle @@ -75,6 +75,11 @@ tasks.withType(Javadoc) { options.addStringOption('charSet', 'UTF-8') } +// make sure that Sonarqube still runs even if there are failing tests +test { + ignoreFailures = true +} + checkstyle { toolVersion '8.29' configFile = file("config/checkstyle/checkstyle.xml") From 140f177b9717b50aba164d15e8b43716cb74840a Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 28 Jul 2022 09:39:56 -0400 Subject: [PATCH 199/243] Try this a different way --- .github/workflows/integration.yml | 2 +- build.gradle | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 1c787bc..c237ac4 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -33,5 +33,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - chmod +x gradlew + chmod +x --continue gradlew ./gradlew build sonarqube diff --git a/build.gradle b/build.gradle index 844963a..fa55d43 100644 --- a/build.gradle +++ b/build.gradle @@ -75,11 +75,6 @@ tasks.withType(Javadoc) { options.addStringOption('charSet', 'UTF-8') } -// make sure that Sonarqube still runs even if there are failing tests -test { - ignoreFailures = true -} - checkstyle { toolVersion '8.29' configFile = file("config/checkstyle/checkstyle.xml") From 771054665866b0b66bf8581bba15b2bb0b27bbc9 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 28 Jul 2022 09:41:31 -0400 Subject: [PATCH 200/243] Try this a different way --- .github/workflows/integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index c237ac4..374a80c 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -33,5 +33,5 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | - chmod +x --continue gradlew - ./gradlew build sonarqube + chmod +x gradlew + ./gradlew --continue build sonarqube From 38b532b04b2a822742e559582924335e2eaa814b Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 28 Jul 2022 10:04:48 -0400 Subject: [PATCH 201/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 428f152..3b10954 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.2 + 5.3 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.2' +compile 'com.imsweb:seerapi-client-java:5.3' ``` ## Usage diff --git a/build.gradle b/build.gradle index fa55d43..95692f7 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.2' +version = '5.3' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From e0b8fbb061a1735fa8b086aa622e919709df13b7 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 15 Sep 2022 08:34:26 -0400 Subject: [PATCH 202/243] Dependency updates --- build.gradle | 12 ++++++------ gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 6 ++++++ gradlew.bat | 14 ++++++++------ 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 95692f7..9c9e99f 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,13 @@ plugins { id 'java-library' id 'checkstyle' id 'jacoco' - id "com.github.spotbugs" version "5.0.9" + id "com.github.spotbugs" version "5.0.12" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '3.2.0' id "com.github.ben-manes.versions" version "0.42.0" - id 'org.sonatype.gradle.plugins.scan' version '2.3.0' + id 'org.sonatype.gradle.plugins.scan' version '2.4.1' id "org.sonarqube" version "3.4.0.2513" } @@ -34,7 +34,7 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.7.1' + spotbugs 'com.github.spotbugs:spotbugs:4.7.2' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' @@ -44,7 +44,7 @@ dependencies { api 'com.squareup.okio:okio:3.2.0' // newer version of dependency to fix vulnerability until converter-jackson is updated - api 'com.fasterxml.jackson.core:jackson-databind:2.13.3' + api 'com.fasterxml.jackson.core:jackson-databind:2.13.4' testImplementation 'junit:junit:4.13.2' testImplementation 'org.assertj:assertj-core:3.23.1' @@ -101,12 +101,12 @@ sonarqube { // Nexus vulnerability scan (see https://github.com/sonatype-nexus-community/scan-gradle-plugin) ossIndexAudit { - dependencyGraph = true + outputFormat = 'DEPENDENCY_GRAPH' printBanner = false } wrapper { - gradleVersion = '7.5' + gradleVersion = '7.5.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..249e5832f090a2944b7473328c07c9755baa3196 100644 GIT binary patch delta 10197 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2ec77e5..8fad3f5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..a69d9cb 100644 --- a/gradlew +++ b/gradlew @@ -205,6 +205,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..f127cfd 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal From 1bf1e43dab617a5b62dc5ec40e395748afe3357e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 15 Sep 2022 09:30:55 -0400 Subject: [PATCH 203/243] Convert to JUnit5 --- build.gradle | 8 +++- .../seerapi/client/ObjectMapperTest.java | 27 ++++++----- .../imsweb/seerapi/client/SeerApiTest.java | 24 ++++++---- .../seerapi/client/disease/DiseaseTest.java | 44 ++++++++++-------- .../seerapi/client/glossary/GlossaryTest.java | 32 ++++++------- .../client/hcpcs/HcpcsServiceTest.java | 14 +++--- .../seerapi/client/hcpcs/mph/MphTest.java | 46 ++++++++++++------- .../seerapi/client/naaccr/NaaccrTest.java | 26 +++++------ .../imsweb/seerapi/client/ndc/NdcTest.java | 18 ++++---- .../com/imsweb/seerapi/client/rx/RxTest.java | 28 +++++------ .../client/siterecode/SiteRecodeTest.java | 31 +++++++------ .../seerapi/client/staging/StagingTest.java | 46 +++++++++---------- .../seerapi/client/surgery/SurgeryTest.java | 14 +++--- 13 files changed, 196 insertions(+), 162 deletions(-) diff --git a/build.gradle b/build.gradle index 9c9e99f..7030e06 100644 --- a/build.gradle +++ b/build.gradle @@ -46,7 +46,9 @@ dependencies { // newer version of dependency to fix vulnerability until converter-jackson is updated api 'com.fasterxml.jackson.core:jackson-databind:2.13.4' - testImplementation 'junit:junit:4.13.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' testImplementation 'org.assertj:assertj-core:3.23.1' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } @@ -75,6 +77,10 @@ tasks.withType(Javadoc) { options.addStringOption('charSet', 'UTF-8') } +test { + useJUnitPlatform() +} + checkstyle { toolVersion '8.29' configFile = file("config/checkstyle/checkstyle.xml") diff --git a/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java b/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java index 8380b3e..c8fc18f 100644 --- a/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ObjectMapperTest.java @@ -3,8 +3,7 @@ import java.io.IOException; import java.util.Collections; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.ObjectMapper; @@ -12,28 +11,32 @@ import com.imsweb.seerapi.client.disease.SiteRange; import com.imsweb.seerapi.client.disease.YearRange; -public class ObjectMapperTest { +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ObjectMapperTest { @Test - public void testMapper() throws IOException { + void testMapper() throws IOException { Range range = new Range("10", "40"); ObjectMapper mapper = SeerApi.getMapper(); String json = mapper.writeValueAsString(range); - Assert.assertTrue(json.contains("low")); - Assert.assertFalse(json.contains("lowValue")); + assertTrue(json.contains("low")); + assertFalse(json.contains("lowValue")); // now test reading that back in range = mapper.readValue(json, Range.class); - Assert.assertEquals("10", range.getLowValue()); - Assert.assertEquals("40", range.getHighValue()); + assertEquals("10", range.getLowValue()); + assertEquals("40", range.getHighValue()); } @Test - public void testDiseaseMapping() throws IOException { + void testDiseaseMapping() throws IOException { Disease partial = new Disease(); partial.setType(Disease.Type.HEMATO); @@ -49,13 +52,13 @@ public void testDiseaseMapping() throws IOException { String json = mapper.writeValueAsString(partial); - Assert.assertTrue(json.contains("icdO3_morphology")); - Assert.assertFalse(json.contains("icdO3Morphology")); + assertTrue(json.contains("icdO3_morphology")); + assertFalse(json.contains("icdO3Morphology")); // now test reading that back in partial = mapper.readValue(json, Disease.class); - Assert.assertEquals("9840/3", partial.getIcdO3Morphology()); + assertEquals("9840/3", partial.getIcdO3Morphology()); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java b/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java index e669a9d..38c28be 100644 --- a/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java +++ b/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java @@ -5,18 +5,26 @@ import java.io.IOException; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class SeerApiTest { +import retrofit2.Call; - @Test(expected = NotAuthorizedException.class) - public void testBadApiKeyAndURL() throws IOException { - new SeerApi.Builder().url("https://api.seer.cancer.gov/rest/").apiKey("BAD KEY").connect().siteRecode().version().execute(); +import com.imsweb.seerapi.client.shared.Version; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +class SeerApiTest { + + @Test + void testBadApiKeyAndURL() { + Call call = new SeerApi.Builder().url("https://api.seer.cancer.gov/rest/").apiKey("BAD KEY").connect().siteRecode().version(); + assertThrows(NotAuthorizedException.class, call::execute); } - @Test(expected = NotAuthorizedException.class) - public void testBadApiKey() throws IOException { - new SeerApi.Builder().apiKey("BAD KEY").connect().siteRecode().version().execute(); + @Test + void testBadApiKey() throws IOException { + Call call = new SeerApi.Builder().apiKey("BAD KEY").connect().siteRecode().version(); + assertThrows(NotAuthorizedException.class, call::execute); } } diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 490574c..4ff1dc1 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -9,37 +9,38 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class DiseaseTest { +class DiseaseTest { private static DiseaseService _DISEASE; - @BeforeClass + @BeforeAll public static void setup() { _DISEASE = new SeerApi.Builder().connect().disease(); } @Test - public void testDiseaseTypeCategory() { + void testDiseaseTypeCategory() { assertEquals(Disease.Type.SOLID_TUMOR, Disease.Type.valueOf("SOLID_TUMOR")); } @Test - public void testDiseaseVersions() throws IOException { + void testDiseaseVersions() throws IOException { List versions = _DISEASE.versions().execute().body(); + assertNotNull(versions); assertEquals(1, versions.size()); DiseaseVersion version = versions.get(0); assertEquals("latest", version.getName()); @@ -49,27 +50,30 @@ public void testDiseaseVersions() throws IOException { } @Test - public void testDiseasePrimarySites() throws IOException { + void testDiseasePrimarySites() throws IOException { List sites = _DISEASE.primarySites().execute().body(); + assertNotNull(sites); assertTrue(sites.size() > 0); assertEquals("C000", sites.get(0).getValue()); assertEquals("External upper lip", sites.get(0).getLabel()); } @Test - public void testDiseasePrimarySiteCode() throws IOException { + void testDiseasePrimarySiteCode() throws IOException { List sites = _DISEASE.primarySiteCode("C021").execute().body(); + assertNotNull(sites); assertTrue(sites.size() > 0); assertEquals("C021", sites.get(0).getValue()); assertEquals("Border of tongue", sites.get(0).getLabel()); } @Test - public void testDiseaseSiteCateogires() throws IOException { + void testDiseaseSiteCateogires() throws IOException { List categories = _DISEASE.siteCategories().execute().body(); + assertNotNull(categories); assertTrue(categories.size() > 0); assertEquals("head-and-neck", categories.get(0).getId()); assertEquals("Head and Neck", categories.get(0).getLabel()); @@ -80,7 +84,7 @@ public void testDiseaseSiteCateogires() throws IOException { @SuppressWarnings("java:S5961") @Test - public void testDiseaseById() throws IOException { + void testDiseaseById() throws IOException { Disease disease = _DISEASE.getById("latest", "51f6cf58e3e27c3994bd5408").execute().body(); assertNotNull(disease); @@ -141,7 +145,7 @@ public void testDiseaseById() throws IOException { } @Test - public void testDiseaseSamePrimary() throws IOException { + void testDiseaseSamePrimary() throws IOException { SamePrimaries same = _DISEASE.samePrimaries("latest", "9870/3", "9872/3", "2010", "2010").execute().body(); assertNotNull(same); @@ -163,7 +167,7 @@ public void testDiseaseSamePrimary() throws IOException { } @Test - public void testDiseaseSearch() throws IOException { + void testDiseaseSearch() throws IOException { DiseaseSearch search = new DiseaseSearch("basophilic", Disease.Type.HEMATO); DiseaseSearchResults results = _DISEASE.search("latest", search.paramMap()).execute().body(); @@ -212,7 +216,7 @@ public void testDiseaseSearch() throws IOException { } @Test - public void testDiseaseSearchIterate() throws IOException { + void testDiseaseSearchIterate() throws IOException { DiseaseSearch search = new DiseaseSearch(); search.setOutputType(PublishableSearch.OutputType.FULL); search.setCount(100); @@ -235,7 +239,7 @@ public void testDiseaseSearchIterate() throws IOException { } @Test - public void testDiseaseReportability() throws IOException { + void testDiseaseReportability() throws IOException { Disease partial = new Disease(); partial.setType(Disease.Type.HEMATO); @@ -254,7 +258,7 @@ public void testDiseaseReportability() throws IOException { } @Test - public void testDiseaseChangelog() throws IOException { + void testDiseaseChangelog() throws IOException { DiseaseChangelogResults results = _DISEASE.diseaseChangelogs("latest", null, "2013-07-30", 1).execute().body(); assertNotNull(results); @@ -279,7 +283,7 @@ public void testDiseaseChangelog() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(Disease.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(DiseaseVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(DiseaseChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index dea1cf5..48310c5 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -11,8 +11,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; @@ -21,27 +21,27 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static com.imsweb.seerapi.client.glossary.Glossary.Category.GENERAL; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class GlossaryTest { +class GlossaryTest { private static GlossaryService _GLOSSARY; - @BeforeClass + @BeforeAll public static void setup() { _GLOSSARY = new SeerApi.Builder().connect().glossary(); } @Test - public void testGlossaryCategory() { + void testGlossaryCategory() { assertEquals(Glossary.Category.SOLID_TUMOR, Glossary.Category.valueOf("SOLID_TUMOR")); } @Test - public void testGlossaryVersions() throws IOException { + void testGlossaryVersions() throws IOException { List versions = _GLOSSARY.versions().execute().body(); assertNotNull(versions); @@ -54,7 +54,7 @@ public void testGlossaryVersions() throws IOException { } @Test - public void testGlossaryById() throws IOException { + void testGlossaryById() throws IOException { GlossarySearchResults results = _GLOSSARY.search("latest", "Lymphangiogram").execute().body(); assertNotNull(results); assertTrue(results.getCount() > 0); @@ -73,7 +73,7 @@ public void testGlossaryById() throws IOException { } @Test - public void testGlossaryChangelog() throws IOException { + void testGlossaryChangelog() throws IOException { GlossaryChangelogResults results = _GLOSSARY.changelogs("latest", null, null, 1).execute().body(); assertNotNull(results); @@ -104,7 +104,7 @@ public void testGlossaryChangelog() throws IOException { } @Test - public void testGlossarySearch() throws IOException { + void testGlossarySearch() throws IOException { String term = "killer"; GlossarySearch search = new GlossarySearch(term); @@ -135,7 +135,7 @@ public void testGlossarySearch() throws IOException { } @Test - public void testGlossarySearchIterate() throws IOException { + void testGlossarySearchIterate() throws IOException { GlossarySearch search = new GlossarySearch(); search.setOutputType(PublishableSearch.OutputType.FULL); search.setCount(25); @@ -160,7 +160,7 @@ public void testGlossarySearchIterate() throws IOException { } @Test - public void testGlossaryMatch() throws IOException { + void testGlossaryMatch() throws IOException { String text = "This text contains summary stage which should be found."; Set matches = _GLOSSARY.match(text, null, true).execute().body(); @@ -173,7 +173,7 @@ public void testGlossaryMatch() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(Glossary.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(GlossaryVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(GlossaryResource.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java index fea3c2f..3d5b47b 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -8,8 +8,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import retrofit2.Response; @@ -22,17 +22,17 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; -public class HcpcsServiceTest { +class HcpcsServiceTest { private static HcpcsService _HCPCS; - @BeforeClass + @BeforeAll public static void setup() { _HCPCS = new SeerApi.Builder().connect().hcpcs(); } @Test - public void testGetProcedureByCode() throws IOException { + void testGetProcedureByCode() throws IOException { Hcpcs proc = _HCPCS.getProcedure("S0087").execute().body(); assertThat(proc).isNotNull(); @@ -68,7 +68,7 @@ public void testGetProcedureByCode() throws IOException { } @Test - public void testSearch() throws IOException { + void testSearch() throws IOException { Response> response = _HCPCS.search(new HashMap<>()).execute(); assertThat(response.headers().get("X-Total-Count")).isNotNull(); assertThat(Integer.valueOf(Objects.requireNonNull(response.headers().get("X-Total-Count")))).isGreaterThan(100); @@ -107,7 +107,7 @@ public void testSearch() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(Hcpcs.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } } \ No newline at end of file diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 799b7f6..1d366af 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -4,8 +4,10 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import retrofit2.Call; import com.imsweb.seerapi.client.BadRequestException; import com.imsweb.seerapi.client.SeerApi; @@ -17,25 +19,28 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class MphTest { private static MphService _MPH; - @BeforeClass + @BeforeAll public static void setup() { _MPH = new SeerApi.Builder().connect().mph(); } - @Test(expected = BadRequestException.class) - public void testMissingAllInput() throws IOException { - _MPH.mph(new MphInputPair()).execute(); + @Test + void testMissingAllInput() { + Call call = _MPH.mph(new MphInputPair()); + assertThrows(BadRequestException.class, call::execute); } - @Test(expected = BadRequestException.class) - public void testMissingSite() throws IOException { + @Test + void testMissingSite() throws IOException { MphInput input1 = new MphInput(); // site is missing input1.setHistologyIcdO3("8000"); @@ -50,11 +55,12 @@ public void testMissingSite() throws IOException { input2.setDateOfDiagnosisYear("2016"); input2.setLaterality("1"); - _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + Call call = _MPH.mph(new MphInputPair(input1, input2)); + assertThrows(BadRequestException.class, call::execute); } @Test - public void testResults() throws IOException { + void testResults() throws IOException { MphInput input1 = new MphInput(); input1.setPrimarySite("C509"); input1.setHistologyIcdO3("8000"); @@ -71,6 +77,7 @@ public void testResults() throws IOException { // first test single primary (only differs by site code) MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(MphOutput.Result.SINGLE_PRIMARY, result.getResult()); assertEquals("mp_2007_breast", result.getGroupId()); assertEquals("M13", result.getStep()); @@ -81,6 +88,7 @@ public void testResults() throws IOException { // next test questionable (setting laterality to unknown for one of the diseases) input2.setLaterality("9"); result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(MphOutput.Result.QUESTIONABLE, result.getResult()); assertEquals("mp_2007_breast", result.getGroupId()); assertEquals("M7", result.getStep()); @@ -100,6 +108,7 @@ public void testResults() throws IOException { input2.setDateOfDiagnosisYear("1998"); input2.setLaterality("1"); result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); assertEquals("mp_2007_breast", result.getGroupId()); assertEquals("M5", result.getStep()); @@ -109,7 +118,7 @@ public void testResults() throws IOException { } @Test - public void testLenientMode() throws IOException { + void testLenientMode() throws IOException { MphInput input1 = new MphInput(); MphInput input2 = new MphInput(); input1.setPrimarySite("C502"); @@ -130,13 +139,14 @@ public void testLenientMode() throws IOException { // not passing should default to STRICT MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); assertEquals(9, result.getAppliedRules().size()); assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); assertEquals("M12", result.getStep()); } - @Test(expected = BadRequestException.class) - public void testInvalidInput() throws IOException { + @Test + void testInvalidInput() throws IOException { MphInput i1 = new MphInput(); MphInput i2 = new MphInput(); @@ -149,11 +159,13 @@ public void testInvalidInput() throws IOException { i2.setBehaviorIcdO3("3"); i1.setDateOfDiagnosisYear("2015"); i2.setDateOfDiagnosisYear("2015"); - _MPH.mph(new MphInputPair(i1, i2)).execute().body(); + + Call call = _MPH.mph(new MphInputPair(i1, i2)); + assertThrows(BadRequestException.class, call::execute); } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(MphRule.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(MphInput.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(MphInputPair.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index 413e718..b238404 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -7,25 +7,25 @@ import java.util.List; import java.util.Objects; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import static org.assertj.core.api.Assertions.assertThat; -public class NaaccrTest { +class NaaccrTest { private static NaaccrService _NAACCR; - @BeforeClass + @BeforeAll public static void setup() { _NAACCR = new SeerApi.Builder().connect().naaccr(); } @Test - public void testNaaccrFlatVersions() throws IOException { + void testNaaccrFlatVersions() throws IOException { List versions = _NAACCR.flatVersions().execute().body(); assertThat(versions).isNotNull().isNotEmpty(); @@ -39,7 +39,7 @@ public void testNaaccrFlatVersions() throws IOException { } @Test - public void testNaaccrXmlVersions() throws IOException { + void testNaaccrXmlVersions() throws IOException { List versions = _NAACCR.xmlVersions().execute().body(); assertThat(versions).isNotNull().isNotEmpty(); @@ -56,7 +56,7 @@ public void testNaaccrXmlVersions() throws IOException { } @Test - public void testNaaccrFlatFieldNames() throws IOException { + void testNaaccrFlatFieldNames() throws IOException { List names = _NAACCR.flatFieldNames("latest").execute().body(); assertThat(names).isNotNull(); @@ -67,7 +67,7 @@ public void testNaaccrFlatFieldNames() throws IOException { } @Test - public void testNaaccrXmlFieldNames() throws IOException { + void testNaaccrXmlFieldNames() throws IOException { List names = _NAACCR.xmlFieldNames("latest").execute().body(); assertThat(names).isNotNull(); @@ -79,7 +79,7 @@ public void testNaaccrXmlFieldNames() throws IOException { } @Test - public void testNaaccrFlatField() throws IOException { + void testNaaccrFlatField() throws IOException { NaaccrFlatField name = _NAACCR.flatField("16", 521).execute().body(); assertThat(name).isNotNull(); @@ -112,7 +112,7 @@ public void testNaaccrFlatField() throws IOException { } @Test - public void testNaaccrXmlField() throws IOException { + void testNaaccrXmlField() throws IOException { NaaccrXmlField name = _NAACCR.xmlField("21", "phase2RadiationExternalBeamTech").execute().body(); assertThat(name).isNotNull(); @@ -132,7 +132,7 @@ public void testNaaccrXmlField() throws IOException { // these two tests are slow so don't run them all the time; they verify that all the items from flat and NAACR can be read without error - @Ignore("Slow test so do not run all the time") + @Disabled("Slow test so do not run all the time") public void loadAllFlat() throws IOException { for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.flatFieldNames("latest").execute().body())) { NaaccrFlatField field = _NAACCR.flatField("latest", name.getItemNum()).execute().body(); @@ -141,7 +141,7 @@ public void loadAllFlat() throws IOException { } } - @Ignore("Slow test so do not run all the time") + @Disabled("Slow test so do not run all the time") public void loadAllXml() throws IOException { for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.xmlFieldNames("latest").execute().body())) { NaaccrXmlField field = _NAACCR.xmlField("latest", name.getNaaccrId()).execute().body(); diff --git a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java index 0825c97..5133619 100644 --- a/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java +++ b/src/test/java/com/imsweb/seerapi/client/ndc/NdcTest.java @@ -8,8 +8,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import retrofit2.Response; @@ -21,17 +21,17 @@ import static org.assertj.core.api.Assertions.assertThat; @SuppressWarnings("ConstantConditions") -public class NdcTest { +class NdcTest { private static NdcService _NDC; - @BeforeClass + @BeforeAll public static void setup() { _NDC = new SeerApi.Builder().connect().ndc(); } @Test - public void testNdcByCode() throws IOException { + void testNdcByCode() throws IOException { NdcProduct product = _NDC.getByCode("0002-3227").execute().body(); assertThat(product).isNotNull(); @@ -81,7 +81,7 @@ public void testNdcByCode() throws IOException { } @Test - public void testNdcSearch() throws IOException { + void testNdcSearch() throws IOException { NdcSearch search = new NdcSearch(); search.setIncludeRemoved(true); @@ -112,7 +112,7 @@ public void testNdcSearch() throws IOException { } @Test - public void testNdcSearchByCategory() throws IOException { + void testNdcSearchByCategory() throws IOException { NdcSearch search = new NdcSearch(); search.setCategory(Category.CHEMOTHERAPY); @@ -129,7 +129,7 @@ public void testNdcSearchByCategory() throws IOException { } @Test - public void testNdcHasSeerInfo() throws IOException { + void testNdcHasSeerInfo() throws IOException { NdcSearch search = new NdcSearch(); search.setIncludeRemoved(true); @@ -154,7 +154,7 @@ public void testNdcHasSeerInfo() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(NdcProduct.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(NdcPackage.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(NdcSubstance.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 42d16cd..4afa012 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -11,30 +11,30 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.publishable.PublishableSearch; import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class RxTest { +class RxTest { private static RxService _RX; - @BeforeClass + @BeforeAll public static void setup() { _RX = new SeerApi.Builder().connect().rx(); } @Test - public void testRxVersions() throws IOException { + void testRxVersions() throws IOException { List versions = _RX.versions().execute().body(); assertNotNull(versions); @@ -47,7 +47,7 @@ public void testRxVersions() throws IOException { } @Test - public void testRxById() throws IOException { + void testRxById() throws IOException { Rx rx = _RX.getById("latest", "53c44afe102c1290262dc672").execute().body(); assertNotNull(rx); @@ -77,7 +77,7 @@ public void testRxById() throws IOException { } @Test - public void testRxChangelog() throws IOException { + void testRxChangelog() throws IOException { RxChangelogResults results = _RX.changelogs("latest", "2015-08-30", "2015-09-30", 1).execute().body(); assertNotNull(results); @@ -106,7 +106,7 @@ public void testRxChangelog() throws IOException { } @Test - public void testRxSearch() throws IOException { + void testRxSearch() throws IOException { RxSearch search = new RxSearch("abt", Rx.Type.DRUG); RxSearchResults results = _RX.search("latest", search.paramMap()).execute().body(); @@ -137,7 +137,7 @@ public void testRxSearch() throws IOException { } @Test - public void testRxSearchIterate() throws IOException { + void testRxSearchIterate() throws IOException { RxSearch search = new RxSearch(); search.setOutputType(PublishableSearch.OutputType.FULL); search.setCount(100); @@ -160,7 +160,7 @@ public void testRxSearchIterate() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(Rx.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(RxChangelog.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(RxChangelogEntry.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index 416320a..f73b214 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -7,8 +7,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import retrofit2.Call; @@ -18,26 +18,28 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class SiteRecodeTest { private static SiteRecodeService _SITE_RECODE; - @BeforeClass + @BeforeAll public static void setup() { _SITE_RECODE = new SeerApi.Builder().connect().siteRecode(); } - @Test(expected = BadRequestException.class) - public void testBadRequestException() throws IOException { - _SITE_RECODE.siteGroup("C379", null).execute(); + @Test + void testBadRequestException() { + Call call = _SITE_RECODE.siteGroup("C379", null); + assertThrows(BadRequestException.class, call::execute); } @Test - public void testExceptionMessages() throws IOException { + void testExceptionMessages() throws IOException { String message = ""; try { @@ -53,16 +55,15 @@ public void testExceptionMessages() throws IOException { } @Test - public void testSiteRecordVersion() throws IOException { - Call call = _SITE_RECODE.version(); - String version = call.execute().body().getVersion(); + void testSiteRecordVersion() throws IOException { + String version = _SITE_RECODE.version().execute().body().getVersion(); assertNotNull(version); assertTrue(version.length() > 0); } @Test - public void testSiteRecode() throws IOException { + void testSiteRecode() throws IOException { Call call = _SITE_RECODE.siteGroup("C379", "9650"); SiteRecode recode = call.execute().body(); @@ -73,7 +74,7 @@ public void testSiteRecode() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(Version.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(SiteRecode.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 8f4f3c2..dfcc2df 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -12,8 +12,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; import com.imsweb.seerapi.client.disease.DateRange; @@ -87,34 +87,34 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -public class StagingTest { +class StagingTest { private static final String _ALGORITHM = "cs"; private static final String _VERSION = "02.05.50"; private static StagingService _STAGING; - @BeforeClass + @BeforeAll public static void setup() { _STAGING = new SeerApi.Builder().connect().staging(); } @Test - public void testGetAlgorithms() throws IOException { + void testGetAlgorithms() throws IOException { List algorithms = _STAGING.algorithms().execute().body(); assertThat(algorithms).isNotEmpty().extracting("algorithm").contains("cs", "tnm", "eod_public"); } @Test - public void testGetAlgorithmVersions() throws IOException { + void testGetAlgorithmVersions() throws IOException { List versions = _STAGING.versions(_ALGORITHM).execute().body(); assertThat(versions).isNotEmpty(); } @Test - public void testListSchemas() throws IOException { + void testListSchemas() throws IOException { List schemaInfos = _STAGING.schemas(_ALGORITHM, _VERSION).execute().body(); assertThat(schemaInfos).isNotEmpty(); @@ -123,7 +123,7 @@ public void testListSchemas() throws IOException { } @Test - public void testSchemaLookup() throws IOException { + void testSchemaLookup() throws IOException { // first test simple lookup that returns a single schema with site/hist only List schemas = _STAGING.schemaLookup(_ALGORITHM, _VERSION, new CsSchemaLookup("C509", "8000").getInputs()).execute().body(); assertThat(schemas).hasSize(1).extracting("id").contains("breast"); @@ -181,7 +181,7 @@ public void testSchemaLookup() throws IOException { } @Test - public void testSchemaById() throws IOException { + void testSchemaById() throws IOException { StagingSchema schema = _STAGING.schemaById(_ALGORITHM, _VERSION, "brain").execute().body(); assertThat(schema).isNotNull(); @@ -210,14 +210,14 @@ public void testSchemaById() throws IOException { } @Test - public void testSchemaInvolvedTables() throws IOException { + void testSchemaInvolvedTables() throws IOException { List tables = _STAGING.involvedTables(_ALGORITHM, _VERSION, "brain").execute().body(); assertThat(tables).isNotEmpty(); } @Test - public void testListTables() throws IOException { + void testListTables() throws IOException { List tables = _STAGING.tables(_ALGORITHM, _VERSION, "ssf1").execute().body(); assertThat(tables).isNotEmpty(); @@ -228,7 +228,7 @@ public void testListTables() throws IOException { } @Test - public void testTableById() throws IOException { + void testTableById() throws IOException { StagingTable table = _STAGING.tableById(_ALGORITHM, _VERSION, "primary_site").execute().body(); assertThat(table).isNotNull(); @@ -238,14 +238,14 @@ public void testTableById() throws IOException { } @Test - public void testTableInvoledSchemas() throws IOException { + void testTableInvoledSchemas() throws IOException { List schemas = _STAGING.involvedSchemas(_ALGORITHM, _VERSION, "extension_baa").execute().body(); assertThat(schemas).isNotEmpty(); } @Test - public void testCsInputBuilder() { + void testCsInputBuilder() { CsStagingData data1 = new CsStagingData(); data1.setInput(CsInput.PRIMARY_SITE, "C680"); data1.setInput(CsInput.HISTOLOGY, "8000"); @@ -291,7 +291,7 @@ public void testCsInputBuilder() { } @Test - public void testCsStaging() throws IOException { + void testCsStaging() throws IOException { CsStagingData data = new CsStagingInputBuilder() .withInput(CsInput.PRIMARY_SITE, "C680") .withInput(CsInput.HISTOLOGY, "8000") @@ -372,7 +372,7 @@ public void testCsStaging() throws IOException { } @Test - public void testTnmInputBuilder() { + void testTnmInputBuilder() { TnmStagingData data1 = new TnmStagingData(); data1.setInput(TnmInput.PRIMARY_SITE, "C680"); data1.setInput(TnmInput.HISTOLOGY, "8000"); @@ -415,7 +415,7 @@ public void testTnmInputBuilder() { } @Test - public void testTnmStaging() throws IOException { + void testTnmStaging() throws IOException { TnmStagingData data = new TnmStagingInputBuilder() .withInput(TnmInput.PRIMARY_SITE, "C680") .withInput(TnmInput.HISTOLOGY, "8000") @@ -457,7 +457,7 @@ public void testTnmStaging() throws IOException { } @Test - public void testEodInputBuilder() { + void testEodInputBuilder() { EodStagingData data1 = new EodStagingData(); data1.setInput(EodInput.PRIMARY_SITE, "C250"); data1.setInput(EodInput.HISTOLOGY, "8154"); @@ -486,7 +486,7 @@ public void testEodInputBuilder() { } @Test - public void testEodStaging() throws IOException { + void testEodStaging() throws IOException { EodStagingData data = new EodStagingInputBuilder() .withInput(EodInput.PRIMARY_SITE, "C250") .withInput(EodInput.HISTOLOGY, "8154") @@ -519,7 +519,7 @@ public void testEodStaging() throws IOException { } @Test - public void testStagingWithErrors() throws IOException { + void testStagingWithErrors() throws IOException { StagingData data = new StagingData(); data.setInput("site", "C181"); data.setInput("hist", "8093"); @@ -535,7 +535,7 @@ public void testStagingWithErrors() throws IOException { } @Test - public void testStagingGlossary() throws IOException { + void testStagingGlossary() throws IOException { Set matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", null, true).execute().body(); assertThat(matches).hasSize(26); matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", EnumSet.of(Category.STAGING), true).execute().body(); @@ -548,7 +548,7 @@ public void testStagingGlossary() throws IOException { } @Test - public void testStagingMetadata() throws IOException { + void testStagingMetadata() throws IOException { StagingSchema schema = _STAGING.schemaById("eod_public", "2.0", "brain").execute().body(); assertThat(schema).isNotNull(); @@ -559,7 +559,7 @@ public void testStagingMetadata() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(StagingAlgorithm.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(StagingMetadata.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters(), hasValidBeanEquals())); MatcherAssert.assertThat(StagingVersion.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSettersExcluding("production", "beta", "development"))); diff --git a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java index 3ec9c38..111d59d 100644 --- a/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/surgery/SurgeryTest.java @@ -8,8 +8,8 @@ import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; @@ -17,24 +17,24 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.assertj.core.api.Assertions.assertThat; -public class SurgeryTest { +class SurgeryTest { private static SurgeryService _SURGERY; - @BeforeClass + @BeforeAll public static void setup() { _SURGERY = new SeerApi.Builder().connect().surgery(); } @Test - public void testSiteSpecificSurgeryTables() throws IOException { + void testSiteSpecificSurgeryTables() throws IOException { List titles = _SURGERY.tables("2014").execute().body(); assertThat(titles).isNotEmpty().containsAnyOf("Oral Cavity"); } @Test - public void testSiteSpecificSurgeryTable() throws IOException { + void testSiteSpecificSurgeryTable() throws IOException { SurgeryTable table = _SURGERY.table("2014", "Oral Cavity", null, null).execute().body(); assertThat(table).isNotNull(); @@ -57,7 +57,7 @@ public void testSiteSpecificSurgeryTable() throws IOException { } @Test - public void testBeans() { + void testBeans() { MatcherAssert.assertThat(SurgeryTable.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); MatcherAssert.assertThat(SurgeryRow.class, CoreMatchers.allOf(hasValidBeanConstructor(), hasValidGettersAndSetters())); } From 33f3dcc21ba3edbb3989f296da2f6f0ac06a65ed Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 15 Sep 2022 09:37:05 -0400 Subject: [PATCH 204/243] Try threading tests --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 7030e06..7daa911 100644 --- a/build.gradle +++ b/build.gradle @@ -79,6 +79,7 @@ tasks.withType(Javadoc) { test { useJUnitPlatform() + maxParallelForks = (int) (Runtime.runtime.availableProcessors() / 2 + 1) } checkstyle { From 8498c23ad33b720ce9114ad9c02bf775a09a7822 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 15 Sep 2022 09:46:50 -0400 Subject: [PATCH 205/243] Parallel give very little. Disabling for now. --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7daa911..7030e06 100644 --- a/build.gradle +++ b/build.gradle @@ -79,7 +79,6 @@ tasks.withType(Javadoc) { test { useJUnitPlatform() - maxParallelForks = (int) (Runtime.runtime.availableProcessors() / 2 + 1) } checkstyle { From 63e71c029d041aed3ab8ac4c18d12acc370f65d4 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 21 Sep 2022 14:09:44 -0400 Subject: [PATCH 206/243] Fix build deprecations --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 7030e06..8d26c39 100644 --- a/build.gradle +++ b/build.gradle @@ -46,9 +46,9 @@ dependencies { // newer version of dependency to fix vulnerability until converter-jackson is updated api 'com.fasterxml.jackson.core:jackson-databind:2.13.4' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' testImplementation 'org.assertj:assertj-core:3.23.1' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } @@ -92,7 +92,7 @@ spotbugs { jacocoTestReport { reports { - xml.enabled true + xml.required = true } } test.finalizedBy jacocoTestReport From 608e0df16460d5482fd9b388717a3b1704f4dbb1 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 12 Jul 2023 11:37:59 -0400 Subject: [PATCH 207/243] Update dependencies and clean up unit tests --- build.gradle | 39 ++++++++++++------ gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 63375 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 24 +++++++---- gradlew.bat | 1 + .../seerapi/client/hcpcs/mph/MphTest.java | 8 ++-- .../com/imsweb/seerapi/client/rx/RxTest.java | 24 +++++++---- .../client/siterecode/SiteRecodeTest.java | 2 +- 8 files changed, 68 insertions(+), 34 deletions(-) diff --git a/build.gradle b/build.gradle index 8d26c39..1f535d9 100644 --- a/build.gradle +++ b/build.gradle @@ -2,14 +2,14 @@ plugins { id 'java-library' id 'checkstyle' id 'jacoco' - id "com.github.spotbugs" version "5.0.12" + id "com.github.spotbugs" version "5.0.14" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '3.2.0' - id "com.github.ben-manes.versions" version "0.42.0" - id 'org.sonatype.gradle.plugins.scan' version '2.4.1' - id "org.sonarqube" version "3.4.0.2513" + id "com.github.ben-manes.versions" version "0.47.0" + id 'org.sonatype.gradle.plugins.scan' version '2.6.0' + id "org.sonarqube" version "4.2.1.3168" } group = 'com.imsweb' @@ -34,22 +34,22 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.7.2' + spotbugs 'com.github.spotbugs:spotbugs:4.7.3' api 'com.squareup.retrofit2:retrofit:2.9.0' api 'com.squareup.retrofit2:converter-jackson:2.9.0' // retrofit will not update these dependencies to fix vulnerabilities - api 'com.squareup.okhttp3:okhttp:4.10.0' - api 'com.squareup.okio:okio:3.2.0' + api 'com.squareup.okhttp3:okhttp:4.11.0' + api 'com.squareup.okio:okio:3.4.0' // newer version of dependency to fix vulnerability until converter-jackson is updated - api 'com.fasterxml.jackson.core:jackson-databind:2.13.4' + api 'com.fasterxml.jackson.core:jackson-databind:2.15.2' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.1' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' - testImplementation 'org.assertj:assertj-core:3.23.1' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.3' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.3' + testImplementation 'org.assertj:assertj-core:3.24.2' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } @@ -111,8 +111,21 @@ ossIndexAudit { printBanner = false } +def isNonStable = { String version -> + def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) } + def regex = /^[0-9,.v-]+(-r)?$/ + return !stableKeyword && !(version ==~ regex) +} + +// https://github.com/ben-manes/gradle-versions-plugin +tasks.named("dependencyUpdates").configure { + rejectVersionIf { + isNonStable(it.candidate.version) + } +} + wrapper { - gradleVersion = '7.5.1' + gradleVersion = '8.2.1' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 41134 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 delta 38514 zcmZ5{Q+Opnm~1AtZQHhO+qSI}o|q@*#I`-L?Fl9}C(b09J9l@#-Mjax|HfnWSJm}* zCEY@-{Dgo~Re*qm2Yo}tO2NnY2A{(0_U%7rD3D-aU@q=9ED&J-b7B+gKQ}>;--vMF z!N6c){~ZzoQ+4mou7LvsW5NalqX(J!VW&PqgXE6U0QtHwzL?`!UoiQt6|2SW#WCcC zQUWpLifp<=sAO=Ifuy47l6zort*OX2&ZE1;RLTdQ6{*s(L=`wRZt%)^phoZ!Wgq|B z)$=~k0q>j5i)VK;Y0#T6XUD_IEW_V`hh4-Z;rj(EFo#icsCmsMsCo6GgH3neM8bla zJwJMR0A&~CypC&T7|!dxxQH<&9E)2Z*Hu9uhF1@CSyAI&8Ps@ z_UU+!X2hK{*6rZu@5?@S-$KIO+i{qW&hN#T0F;S07_C59laHY9=Y0Bm4me942`W8q4yQ!?Xl}Ga;zHJY z7hSOxbULS?0IqfpXA`^H^gPPuDZiP20I;$!_%+X(ON=^zv<*Kk^hA{ucB>4)kC|mg z9Jh&M@C}(rniQFTqEV31fyY|qcpF6YQc-lLv%acjI@tg?mp1Ij%>4sJ`FqCqi@q-f za|FkR9RZQv2)gH~9VyyrO6V0tFGskiRAk50#a-b zDUIIGr!LBxh^*s-GbCq=$n37b8)zf)rEY3uHGabT znWo6R3lp~9v*Rs};H<5-om;r70W|1NV|(5lcqFzRj4;vJJMFsw^Gx9b%7L&3gjyse zqFr!}4rPbsC-W-rT)CQGt`C9AgJK3uSnMQ%lC9YlhiV!m3yml{_yynw65tuY5>si& z3Vvez{!kb6zaPt!mO08$rnD3K=goEU>U-5@CyhXt{Vn+ZlKq}nVn1bg0A``0G@^m& z&R@4L&Oj28g*%B4*}){P56C38IBHOfgbE@@G=6YwA>C^i&}1(YpWHVGh?ckFN~of9 z$AC02<^p*V(78%?>CQQ&al@QfKIuUDePC9~H4KpCjM71gE*-CDA=m$Fa{mQ9;7zE-7oFVB$IJtejA8pxOWNiY7zxn%Ob0`Rk6Q4`vWlUwn54VRJe>7F~ z)3aM6CL6nZu_X#%EF-B?zM?cbjET2~!L+8zZas2cr8qs2p5VdCp4OU`r+{E@Sj5r% zfg@1o*S+ieJXh}Fa-%zky{&E`^Ugz2q8wQ~j4u2e#ABWDI>S3jSNF!NiTf`wGB zM@lwLI14v-M@a=PpBNgio1)`P9Uzq^*X$+b*N=b zU?(f3WC z8gFHt&4XNLB39;skmv9y-;-=UH7>wvzFIpDQfrA%sbqFR(GL5_6<>~R%bYo0-jdg( zr>;^y_A&xgEOWg?K zcW9}eg#LYV^TXN4p39BMVAvk^hblTsxPZrqyXJuO{uxg|p>33Q8q zUl1Gpo<7X}W2I47#bXtYGGs`r|%nSEpWHg_>2V z5IeB=E|%@p+l_WtC^5BPjaI22-vs^(f~)^Pf%cjKKF#ap4P4&`oO_m9OH%{0*qhw|b&&6e!{p;v77O;woJ#ju% zzLajEyHdJViF8`y6-Ptr5jjhuIc38Et zCf#Rp81b0zrzar|?X{p&9Qj!E2$2vt^}rjh91Op>p45ktqNaEd1H@B_E$%RU*cqy} zB^vc0txx-vDArEBM8%=%0@h&`_$dS6fR}P0ksrD0H(8c;4_Us672=Wn%df~@Mg$ux zz3gygTJjXM#nh8rhU?NStq%htTf|zq{c^S1S)2|Uh3)NlUSaj+17eC0j@K;=RSn(D zp?6H~Qr8Ek7c*;L!rXW5_=5}v%|%RGWwQsNESi{5gP_dDvWCi{07L_s`%(r#MD;Ow zJDeeG#jHJn)E_7rcPI^83g=O8@^$&vQm1KL@`Yx2;zF<_buJ8BG8Fab7&iu|?Lo^k zQs<>-XkbIwpH$vaJuaUD>sYvYhY$YghDb$TpQoyinlP8bu!N)%%|W6;`pXUWz{MH)l8X;_}&_AqRPVg(T`Ym<^Xc4)7)YR3{h zb=DgCN^iX0>i$q#2?y;TXOb-==@p}Jg2VgW4}kyFeJKbo{~`Kh|4aIrAmV+4Z}CHn z1^+idqBKJOTSq>{Ynj6c{PwSO`d3BO;)8jDV#pLdOwHsZEZ&GbZ1ws`L>HLrkmpA{YxX+Gvn{y5| zH)zL2|C={GljqXUC%_R9{Pp!4>j$YeB`3v_tc0dG0y(-l?xQ*E3onrG24S`mGLbD2 zhVT%*H!F>FpKP2Wkq$cPO`Zv|7!j}|w=*H-4$PZnNKrISpnR-j(wnB%Qqs#v2s0m< z^fz49^hh;pU*G(2K~TtJYKnWQW9!85*EX|73oFa7Yc&@HE&HXmQa#1znShYAuHwWy zzE8WlU6fVfa#X9a>i8^4$wL3?EvJ(vXTgDo*Gu4aN7NiD;_b_}n1dV zn$61Fm9*A*(GlyOe|k&FgBpz=sdfdx+bdaD)pI-na@3}je$yp7nT$>%=L&# z{dvxt7*(kY>Qb9_zjoWvzNKc)oD}yu1;HndBj%o_Ld`Xe)hfF6#l(_P1I2)%OsBY| zT0!Fzv>es4g^BFB-`sSBTLJrFD8a4ng7;?7ErcGzGlz5%naiuJ@qFlh^-lKh_1a`4 z{54g9ov{vK8{|~YCE=0ucSNh0pIp>g`J$ToWd>pna)@-meL!`SzIn5d^7RzZoxR*X zcCZBp>A2qmJ3j}q9ql+fZ<01r+>}#Zk6%;5>~Yho+oJjnRx7=-5r6?sf0}2`{+Q++ zujwx_nH6QDAVoO6(xDvj+^*ih7v;|A#NUQ}E3OpOpxsI`_Yy!3P=R3P?)>Y;w%_u- zI4<~%>G9Ggc)(VtwK`nElVw3A#oME`p=1*WF(`ro7yh>7M(EnewxUVzY=iM)ld#v3 zn27R{lxXu1y&h~W7VwTdiCYiiA$TI{Bi-gyffV`i1b1_1v(j^iR8aPHYbyX|f|62B zHu1dJ=>ul>3AX#Bn$_O_B_Xw3Af>%vi(%@BR_6$J%@_%0&{PTOL?fd~?TWA?DOT&e zJSFul3hf8c&^ehM#0Co_uV8TKrU7LxdEJkF?Z+!#|D+Ie4t=Wn*A#|CVQ`x@dfQPJ zZ8CS7n~q;YxIe6NDkhycgj)FJ+`~_Do#A|-A_hX0M_9q{`(w$F?>A!6yzbfK%zj=E zfzQfyJi`3PE&cDOSQ(yV2`GU~3D8z^NIKZ(XYtU3wes-gBO};Pp>=N#iHRysBhzwg#N(RD*xy*XXX}$11(}w)=C<$_aX**WS+rCGqx1)qx zU-7DG@eTLM;{>2mwHK>9rFC)yVd70i?St1>@Urn!*JG|U@T+Nw;VZ*{8HdYZH8Zi2 zDc*&Zva`18=qEOwzaW|z;4I7P%wcM_vh_>@iGXN=$b1xMaZLO4HuB9zu<0O1WYzL( z%Ct$t>HfYr#naG2S9pkM+`=YIc)`1TRn&+lFpUXuth$4V;aNiFX;d_KKCPNH4zbz3 zvp|Xmk%$NP#NyoHpzUrq23d#4cOx~Ht>VxcyMuL})vp%XGK+T(u*oq)JivAKkRYN3 zTx=&0y6T5_3q~a2=XwX&X4#T_IdnU@oj)9}UW5~w{ATy*xRx*uVTXS-EI&solM#Kw zlrvh;EKDhjYLzLq%R9&RKfxR>nQ)=HjAq~pYi8Mj>dzq9O zRmmO|YTSXqtCwO|Y~!Uvgc>g|Wxz#d$A|MaF3Sa1?54?Q925S{FY&Nh`u@VG@c{~@ln1zPX`+55)*W>=FY%Yl5s>adSI7m%csS&4*eRqM z#}MFbL+81JuvROZ$`Tou`@xfb7^LB4VX`lLh3^yjV&Xo_I-9R6AF<}|&v#vIw*0xS z5UTlnC^QL%V2z4mSGKr^L{eY}Hcq5~$jtPlu``D|!)gdgVrSvUt5tibB>-byi3DWZ zN1arM+`_4BAzq2S@wD8$@Ps~i@A)qA{((R7&;Ovju~I{<8%#0|U^T%teQNd38>@;$jn0OX_8s;+w>6qY`dd zwGrBi*G7qpP1n0*YR4V2t%2>9wZB)di*I9OwfOS5+UC(Y>=0~QJHSIG=qlJSk$iZL zV3Of4s`bt`f?z({a4qf$?m^$SMRJ_>@EWa+q&TwAnIggsR^DiIm|5O_=XkO(cE!Q( zAgJ8ev_lRkDo3`Fk5|n*utE;TH~(&zo2)gA76t19p)1)zzIZrI6E;c|pGI>Xe6AhO zdXd#fYvMeIoOmt|N`MhnUsh&FQ_TJQ2&cpmsUE_yO!tXvV4bLxp6?1S^Bb@=SXOj+ z2PMLY9vkPcf!i5W@~QiAjQ!Lr40U3~NaL=C)Wwt9WOe!ZlYgKa zka#^1<<@WNVbwL>9vB-+i|7PiZI88M#`_C?c{)wU$3O}O7LWlMc5jU8=!ROj&+R>M zIW|Q=D^v&7qoYjGKvCqbT&1TGlTpUZOF}ri5`0d4;jZ)gXSlHSc_0MP^>?6BfoPoG zd_@3BZF-a(O|91sOHy>jowZk~$DkEusg^QTge+OM+#Bs9^!Zz_#G#zq*vaBJHmWtw z9rGmcJpPeQ9?-sDUzw2_zYme;qW_6N7{pluO~GUg*!LdUJ3PBtWmW+!jkTD_9+_bmD}zo-D!6 zUY^4_IdmZ9Fqv1pf`Sy>CbtM%R;M_-XS)gF<~`Dk`;=eVm;O&8U)v8G!*Rj~<^c1y z5QLlcuCt$=5ifSeQqldU8AAx9$`75C??;TOE6DS(8Y!rfg}u;=P&RHb#f5VR7IYyj zwqNS0e+mE7i2QFNYo)KzR{{qEyZz@wN`uU>h(M;&FrbTbDnOZrkqU+wrjXB{Ce;r0 z>8M!pXf0bYY+ttWh)N~JoRy@~h?gRwi#_km8Rrq=JUX7NY$`*=N($Uhq!ggX* z1jm-#FGUIA)-i(Tm6D(K7277c2F*&r0mEl_;CV(a&4A|mpTB5O*D<$J&U%BXku?@i zyZbf-lJhHt^QyR=wvz@a%A8jc9@cWb#E(rDBJSHS-pKKB?+pMs)~IyzpT`?(jeAbz z^sV8cHxm_8vblKn9oDggn68t9_=Yf-u5e|)st6U$r=b75p8@`EdR)bj4y{PV!p4>C zkSmtoS^{WnpFczumJ3;f26Ne1EI$yHbaAEToi{!r-LL>2db(pY!hC`5eCXqb*Fv>E zy-lh|TrR1PP?>(WlwgYAXHw!L?V7ATGc5e9o*=WYyE-OjiE@LUvs$vVsvJ=tvHbX@ zLi-1cNZ1^hsucBRo$)!`D%k6P&mG_q8V-A%WZNlG^B*59S=<09uK$MIvJ=L&rK?QT z{l0~KI~<6nrM{Log*j1AjUudD`PRJ=nhoj7?STA`nP2c2M_#vd;}3}pV@^9ZZs>io zN0lI05Z%3IgyW2i5PgH=9ho=rO{rkvx|81(0Z$1j0GSYP1X&91+Run95#^}9g@!fLb z0QRtNaKLz}4aO31gV(fJ(?)P=Mrr(1wYY${<&3?l$}v|+3U>1idJBS^!`wes+wm~C z_k*y+<`d8G+hI|Dev(5afuFc0BF3RKjYdNt#rL#`3MxU0@46E8X4!r9PFZqr^JtdW zkg!4CIpxkirJUo7M4=hX)5`6XPE09F0D}X%lCoiZ!j&1xOtT9fyY`Z;IGQCBI@D(> zSVn%NDiw(htb4*nuoxP0w$NnRDMB3&FSvP(wgzz)2*{kcOa5<#T10E=cJ0m04lUfZ zZKXyOt4mhA%sc5X_;MN^%iL_ng2(=4fAg1SEEPttb3te72xEYQMj~ z58yGWspcm$Hl1mf!@JMn4Gju!cY)bJ?qaJqt>YGqEUD;wrk$UvraO*_k=8vz@7kG~ zXuA3$7TGPJ?tt)fft%NZzN1@+22EGhyAD)`UeQ$x2aD`VpfN294}c4K`%y}4=l`e8d)(x?}GJArx=7gy7o2iF`v zB22@W^xiAXtlXL#@2$0Vx0r`j1$gFBEBInt?S-&1_>3a0L3hLAJ?UCBKyT)TD(lpaY<&%8zjf#B+Htv-%zOBn z4u!#*4W`EC9nGgfG9QBsMWRJQuZebGLPUWok6t^zNaUF{Tm#)kxEhqvnPwx717>d` z7y2%0XK7_e57Ky%;qQk?fFiQ~U~ib~njeYVb<>=r8q}Zr@`w)1-UJ`a-nbojg-OF_A-|?rLy;sn7)+%N{NQG7J$PE6X2^SoB4H#ku4k7==ER=gS6lKyDgh$?Q z{847JfdQpop*IVPKEVv(nyqAl<(w-mhqA9&udYNot*%{Ob((E+1mM4pBItj2#;=>b zC0uc}L(-^);kp>e#L1$(>?y~_M9Kt*FgGru8=2AQ&h~^6)XQIapcz1ft))WOsN^uW z#nxPmwpA&sO}R?@oPIxjfya;>Ww)%NvJXAC|sgy};ao6+?zP%1zd}BHh_! zmGrR{tWf)eUAACX4{AAfKdjmI3U+95j3T*MNd`4$j>h!OEJ=o-4uR~O zIm^@tv1aT#n@VpeeiI5#^rtTQ?#OCH%g|}OgDcZszOKf8zV15u?a0pzf0{KO$rqwd z=7k%k)FEA=MF87GK+_&B{d-N?0#DYe3H~Sg{%!;7AKJNhW^Ulr%v0Wn1Ape|n3`6Y z*NE*6*@5nbo|?pNh%ZhmuV~IdlD-?N(}9F%Y?2^Cb@=^oKSoc3gJ8u zf*-<($M+|Mf@}dNutkQgkSYn}!5XVKuDUaCEPT3P381oWc{}jXjFV6u#VIfywZVin zzTSsV4|(*2D{WhvlT8u*Nwc{Tfu|hi9#8&_Vh{zY(Af593w2Pr(M3j$M@;Ki$|<%d zWgG(FSWjBrp*ye{>ahTS*l*WN;!Jc5>eMEzxzSa1Z1VEVnUJPO?n;o~koHap`)MR+ z%yn@P0QmcRlaaV0Z)!h3cd+K#EE2ZuW^Vwn)FgPiqTNh*zzBwhj##7)3yV8AMjIBk#3Vz#v(!KK|+QMSp{x`p#a=T zSeyIUavK{nA-?~+tz|7jtn}Em@#0+-iBEDodhN^WZVdH2lG(`K_mmr*g4Ym?EC;Hm1R}T@xML< zJ8M{Y^wCL*lA93CNGW8MaC1?(G&!cMgE}~CGdVZdE&|2(2`-Pzuj1&DBRIieB5C*A z?K9sLpr=!B^0qvJPn)g_2L^&6vPM%AA>H{?Curp8X}$Di;CWUz<5OeZ(hjq%7V?

Ed3W8DKk=GWZ^H1%j3(j1_6^9H~ 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8fad3f5..c747538 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index a69d9cb..fcb6fca 100644 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +130,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,6 +197,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/gradlew.bat b/gradlew.bat index f127cfd..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 1d366af..7a8a609 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -79,7 +79,7 @@ void testResults() throws IOException { MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); assertNotNull(result); assertEquals(MphOutput.Result.SINGLE_PRIMARY, result.getResult()); - assertEquals("mp_2007_breast", result.getGroupId()); + assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M13", result.getStep()); assertEquals("Tumors that do not meet any of the criteria are abstracted as a single primary.", result.getReason()); assertEquals(10, result.getAppliedRules().size()); @@ -90,9 +90,9 @@ void testResults() throws IOException { result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); assertNotNull(result); assertEquals(MphOutput.Result.QUESTIONABLE, result.getResult()); - assertEquals("mp_2007_breast", result.getGroupId()); + assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M7", result.getStep()); - assertEquals("Unable to apply Rule M7 of mp_2007_breast. Valid and known laterality should be provided.", result.getReason()); + assertEquals("Unable to apply Rule M7 of MPH 2007-2017 Breast. Valid and known laterality should be provided.", result.getReason()); assertEquals(4, result.getAppliedRules().size()); assertEquals("Is there a tumor(s) in each breast?", result.getAppliedRules().get(3).getQuestion()); @@ -110,7 +110,7 @@ void testResults() throws IOException { result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); assertNotNull(result); assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); - assertEquals("mp_2007_breast", result.getGroupId()); + assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M5", result.getStep()); assertEquals("Tumors diagnosed more than five (5) years apart are multiple primaries.", result.getReason()); assertEquals(2, result.getAppliedRules().size()); diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 4afa012..961ab13 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -48,19 +48,19 @@ void testRxVersions() throws IOException { @Test void testRxById() throws IOException { - Rx rx = _RX.getById("latest", "53c44afe102c1290262dc672").execute().body(); + Rx rx = _RX.getById("latest", "53c44b0a102c1290262dce76").execute().body(); assertNotNull(rx); - assertEquals("ABT-751", rx.getName()); + assertEquals("Imatinib mesylate", rx.getName()); assertTrue(rx.getAlternateName().size() > 1); assertEquals(Rx.Type.DRUG, rx.getType()); assertNull(rx.getHistology()); - assertTrue(rx.getRemarks().startsWith("Phase II ALL")); + assertTrue(rx.getRemarks().startsWith("January 31, 2012")); assertNull(rx.getEvsId()); assertNull(rx.getAbbreviation()); assertEquals(Collections.singletonList("Chemotherapy"), rx.getCategory()); assertTrue(rx.getSubcategory().size() > 0); - assertNull(rx.getNscNumber()); + assertEquals(1, rx.getNscNumber().size()); assertNull(rx.getDrugs()); assertNull(rx.getRadiation()); assertNull(rx.getHidden()); @@ -72,7 +72,17 @@ void testRxById() throws IOException { assertNull(rx.getNote()); assertNull(rx.getFieldNotes()); assertNull(rx.getScore()); - assertEquals(Arrays.asList("neuroblastoma", "Pediatric ALL"), rx.getPrimarySite()); + assertEquals(Arrays.asList("aggressive mastocytosis", + "chronic eosinophilic leukemia", + "Colorectal", + "dermatofibrosarcoma protuberans", + "gastric", + "GIST", + "hypereosinophilic syndrome", + "leukemia", + "lung", + "other cancer", + "Ph+ALL"), rx.getPrimarySite()); assertNull(rx.getHistory()); } @@ -112,8 +122,8 @@ void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(12, results.getTotal().longValue()); - assertEquals(12, results.getResults().size()); + assertEquals(8, results.getTotal().longValue()); + assertEquals(8, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index f73b214..3339b15 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -51,7 +51,7 @@ void testExceptionMessages() throws IOException { // the API call works out to: // https://api.seer.cancer.gov/rest/recode/sitegroup?site=C379 - assertEquals("Required request parameter 'hist' for method parameter type String is not present", message); + assertEquals("Required parameter 'hist' is not present.", message); } @Test From f12fa60c92ddbd37c2c58ba927dc5ae3efd715ce Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 12 Jul 2023 14:40:53 -0400 Subject: [PATCH 208/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3b10954..6951dac 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.3 + 5.4 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.3' +compile 'com.imsweb:seerapi-client-java:5.4' ``` ## Usage diff --git a/build.gradle b/build.gradle index 1f535d9..ec68cb4 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.3' +version = '5.4' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 4ffe59407ae67c393fe7c737ddb29ea0bb5946f8 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 7 Aug 2024 13:54:06 -0400 Subject: [PATCH 209/243] Add missing rationale field --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 63375 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 19 +++++++++-------- gradlew.bat | 20 +++++++++--------- .../seerapi/client/staging/StagingTable.java | 10 +++++++++ 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/build.gradle b/build.gradle index ec68cb4..ecffcb7 100644 --- a/build.gradle +++ b/build.gradle @@ -125,7 +125,7 @@ tasks.named("dependencyUpdates").configure { } wrapper { - gradleVersion = '8.2.1' + gradleVersion = '8.8' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4cdf41af1ab109bc7f253b2b887023340..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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

NnX)EH+Nua)3Y(c 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≫L+crb^Bz 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 /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -201,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..25da30d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java index 8974947..8a78d78 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java @@ -22,6 +22,7 @@ public class StagingTable { private String _subtitle; private String _notes; private String _footnotes; + private String _rationale; private Date _lastModified; private List _definition; private Set _extraInput; @@ -108,6 +109,15 @@ public void setFootnotes(String footnotes) { _footnotes = footnotes; } + @JsonProperty("rationale") + public String getRationale() { + return _rationale; + } + + public void setRationale(String rationale) { + _rationale = rationale; + } + @JsonProperty("last_modified") public Date getLastModified() { return _lastModified; From 9e51906b118601e08ba9f1d8a9442338f5ab16d3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 7 Aug 2024 14:14:13 -0400 Subject: [PATCH 210/243] Unit test fixes --- .../imsweb/seerapi/client/mph/MphInput.java | 20 ------------------- .../imsweb/seerapi/client/mph/MphOutput.java | 13 +++++++----- .../seerapi/client/disease/DiseaseTest.java | 8 ++++---- .../seerapi/client/hcpcs/mph/MphTest.java | 15 ++++++++------ .../seerapi/client/naaccr/NaaccrTest.java | 2 +- .../com/imsweb/seerapi/client/rx/RxTest.java | 4 ++-- 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java b/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java index bab3fea..67c67cd 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphInput.java @@ -4,16 +4,6 @@ public class MphInput { - /** - * How to consider histology match, if it is strict 8000 is considered a different histology than 8010-9999 - * for rule : Do the tumors have ICD-O-3 histology codes that are different at the first (Xxxx), second (Xxxx), or third (xxXx) number? - * If lenient mode is on 8000 is considered as NOS and be considered to match any 8nnn histologies. - */ - public enum HistologyMatchMode { - STRICT, - LENIENT - } - @JsonProperty("primary_site") private String _primarySite; @JsonProperty("histology_icd_o3") @@ -32,8 +22,6 @@ public enum HistologyMatchMode { private String _dateOfDiagnosisMonth; @JsonProperty("date_of_diagnosis_day") private String _dateOfDiagnosisDay; - @JsonProperty("tx_status") - private String _txStatus; public String getPrimarySite() { return _primarySite; @@ -107,12 +95,4 @@ public void setDateOfDiagnosisDay(String dateOfDiagnosisDay) { _dateOfDiagnosisDay = dateOfDiagnosisDay; } - public String getTxStatus() { - return _txStatus; - } - - public void setTxStatus(String txStatus) { - _txStatus = txStatus; - } - } diff --git a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java index 079bf57..966b60b 100644 --- a/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java +++ b/src/main/java/com/imsweb/seerapi/client/mph/MphOutput.java @@ -8,14 +8,16 @@ public class MphOutput { @JsonProperty("result") private Result _result; - @JsonProperty("reason") - private String _reason; - @JsonProperty("applied_rules") - private List _appliedRules; @JsonProperty("group_id") private String _groupId; + @JsonProperty("group_name") + private String _groupName; @JsonProperty("step") private String _step; + @JsonProperty("reason") + private String _reason; + @JsonProperty("applied_rules") + private List _appliedRules; public Result getResult() { return _result; @@ -64,6 +66,7 @@ public enum Result { // indicates the two tumors are different primaries MULTIPLE_PRIMARIES, // indicates there is not enough information to make a proper determination - QUESTIONABLE + QUESTIONABLE, + INVALID_INPUT } } diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 4ff1dc1..01a9646 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -174,8 +174,8 @@ void testDiseaseSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(6, results.getTotal().longValue()); - assertEquals(6, results.getResults().size()); + assertEquals(5, results.getTotal().longValue()); + assertEquals(5, results.getResults().size()); assertEquals(Collections.singletonList("basophilic"), results.getTerms()); search.setSiteCategory("BAD_VALUE"); @@ -210,8 +210,8 @@ void testDiseaseSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(7, results.getTotal().longValue()); - assertEquals(7, results.getResults().size()); + assertEquals(6, results.getTotal().longValue()); + assertEquals(6, results.getResults().size()); assertEquals(Collections.singletonList("basophilic"), results.getTerms()); } diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java index 7a8a609..6149e5e 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/mph/MphTest.java @@ -14,6 +14,7 @@ import com.imsweb.seerapi.client.mph.MphInput; import com.imsweb.seerapi.client.mph.MphInputPair; import com.imsweb.seerapi.client.mph.MphOutput; +import com.imsweb.seerapi.client.mph.MphOutput.Result; import com.imsweb.seerapi.client.mph.MphRule; import com.imsweb.seerapi.client.mph.MphService; @@ -55,8 +56,9 @@ void testMissingSite() throws IOException { input2.setDateOfDiagnosisYear("2016"); input2.setLaterality("1"); - Call call = _MPH.mph(new MphInputPair(input1, input2)); - assertThrows(BadRequestException.class, call::execute); + MphOutput result = _MPH.mph(new MphInputPair(input1, input2)).execute().body(); + assertNotNull(result); + assertEquals(Result.INVALID_INPUT, result.getResult()); } @Test @@ -112,9 +114,9 @@ void testResults() throws IOException { assertEquals(MphOutput.Result.MULTIPLE_PRIMARIES, result.getResult()); assertEquals("mph_2007_to_2017_breast", result.getGroupId()); assertEquals("M5", result.getStep()); - assertEquals("Tumors diagnosed more than five (5) years apart are multiple primaries.", result.getReason()); + assertEquals("Tumors diagnosed more than 5 years apart are multiple primaries.", result.getReason()); assertEquals(2, result.getAppliedRules().size()); - assertEquals("Are there tumors diagnosed more than five (5) years apart?", result.getAppliedRules().get(1).getQuestion()); + assertEquals("Are there tumors diagnosed more than 5 years apart?", result.getAppliedRules().get(1).getQuestion()); } @Test @@ -160,8 +162,9 @@ void testInvalidInput() throws IOException { i1.setDateOfDiagnosisYear("2015"); i2.setDateOfDiagnosisYear("2015"); - Call call = _MPH.mph(new MphInputPair(i1, i2)); - assertThrows(BadRequestException.class, call::execute); + MphOutput result = _MPH.mph(new MphInputPair(i1, i2)).execute().body(); + assertNotNull(result); + assertEquals(MphOutput.Result.INVALID_INPUT, result.getResult()); } @Test diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index b238404..4172f7d 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -124,7 +124,7 @@ void testNaaccrXmlField() throws IOException { assertThat(name.getRecordTypes()).containsExactly("A", "M", "C", "I"); assertThat(name.getDataType()).isEqualTo("digits"); assertThat(name.getLength()).isEqualTo(2); - assertThat(name.getPadType()).isEqualTo("rightBlank"); + assertThat(name.getPadType()).isEqualTo("none"); assertThat(name.getTrimType()).isEqualTo("all"); assertThat(name.getAllowUnlimitedText()).isFalse(); assertThat(name.getDocumentation()).isNotEmpty(); diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 961ab13..a017fd5 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -122,8 +122,8 @@ void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(8, results.getTotal().longValue()); - assertEquals(8, results.getResults().size()); + assertEquals(7, results.getTotal().longValue()); + assertEquals(7, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); From 0f1aff2ebf5cf862872be486ac966643b8af1239 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 7 Aug 2024 14:20:54 -0400 Subject: [PATCH 211/243] Force build --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ec68cb4..e1f2d58 100644 --- a/build.gradle +++ b/build.gradle @@ -216,4 +216,4 @@ javadoc { nexusStaging { numberOfRetries = 50 delayBetweenRetriesInMillis = 5000 -} \ No newline at end of file +} From 17037d6033a4ddcb5438b7b3051b63c953f0cd7e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 7 Aug 2024 14:31:03 -0400 Subject: [PATCH 212/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6951dac..e3478a1 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.4 + 5.5 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.4' +compile 'com.imsweb:seerapi-client-java:5.5' ``` ## Usage diff --git a/build.gradle b/build.gradle index 8363592..149c4ed 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.4' +version = '5.5' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 72dc86291ec0b0ef3211557595c5cf0c3b204d42 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 7 Aug 2024 15:29:22 -0400 Subject: [PATCH 213/243] Forgot two other table fields --- .../seerapi/client/staging/StagingTable.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java index 8a78d78..896c84a 100644 --- a/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java +++ b/src/main/java/com/imsweb/seerapi/client/staging/StagingTable.java @@ -23,6 +23,8 @@ public class StagingTable { private String _notes; private String _footnotes; private String _rationale; + private String additionalInfo; + private String codingGuidelines; private Date _lastModified; private List _definition; private Set _extraInput; @@ -118,6 +120,24 @@ public void setRationale(String rationale) { _rationale = rationale; } + @JsonProperty("additional_info") + public String getAdditionalInfo() { + return additionalInfo; + } + + public void setAdditionalInfo(String additionalInfo) { + this.additionalInfo = additionalInfo; + } + + @JsonProperty("coding_guidelines") + public String getCodingGuidelines() { + return codingGuidelines; + } + + public void setCodingGuidelines(String codingGuidelines) { + this.codingGuidelines = codingGuidelines; + } + @JsonProperty("last_modified") public Date getLastModified() { return _lastModified; From a0157bcac71104981465ac440f105286cfd575d5 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 7 Aug 2024 15:38:06 -0400 Subject: [PATCH 214/243] Prepare for release --- README.md | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e3478a1..17ae11e 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.5 + 5.6 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.5' +compile 'com.imsweb:seerapi-client-java:5.6' ``` ## Usage diff --git a/build.gradle b/build.gradle index 149c4ed..fce364c 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.5' +version = '5.6' description = 'Java client library for SEER*API' tasks.withType(JavaCompile) { From 25c74c25705d897a0f7c1f2a71ae20ce27c3ec7a Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 10 Sep 2024 07:52:07 -0400 Subject: [PATCH 215/243] Adding comparison test --- .../seerapi/compare/ComparisonTest.java | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java new file mode 100644 index 0000000..89cb7c2 --- /dev/null +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2024 Information Management Services, Inc. + */ +package com.imsweb.seerapi.compare; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.hcpcs.Hcpcs; +import com.imsweb.seerapi.client.hcpcs.HcpcsService; +import com.imsweb.seerapi.client.ndc.NdcProduct; +import com.imsweb.seerapi.client.ndc.NdcService; +import com.imsweb.seerapi.client.staging.StagingSchema; +import com.imsweb.seerapi.client.staging.StagingSchemaInfo; +import com.imsweb.seerapi.client.staging.StagingService; +import com.imsweb.seerapi.client.staging.StagingTable; + +import static org.assertj.core.api.Assertions.assertThat; + +@Disabled("Only for manual testing") +class ComparisonTest { + + private static final String PROD_URL = "https://api.seer.cancer.gov/rest/"; + private static final String LOCAL_URL = "http://localhost:8080/rest/"; + + private String getApiKey() { + return System.getenv("TESTING_API_KEY"); + } + + @Test + void testNdc() throws IOException { + NdcService ndcProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().ndc(); + NdcService ndcLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().ndc(); + + long page = 1; + + Map params = new HashMap<>(); + params.put("page", String.valueOf(page)); + params.put("per_page", "100"); + params.put("order", "ndc"); + List prodList = ndcProd.search(params).execute().body(); + List localList = ndcLocal.search(params).execute().body(); + + while (!Objects.requireNonNull(prodList).isEmpty() && !Objects.requireNonNull(localList).isEmpty()) { + assertThat(localList) + .hasSameSizeAs(prodList) // Ensure both lists have the same size + .usingRecursiveComparison() + .isEqualTo(prodList); + + System.out.println("NDC page " + page); + + page += 1; + params.put("page", String.valueOf(page)); + prodList = ndcProd.search(params).execute().body(); + localList = ndcLocal.search(params).execute().body(); + } + } + + @Test + void testHcpcs() throws IOException { + HcpcsService hcpcsProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().hcpcs(); + HcpcsService hcpcsLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().hcpcs(); + + long page = 1; + + Map params = new HashMap<>(); + params.put("page", String.valueOf(page)); + params.put("per_page", "100"); + params.put("order", "hcpcs_code"); + + List prodList = hcpcsProd.search(params).execute().body(); + List localList = hcpcsLocal.search(params).execute().body(); + + while (!Objects.requireNonNull(prodList).isEmpty()) { + System.out.println("HCPCS page " + page); + assertThat(localList) + .hasSameSizeAs(prodList) // Ensure both lists have the same size + .usingRecursiveComparison() + .ignoringCollectionOrderInFields("categories") + .isEqualTo(prodList); + + page += 1; + params.put("page", String.valueOf(page)); + prodList = hcpcsProd.search(params).execute().body(); + localList = hcpcsLocal.search(params).execute().body(); + } + } + + private Map getAlgorithmVersions() { + Map versions = new LinkedHashMap<>(); + + versions.put("pediatric", "1.2"); + versions.put("eod_public", "3.2"); + versions.put("tnm", "2.0"); + versions.put("cs", "02.05.50"); + + return versions; + } + + @Test + void testStagingSchemas() throws IOException { + StagingService stagingProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService stagingLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + + Map algorithmMap = getAlgorithmVersions(); + for (String algorithmId : algorithmMap.keySet()) { + String algorithmVersion = algorithmMap.get(algorithmId); + + System.out.println("Getting list of all schemas in " + algorithmId + ":" + algorithmVersion); + + List prodSchemas = stagingProd.schemas(algorithmId, algorithmVersion).execute().body(); + List localSchemas = stagingLocal.schemas(algorithmId, algorithmVersion).execute().body(); + + assertThat(localSchemas) + .hasSameSizeAs(prodSchemas) // Ensure both lists have the same size + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(prodSchemas); + + for (StagingSchemaInfo prodSchema : Objects.requireNonNull(prodSchemas)) { + StagingSchema prod = stagingProd.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); + StagingSchema local = stagingLocal.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); + + System.out.println("Comparing [" + algorithmId + ":" + algorithmVersion + "] schema " + prodSchema.getId()); + + assertThat(local) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .withComparatorForType( + (date1, date2) -> { + // ignore milliseconds when comparing two Date objects + long time1 = date1.getTime() / 1000; + long time2 = date2.getTime() / 1000; + return Long.compare(time1, time2); + }, + Date.class + ) + .isEqualTo(prod); + } + } + } + + @Test + void testStagingTables() throws IOException { + StagingService stagingProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService stagingLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + + Map algorithmMap = getAlgorithmVersions(); + for (String algorithmId : algorithmMap.keySet()) { + String algorithmVersion = algorithmMap.get(algorithmId); + + System.out.println("Getting list of all tables in " + algorithmId + ":" + algorithmVersion); + + List prodTables = stagingProd.tables(algorithmId, algorithmVersion).execute().body(); + List localTables = stagingLocal.tables(algorithmId, algorithmVersion).execute().body(); + + assertThat(localTables) + .hasSameSizeAs(prodTables) // Ensure both lists have the same size + .usingRecursiveComparison() + .ignoringCollectionOrder() + .isEqualTo(prodTables); + + for (StagingTable prodTable : Objects.requireNonNull(prodTables)) { + StagingTable prod = stagingProd.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); + StagingTable local = stagingLocal.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); + + System.out.println("Comparing [" + algorithmId + ":" + algorithmVersion + "] table " + prodTable.getId()); + + assertThat(local) + .usingRecursiveComparison() + .withComparatorForType( + (date1, date2) -> { + // ignore milliseconds when comparing two Date objects + long time1 = date1.getTime() / 1000; + long time2 = date2.getTime() / 1000; + return Long.compare(time1, time2); + }, + Date.class + ) + .isEqualTo(prod); + } + } + } +} From ece2d2c86dd37cf7707829a2802ef75465b0fb43 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 10 Sep 2024 08:58:04 -0400 Subject: [PATCH 216/243] Added glossary comparison --- .../seerapi/compare/ComparisonTest.java | 109 ++++++++++++++---- 1 file changed, 85 insertions(+), 24 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java index 89cb7c2..271ba7b 100644 --- a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -4,6 +4,7 @@ package com.imsweb.seerapi.compare; import java.io.IOException; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; @@ -15,6 +16,9 @@ import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.glossary.Glossary; +import com.imsweb.seerapi.client.glossary.GlossarySearchResults; +import com.imsweb.seerapi.client.glossary.GlossaryService; import com.imsweb.seerapi.client.hcpcs.Hcpcs; import com.imsweb.seerapi.client.hcpcs.HcpcsService; import com.imsweb.seerapi.client.ndc.NdcProduct; @@ -38,8 +42,8 @@ private String getApiKey() { @Test void testNdc() throws IOException { - NdcService ndcProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().ndc(); - NdcService ndcLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().ndc(); + NdcService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().ndc(); + NdcService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().ndc(); long page = 1; @@ -47,8 +51,8 @@ void testNdc() throws IOException { params.put("page", String.valueOf(page)); params.put("per_page", "100"); params.put("order", "ndc"); - List prodList = ndcProd.search(params).execute().body(); - List localList = ndcLocal.search(params).execute().body(); + List prodList = prodService.search(params).execute().body(); + List localList = localService.search(params).execute().body(); while (!Objects.requireNonNull(prodList).isEmpty() && !Objects.requireNonNull(localList).isEmpty()) { assertThat(localList) @@ -60,15 +64,15 @@ void testNdc() throws IOException { page += 1; params.put("page", String.valueOf(page)); - prodList = ndcProd.search(params).execute().body(); - localList = ndcLocal.search(params).execute().body(); + prodList = prodService.search(params).execute().body(); + localList = localService.search(params).execute().body(); } } @Test void testHcpcs() throws IOException { - HcpcsService hcpcsProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().hcpcs(); - HcpcsService hcpcsLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().hcpcs(); + HcpcsService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().hcpcs(); + HcpcsService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().hcpcs(); long page = 1; @@ -77,8 +81,8 @@ void testHcpcs() throws IOException { params.put("per_page", "100"); params.put("order", "hcpcs_code"); - List prodList = hcpcsProd.search(params).execute().body(); - List localList = hcpcsLocal.search(params).execute().body(); + List prodList = prodService.search(params).execute().body(); + List localList = localService.search(params).execute().body(); while (!Objects.requireNonNull(prodList).isEmpty()) { System.out.println("HCPCS page " + page); @@ -90,8 +94,8 @@ void testHcpcs() throws IOException { page += 1; params.put("page", String.valueOf(page)); - prodList = hcpcsProd.search(params).execute().body(); - localList = hcpcsLocal.search(params).execute().body(); + prodList = prodService.search(params).execute().body(); + localList = localService.search(params).execute().body(); } } @@ -108,8 +112,8 @@ private Map getAlgorithmVersions() { @Test void testStagingSchemas() throws IOException { - StagingService stagingProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); - StagingService stagingLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); Map algorithmMap = getAlgorithmVersions(); for (String algorithmId : algorithmMap.keySet()) { @@ -117,8 +121,8 @@ void testStagingSchemas() throws IOException { System.out.println("Getting list of all schemas in " + algorithmId + ":" + algorithmVersion); - List prodSchemas = stagingProd.schemas(algorithmId, algorithmVersion).execute().body(); - List localSchemas = stagingLocal.schemas(algorithmId, algorithmVersion).execute().body(); + List prodSchemas = prodService.schemas(algorithmId, algorithmVersion).execute().body(); + List localSchemas = localService.schemas(algorithmId, algorithmVersion).execute().body(); assertThat(localSchemas) .hasSameSizeAs(prodSchemas) // Ensure both lists have the same size @@ -127,8 +131,8 @@ void testStagingSchemas() throws IOException { .isEqualTo(prodSchemas); for (StagingSchemaInfo prodSchema : Objects.requireNonNull(prodSchemas)) { - StagingSchema prod = stagingProd.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); - StagingSchema local = stagingLocal.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); + StagingSchema prod = prodService.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); + StagingSchema local = localService.schemaById(algorithmId, algorithmVersion, prodSchema.getId()).execute().body(); System.out.println("Comparing [" + algorithmId + ":" + algorithmVersion + "] schema " + prodSchema.getId()); @@ -151,8 +155,8 @@ void testStagingSchemas() throws IOException { @Test void testStagingTables() throws IOException { - StagingService stagingProd = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); - StagingService stagingLocal = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); Map algorithmMap = getAlgorithmVersions(); for (String algorithmId : algorithmMap.keySet()) { @@ -160,8 +164,8 @@ void testStagingTables() throws IOException { System.out.println("Getting list of all tables in " + algorithmId + ":" + algorithmVersion); - List prodTables = stagingProd.tables(algorithmId, algorithmVersion).execute().body(); - List localTables = stagingLocal.tables(algorithmId, algorithmVersion).execute().body(); + List prodTables = prodService.tables(algorithmId, algorithmVersion).execute().body(); + List localTables = localService.tables(algorithmId, algorithmVersion).execute().body(); assertThat(localTables) .hasSameSizeAs(prodTables) // Ensure both lists have the same size @@ -170,8 +174,8 @@ void testStagingTables() throws IOException { .isEqualTo(prodTables); for (StagingTable prodTable : Objects.requireNonNull(prodTables)) { - StagingTable prod = stagingProd.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); - StagingTable local = stagingLocal.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); + StagingTable prod = prodService.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); + StagingTable local = localService.tableById(algorithmId, algorithmVersion, prodTable.getId()).execute().body(); System.out.println("Comparing [" + algorithmId + ":" + algorithmVersion + "] table " + prodTable.getId()); @@ -190,4 +194,61 @@ void testStagingTables() throws IOException { } } } + + @Test + void testGlossary() throws IOException { + GlossaryService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().glossary(); + GlossaryService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().glossary(); + + Map params = new HashMap<>(); + + long offset = 0; + long perPage = 100; + params.put("offset", String.valueOf(offset)); + params.put("count", String.valueOf(perPage)); + + // get a list of ids + List ids = new ArrayList<>(); + + System.out.println("Collecting identifiers for glossary 'latest' version"); + + GlossarySearchResults prod = prodService.search("latest", params).execute().body(); + + while (Objects.requireNonNull(prod).getResults() != null && !prod.getResults().isEmpty()) { + for (Glossary glossary : prod.getResults()) + ids.add(glossary.getId()); + + offset += perPage; + params.put("offset", String.valueOf(offset)); + + prod = prodService.search("latest", params).execute().body(); + } + + System.out.println("Found " + ids.size() + " identifiers for glossary 'latest' version"); + + for (String id : ids) { + System.out.println("Comparing " + id); + Glossary prodGlossary = prodService.getById("latest", id).execute().body(); + Glossary localGlossary = localService.getById("latest", id).execute().body(); + + assertThat(localGlossary) + .usingRecursiveComparison() + .withComparatorForType( + (value1, value2) -> { + // Treat null and empty string as equal + if (value1 == null && "".equals(value2) || "".equals(value1) && value2 == null) { + return 0; // Consider them equal + } + if (value1 == null) + return -1; + if (value2 == null) + return 1; + return value1.compareTo(value2); + }, + String.class // Apply to all String fields, including in lists + ) + .isEqualTo(prodGlossary); + } + } + } From 158cfdbf46aaf9e2340a4956c4662a2a0d1de05d Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 10 Sep 2024 09:47:19 -0400 Subject: [PATCH 217/243] Added disease comparison (and found a BIG bug!) --- .../seerapi/compare/ComparisonTest.java | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java index 271ba7b..b1819e9 100644 --- a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -16,6 +16,9 @@ import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; +import com.imsweb.seerapi.client.disease.Disease; +import com.imsweb.seerapi.client.disease.DiseaseSearchResults; +import com.imsweb.seerapi.client.disease.DiseaseService; import com.imsweb.seerapi.client.glossary.Glossary; import com.imsweb.seerapi.client.glossary.GlossarySearchResults; import com.imsweb.seerapi.client.glossary.GlossaryService; @@ -23,6 +26,9 @@ import com.imsweb.seerapi.client.hcpcs.HcpcsService; import com.imsweb.seerapi.client.ndc.NdcProduct; import com.imsweb.seerapi.client.ndc.NdcService; +import com.imsweb.seerapi.client.rx.Rx; +import com.imsweb.seerapi.client.rx.RxSearchResults; +import com.imsweb.seerapi.client.rx.RxService; import com.imsweb.seerapi.client.staging.StagingSchema; import com.imsweb.seerapi.client.staging.StagingSchemaInfo; import com.imsweb.seerapi.client.staging.StagingService; @@ -251,4 +257,101 @@ void testGlossary() throws IOException { } } + @Test + void testRx() throws IOException { + RxService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().rx(); + RxService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().rx(); + + Map params = new HashMap<>(); + + long offset = 0; + long perPage = 100; + params.put("offset", String.valueOf(offset)); + params.put("count", String.valueOf(perPage)); + + // get a list of ids + List ids = new ArrayList<>(); + + System.out.println("Collecting identifiers for rx 'latest' version"); + + RxSearchResults prod = prodService.search("latest", params).execute().body(); + + while (Objects.requireNonNull(prod).getResults() != null && !prod.getResults().isEmpty()) { + for (Rx rx : prod.getResults()) + ids.add(rx.getId()); + + offset += perPage; + params.put("offset", String.valueOf(offset)); + + prod = prodService.search("latest", params).execute().body(); + } + + System.out.println("Found " + ids.size() + " identifiers for rx 'latest' version"); + + for (String id : ids) { + System.out.println("Comparing " + id); + Rx prodRx = prodService.getById("latest", id).execute().body(); + Rx localRx = localService.getById("latest", id).execute().body(); + + assertThat(localRx) + .usingRecursiveComparison() + .isEqualTo(prodRx); + } + } + + @Test + void testDisease() throws IOException { + DiseaseService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().disease(); + DiseaseService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().disease(); + + Map params = new HashMap<>(); + + long offset = 0; + long perPage = 100; + params.put("offset", String.valueOf(offset)); + params.put("count", String.valueOf(perPage)); + + // get a list of ids + List ids = new ArrayList<>(); + + System.out.println("Collecting identifiers for disease 'latest' version"); + + DiseaseSearchResults prod = prodService.search("latest", params).execute().body(); + + while (Objects.requireNonNull(prod).getResults() != null && !prod.getResults().isEmpty()) { + for (Disease disease : prod.getResults()) + ids.add(disease.getId()); + + offset += perPage; + params.put("offset", String.valueOf(offset)); + + prod = prodService.search("latest", params).execute().body(); + } + + System.out.println("Found " + ids.size() + " identifiers for disease 'latest' version"); + + for (String id : ids) { + System.out.println("Comparing " + id); + Disease prodDisease = prodService.getById("latest", id).execute().body(); + Disease localDisease = localService.getById("latest", id).execute().body(); + + assertThat(localDisease) + .usingRecursiveComparison() + .withComparatorForType( + (value1, value2) -> { + // Treat null and empty string as equal + if (value1 == null && "".equals(value2) || "".equals(value1) && value2 == null) { + return 0; // Consider them equal + } + if (value1 == null) + return -1; + if (value2 == null) + return 1; + return value1.compareTo(value2); + }, + String.class // Apply to all String fields, including in lists + ) + .isEqualTo(prodDisease); + } + } } From 1abb5754d112d7959510f5960faada2904fe9a3e Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 10 Sep 2024 10:21:01 -0400 Subject: [PATCH 218/243] Cleanup --- .../seerapi/compare/ComparisonTest.java | 37 ++++--------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java index b1819e9..0f4d2e6 100644 --- a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -52,6 +52,7 @@ void testNdc() throws IOException { NdcService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().ndc(); long page = 1; + long processed = 0; Map params = new HashMap<>(); params.put("page", String.valueOf(page)); @@ -61,12 +62,13 @@ void testNdc() throws IOException { List localList = localService.search(params).execute().body(); while (!Objects.requireNonNull(prodList).isEmpty() && !Objects.requireNonNull(localList).isEmpty()) { + processed += prodList.size(); assertThat(localList) .hasSameSizeAs(prodList) // Ensure both lists have the same size .usingRecursiveComparison() .isEqualTo(prodList); - System.out.println("NDC page " + page); + System.out.println("NDC page " + page + " (processed " + processed + " so far)"); page += 1; params.put("page", String.valueOf(page)); @@ -80,6 +82,7 @@ void testHcpcs() throws IOException { HcpcsService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().hcpcs(); HcpcsService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().hcpcs(); + long processed = 0; long page = 1; Map params = new HashMap<>(); @@ -91,7 +94,9 @@ void testHcpcs() throws IOException { List localList = localService.search(params).execute().body(); while (!Objects.requireNonNull(prodList).isEmpty()) { - System.out.println("HCPCS page " + page); + processed += prodList.size(); + System.out.println("HCPCS page " + page + " (processed " + processed + " so far)"); + assertThat(localList) .hasSameSizeAs(prodList) // Ensure both lists have the same size .usingRecursiveComparison() @@ -239,20 +244,6 @@ void testGlossary() throws IOException { assertThat(localGlossary) .usingRecursiveComparison() - .withComparatorForType( - (value1, value2) -> { - // Treat null and empty string as equal - if (value1 == null && "".equals(value2) || "".equals(value1) && value2 == null) { - return 0; // Consider them equal - } - if (value1 == null) - return -1; - if (value2 == null) - return 1; - return value1.compareTo(value2); - }, - String.class // Apply to all String fields, including in lists - ) .isEqualTo(prodGlossary); } } @@ -337,20 +328,6 @@ void testDisease() throws IOException { assertThat(localDisease) .usingRecursiveComparison() - .withComparatorForType( - (value1, value2) -> { - // Treat null and empty string as equal - if (value1 == null && "".equals(value2) || "".equals(value1) && value2 == null) { - return 0; // Consider them equal - } - if (value1 == null) - return -1; - if (value2 == null) - return 1; - return value1.compareTo(value2); - }, - String.class // Apply to all String fields, including in lists - ) .isEqualTo(prodDisease); } } From ca4d5c9df186e8503008d4b76502788e6004ee1d Mon Sep 17 00:00:00 2001 From: Chuck May Date: Tue, 10 Sep 2024 11:24:20 -0400 Subject: [PATCH 219/243] Add comparison of staging algorithms and versions --- .../seerapi/compare/ComparisonTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java index 0f4d2e6..596854c 100644 --- a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -29,10 +29,12 @@ import com.imsweb.seerapi.client.rx.Rx; import com.imsweb.seerapi.client.rx.RxSearchResults; import com.imsweb.seerapi.client.rx.RxService; +import com.imsweb.seerapi.client.staging.StagingAlgorithm; import com.imsweb.seerapi.client.staging.StagingSchema; import com.imsweb.seerapi.client.staging.StagingSchemaInfo; import com.imsweb.seerapi.client.staging.StagingService; import com.imsweb.seerapi.client.staging.StagingTable; +import com.imsweb.seerapi.client.staging.StagingVersion; import static org.assertj.core.api.Assertions.assertThat; @@ -121,6 +123,30 @@ private Map getAlgorithmVersions() { return versions; } + @Test + void testStagingAlgorithmsAndVersions() throws IOException { + StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); + StagingService localService = new SeerApi.Builder().url(LOCAL_URL).apiKey(getApiKey()).connect().staging(); + + List prodAlgorithms = prodService.algorithms().execute().body(); + List localAlgorithms = localService.algorithms().execute().body(); + + assertThat(localAlgorithms) + .hasSameSizeAs(prodAlgorithms) // Ensure both lists have the same size + .usingRecursiveComparison() + .isEqualTo(prodAlgorithms); + + for (StagingAlgorithm algorithm : Objects.requireNonNull(prodAlgorithms)) { + List prodVersions = prodService.versions(algorithm.getAlgorithm()).execute().body(); + List localVersions = localService.versions(algorithm.getAlgorithm()).execute().body(); + + assertThat(localVersions) + .hasSameSizeAs(prodVersions) + .usingRecursiveComparison() + .isEqualTo(prodVersions); + } + } + @Test void testStagingSchemas() throws IOException { StagingService prodService = new SeerApi.Builder().url(PROD_URL).apiKey(getApiKey()).connect().staging(); From 07c6700a197cd849fad143982816f338826464f3 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Wed, 11 Sep 2024 13:55:54 -0400 Subject: [PATCH 220/243] Limit NDC to 10,000 --- src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java index 596854c..45a9f4e 100644 --- a/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java +++ b/src/test/java/com/imsweb/seerapi/compare/ComparisonTest.java @@ -76,6 +76,10 @@ void testNdc() throws IOException { params.put("page", String.valueOf(page)); prodList = prodService.search(params).execute().body(); localList = localService.search(params).execute().body(); + + // there are way too many entities; limit to 10,000 + if (processed >= 10_000) + break; } } From d29ab11bd6fd97f726c508ab7272e553706f9010 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 31 Oct 2024 09:14:55 -0400 Subject: [PATCH 221/243] Support changes from recode endpoint --- .../client/siterecode/SiteGroupAlgorithm.java | 50 +++++++++++++++++++ .../seerapi/client/siterecode/SiteRecode.java | 10 ++++ .../client/siterecode/SiteRecodeService.java | 21 ++++---- .../imsweb/seerapi/client/SeerApiTest.java | 10 ++-- .../seerapi/client/disease/DiseaseTest.java | 17 ++++--- .../seerapi/client/glossary/GlossaryTest.java | 38 ++------------ .../client/hcpcs/HcpcsServiceTest.java | 3 +- .../com/imsweb/seerapi/client/rx/RxTest.java | 11 ++-- .../client/siterecode/SiteRecodeTest.java | 40 ++++++++++----- 9 files changed, 124 insertions(+), 76 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java diff --git a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java new file mode 100644 index 0000000..3d7a72e --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteGroupAlgorithm.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 Information Management Services, Inc. + */ +package com.imsweb.seerapi.client.siterecode; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SiteGroupAlgorithm { + + private String id; + private String name; + private String version; + @JsonProperty("required_input") + private List requiredInput; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public List getRequiredInput() { + return requiredInput; + } + + public void setRequiredInput(List requiredInput) { + this.requiredInput = requiredInput; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java index 64e4686..38e711c 100644 --- a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java +++ b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecode.java @@ -11,6 +11,8 @@ public class SiteRecode { protected String _site; @JsonProperty("hist") protected String _hist; + @JsonProperty("behavior") + protected String _behavior; @JsonProperty("site_group") protected String _siteGroup; @@ -30,6 +32,14 @@ public void setHist(String hist) { _hist = hist; } + public String getBehavior() { + return _behavior; + } + + public void setBehavior(String behavior) { + _behavior = behavior; + } + public String getSiteGroup() { return _siteGroup; } diff --git a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java index 0ae0956..125df9b 100644 --- a/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java +++ b/src/main/java/com/imsweb/seerapi/client/siterecode/SiteRecodeService.java @@ -3,28 +3,31 @@ */ package com.imsweb.seerapi.client.siterecode; +import java.util.List; + import retrofit2.Call; import retrofit2.http.GET; +import retrofit2.http.Path; import retrofit2.http.Query; -import com.imsweb.seerapi.client.shared.Version; - public interface SiteRecodeService { /** - * Return the version of the SEER Site Recode database. - * @return a String representing the database version + * Return the supported algorithms and versions + * @return a list of information about the algorithms */ - @GET("recode/version") - Call version(); + @GET("recode/sitegroup/algorithms") + Call> algorithms(); /** - * Return the SEER Site Group for the site/histology combination, or 99999 if the combination is unknown. + * Return the specified algorithm site group for the site/histology/behavior combination, or 99999 if the combination is unknown. + * @param algorithm site group algorithm * @param site Primary Site O3 * @param hist Histology O3 + * @param behavior Behavior O3 * @return a SiteRecode object based on the site and histology */ - @GET("recode/sitegroup") - Call siteGroup(@Query("site") String site, @Query("hist") String hist); + @GET("recode/sitegroup/{algorithm}") + Call siteGroup(@Path("algorithm") String algorithm, @Query("site") String site, @Query("hist") String hist, @Query("behavior") String behavior); } diff --git a/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java b/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java index 38c28be..48f5ed6 100644 --- a/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java +++ b/src/test/java/com/imsweb/seerapi/client/SeerApiTest.java @@ -3,13 +3,13 @@ */ package com.imsweb.seerapi.client; -import java.io.IOException; +import java.util.List; import org.junit.jupiter.api.Test; import retrofit2.Call; -import com.imsweb.seerapi.client.shared.Version; +import com.imsweb.seerapi.client.siterecode.SiteGroupAlgorithm; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -17,13 +17,13 @@ class SeerApiTest { @Test void testBadApiKeyAndURL() { - Call call = new SeerApi.Builder().url("https://api.seer.cancer.gov/rest/").apiKey("BAD KEY").connect().siteRecode().version(); + Call> call = new SeerApi.Builder().url("https://api.seer.cancer.gov/rest/").apiKey("BAD KEY").connect().siteRecode().algorithms(); assertThrows(NotAuthorizedException.class, call::execute); } @Test - void testBadApiKey() throws IOException { - Call call = new SeerApi.Builder().apiKey("BAD KEY").connect().siteRecode().version(); + void testBadApiKey() { + Call> call = new SeerApi.Builder().apiKey("BAD KEY").connect().siteRecode().algorithms(); assertThrows(NotAuthorizedException.class, call::execute); } diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 01a9646..a12f1d6 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -18,6 +18,7 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -54,7 +55,7 @@ void testDiseasePrimarySites() throws IOException { List sites = _DISEASE.primarySites().execute().body(); assertNotNull(sites); - assertTrue(sites.size() > 0); + assertFalse(sites.isEmpty()); assertEquals("C000", sites.get(0).getValue()); assertEquals("External upper lip", sites.get(0).getLabel()); } @@ -64,7 +65,7 @@ void testDiseasePrimarySiteCode() throws IOException { List sites = _DISEASE.primarySiteCode("C021").execute().body(); assertNotNull(sites); - assertTrue(sites.size() > 0); + assertFalse(sites.isEmpty()); assertEquals("C021", sites.get(0).getValue()); assertEquals("Border of tongue", sites.get(0).getLabel()); } @@ -74,7 +75,7 @@ void testDiseaseSiteCateogires() throws IOException { List categories = _DISEASE.siteCategories().execute().body(); assertNotNull(categories); - assertTrue(categories.size() > 0); + assertFalse(categories.isEmpty()); assertEquals("head-and-neck", categories.get(0).getId()); assertEquals("Head and Neck", categories.get(0).getLabel()); assertEquals(2, categories.get(0).getSites().size()); @@ -91,7 +92,7 @@ void testDiseaseById() throws IOException { assertEquals("Pure erythroid leukemia", disease.getName()); assertEquals(Disease.Type.HEMATO, disease.getType()); assertEquals("9840/3", disease.getIcdO3Morphology()); - assertTrue(disease.getSamePrimaries().size() > 0); + assertFalse(disease.getSamePrimaries().isEmpty()); assertNotNull(disease.getId()); assertEquals("latest", disease.getVersion()); @@ -115,7 +116,7 @@ void testDiseaseById() throws IOException { assertEquals(1, disease.getAbstractorNote().size()); assertEquals(2, disease.getTreatment().size()); assertNull(disease.getGenetics()); - assertTrue(disease.getAlternateName().size() > 0); + assertFalse(disease.getAlternateName().isEmpty()); assertEquals("Acute erythremia", disease.getAlternateName().get(0).getValue()); assertTrue(disease.getIcdO2Morphology().contains("9840/3")); assertTrue(disease.getIcdO1Morphology().contains("9840/3")); @@ -228,7 +229,7 @@ void testDiseaseSearchIterate() throws IOException { DiseaseSearchResults results = _DISEASE.search("latest", search.paramMap()).execute().body(); assertNotNull(results); assertTrue(results.getTotal() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); // the first time through, set the total if (total == null) @@ -276,8 +277,8 @@ void testDiseaseChangelog() throws IOException { assertEquals("Initial migration", changelog.getDescription()); DiseaseChangelogEntry entry = changelog.getAdds().get(0); - assertTrue(entry.getId().length() > 0); - assertTrue(entry.getName().length() > 0); + assertFalse(entry.getId().isEmpty()); + assertFalse(entry.getName().isEmpty()); assertNull(entry.getOldVersion()); assertNull(entry.getNewVersion()); } diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index 48310c5..65bd6e2 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -22,6 +22,7 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static com.imsweb.seerapi.client.glossary.Glossary.Category.GENERAL; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -72,37 +73,6 @@ void testGlossaryById() throws IOException { assertNull(glossary.getHistory()); } - @Test - void testGlossaryChangelog() throws IOException { - GlossaryChangelogResults results = _GLOSSARY.changelogs("latest", null, null, 1).execute().body(); - - assertNotNull(results); - - // TODO since all the glossary items were removed from the production database, this needs to be commented out; it will return when they are published again - - /* - Assert.assertEquals(1, changes.size()); - - GlossaryChangelog changelog = changes.get(0); - - Assert.assertNotNull(changelog.getUser()); - Assert.assertEquals("latest_dev", changelog.getVersion()); - Assert.assertTrue(changelog.getId().length() > 0); - Assert.assertTrue(changelog.getAdds().size() > 0); - - GlossaryChangelogEntry entry = changelog.getAdds().get(0); - Assert.assertTrue(entry.getId().length() > 0); - Assert.assertTrue(entry.getName().length() > 0); - Assert.assertNull(entry.getOldVersion()); - Assert.assertNull(entry.getNewVersion()); - - Assert.assertNull(changelog.getMods()); - Assert.assertNull(changelog.getDeletes()); - Assert.assertNotNull(changelog.getDate()); - Assert.assertEquals("Initial migration", changelog.getDescription()); - */ - } - @Test void testGlossarySearch() throws IOException { String term = "killer"; @@ -113,7 +83,7 @@ void testGlossarySearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); assertTrue(results.getTotal().longValue() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); assertEquals(Collections.singletonList(term), results.getTerms()); // add the category and verify there are no results @@ -130,7 +100,7 @@ void testGlossarySearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); assertTrue(results.getTotal().longValue() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); assertEquals(Collections.singletonList(term), results.getTerms()); } @@ -147,7 +117,7 @@ void testGlossarySearchIterate() throws IOException { GlossarySearchResults results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.HEMATO)).execute().body(); assertNotNull(results); assertTrue(results.getTotal() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); // the first time through, set the total if (total == null) diff --git a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java index 3d5b47b..90b4401 100644 --- a/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java +++ b/src/test/java/com/imsweb/seerapi/client/hcpcs/HcpcsServiceTest.java @@ -93,8 +93,7 @@ void testSearch() throws IOException { assertThat(results).hasSize(2); assertThat(results).extracting("hcpcsCode").contains("J9207", "C9240"); - // TODO the scores should be coming back from the API but are not; waiting on API fix - //assertThat(Objects.requireNonNull(results).get(0).getScore()).isGreaterThan(0); + assertThat(Objects.requireNonNull(results).get(0).getScore()).isPositive(); // test categories params.put("category", Category.CHEMOTHERAPY.toString()); diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index a017fd5..6834468 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -20,6 +20,7 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -59,7 +60,7 @@ void testRxById() throws IOException { assertNull(rx.getEvsId()); assertNull(rx.getAbbreviation()); assertEquals(Collections.singletonList("Chemotherapy"), rx.getCategory()); - assertTrue(rx.getSubcategory().size() > 0); + assertFalse(rx.getSubcategory().isEmpty()); assertEquals(1, rx.getNscNumber().size()); assertNull(rx.getDrugs()); assertNull(rx.getRadiation()); @@ -103,14 +104,14 @@ void testRxChangelog() throws IOException { assertNotNull(changelog.getUser()); assertEquals("latest", changelog.getVersion()); assertNull(changelog.getAdds()); - assertTrue(changelog.getMods().size() > 0); + assertFalse(changelog.getMods().isEmpty()); assertNull(changelog.getDeletes()); assertNotNull(changelog.getDate()); assertNull(changelog.getDescription()); RxChangelogEntry entry = changelog.getMods().get(0); - assertTrue(entry.getId().length() > 0); - assertTrue(entry.getName().length() > 0); + assertFalse(entry.getId().isEmpty()); + assertFalse(entry.getName().isEmpty()); assertNotNull(entry.getOldVersion()); assertNotNull(entry.getNewVersion()); } @@ -159,7 +160,7 @@ void testRxSearchIterate() throws IOException { RxSearchResults results = _RX.search("latest", search.paramMap()).execute().body(); assertNotNull(results); assertTrue(results.getTotal() > 0); - assertTrue(results.getResults().size() > 0); + assertFalse(results.getResults().isEmpty()); // the first time through, set the total if (total == null) diff --git a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java index 3339b15..00e7137 100644 --- a/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java +++ b/src/test/java/com/imsweb/seerapi/client/siterecode/SiteRecodeTest.java @@ -4,6 +4,7 @@ package com.imsweb.seerapi.client.siterecode; import java.io.IOException; +import java.util.List; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; @@ -21,7 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; public class SiteRecodeTest { @@ -34,43 +34,57 @@ public static void setup() { @Test void testBadRequestException() { - Call call = _SITE_RECODE.siteGroup("C379", null); + Call call = _SITE_RECODE.siteGroup("seer", "C379", null, null); assertThrows(BadRequestException.class, call::execute); } + @Test + void testSiteRecodeAlgorithms() throws IOException { + List algorithms = _SITE_RECODE.algorithms().execute().body(); + + assertNotNull(algorithms); + assertEquals(3, algorithms.size()); + } + @Test void testExceptionMessages() throws IOException { String message = ""; try { - _SITE_RECODE.siteGroup("C379", null).execute(); + _SITE_RECODE.siteGroup("seer", "C379", null, null).execute(); } catch (BadRequestException e) { message = e.getMessage(); } // the API call works out to: - // https://api.seer.cancer.gov/rest/recode/sitegroup?site=C379 + // https://api.seer.cancer.gov/rest/recode/sitegroup/seer?site=C379 assertEquals("Required parameter 'hist' is not present.", message); } - @Test - void testSiteRecordVersion() throws IOException { - String version = _SITE_RECODE.version().execute().body().getVersion(); - - assertNotNull(version); - assertTrue(version.length() > 0); - } - @Test void testSiteRecode() throws IOException { - Call call = _SITE_RECODE.siteGroup("C379", "9650"); + Call call = _SITE_RECODE.siteGroup("seer", "C379", "9650", null); SiteRecode recode = call.execute().body(); assertNotNull(recode); assertEquals("C379", recode.getSite()); assertEquals("9650", recode.getHist()); assertEquals("33011", recode.getSiteGroup()); + + call = _SITE_RECODE.siteGroup("iccc", "C379", "9650", "3"); + recode = call.execute().body(); + assertNotNull(recode); + assertEquals("C379", recode.getSite()); + assertEquals("9650", recode.getHist()); + assertEquals("021", recode.getSiteGroup()); + + call = _SITE_RECODE.siteGroup("aya", "C379", "9650", "3"); + recode = call.execute().body(); + assertNotNull(recode); + assertEquals("C379", recode.getSite()); + assertEquals("9650", recode.getHist()); + assertEquals("06", recode.getSiteGroup()); } @Test From f15e05dac4fe238c1659fe306b9cb20c38643bbe Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 31 Oct 2024 09:23:05 -0400 Subject: [PATCH 222/243] Update dependencies --- build.gradle | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/build.gradle b/build.gradle index fce364c..2d4a8c5 100644 --- a/build.gradle +++ b/build.gradle @@ -2,21 +2,21 @@ plugins { id 'java-library' id 'checkstyle' id 'jacoco' - id "com.github.spotbugs" version "5.0.14" + id "com.github.spotbugs" version "6.0.25" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" - id 'com.adarshr.test-logger' version '3.2.0' - id "com.github.ben-manes.versions" version "0.47.0" - id 'org.sonatype.gradle.plugins.scan' version '2.6.0' - id "org.sonarqube" version "4.2.1.3168" + id 'com.adarshr.test-logger' version '4.0.0' + id "com.github.ben-manes.versions" version "0.51.0" + id 'org.sonatype.gradle.plugins.scan' version '2.8.3' + id "org.sonarqube" version "5.1.0.4882" } group = 'com.imsweb' version = '5.6' description = 'Java client library for SEER*API' -tasks.withType(JavaCompile) { +tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs << "-Werror" } @@ -34,22 +34,19 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.7.3' + spotbugs 'com.github.spotbugs:spotbugs:4.8.6' - api 'com.squareup.retrofit2:retrofit:2.9.0' - api 'com.squareup.retrofit2:converter-jackson:2.9.0' + api 'com.squareup.retrofit2:retrofit:2.11.0' + api 'com.squareup.retrofit2:converter-jackson:2.11.0' // retrofit will not update these dependencies to fix vulnerabilities - api 'com.squareup.okhttp3:okhttp:4.11.0' - api 'com.squareup.okio:okio:3.4.0' + api 'com.squareup.okhttp3:okhttp:4.12.0' + api 'com.squareup.okio:okio:3.9.1' - // newer version of dependency to fix vulnerability until converter-jackson is updated - api 'com.fasterxml.jackson.core:jackson-databind:2.15.2' - - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.3' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.3' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.3' - testImplementation 'org.assertj:assertj-core:3.24.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.3' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.3' + testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } @@ -70,7 +67,7 @@ jar { } } -tasks.withType(Javadoc) { +tasks.withType(Javadoc).configureEach { failOnError false options.addStringOption('Xdoclint:none', '-quiet') options.addStringOption('encoding', 'UTF-8') From 957b12fea4243ce694597c1f64dc1cf6b1769d1d Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 31 Oct 2024 09:26:39 -0400 Subject: [PATCH 223/243] Fix build --- .github/workflows/integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 374a80c..f0cb2c7 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -34,4 +34,4 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | chmod +x gradlew - ./gradlew --continue build sonarqube + ./gradlew --continue build sonar From a46ffd44467d8a0e8e5ca6b160a26d640cb290f9 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 31 Oct 2024 09:30:12 -0400 Subject: [PATCH 224/243] Sonarqube giving issues --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2d4a8c5..752c3ac 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id 'com.adarshr.test-logger' version '4.0.0' id "com.github.ben-manes.versions" version "0.51.0" id 'org.sonatype.gradle.plugins.scan' version '2.8.3' - id "org.sonarqube" version "5.1.0.4882" + id "org.sonarqube" version "4.2.1.3168" } group = 'com.imsweb' From 4d18084bf9beb055a4bc91285f13d151e2ac9888 Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 31 Oct 2024 09:32:30 -0400 Subject: [PATCH 225/243] Try to suppress --- build.gradle | 2 +- config/spotbugs/spotbugs-exclude.xml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 752c3ac..2d4a8c5 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ plugins { id 'com.adarshr.test-logger' version '4.0.0' id "com.github.ben-manes.versions" version "0.51.0" id 'org.sonatype.gradle.plugins.scan' version '2.8.3' - id "org.sonarqube" version "4.2.1.3168" + id "org.sonarqube" version "5.1.0.4882" } group = 'com.imsweb' diff --git a/config/spotbugs/spotbugs-exclude.xml b/config/spotbugs/spotbugs-exclude.xml index a9f5d85..eee175d 100644 --- a/config/spotbugs/spotbugs-exclude.xml +++ b/config/spotbugs/spotbugs-exclude.xml @@ -36,6 +36,10 @@ + + + + From 3a1764af96edff8c65fe64090be4072ba3aa003c Mon Sep 17 00:00:00 2001 From: Chuck May Date: Thu, 31 Oct 2024 09:48:02 -0400 Subject: [PATCH 226/243] Prepare for release --- README.md | 18 ++++++++++-------- build.gradle | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 17ae11e..9897b36 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.6 + 5.7 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.6' +compile 'com.imsweb:seerapi-client-java:5.7' ``` ## Usage @@ -132,15 +132,17 @@ A searchable database for coding oncology drug and regimen treatment categories api.rx().getById("latest", "53c44b01102c1290262dc8b2").execute().body() ``` -### SEER Incidence Site Recode (rest/recode) +### Site Recode (rest/recode) -The values of SEER site recode variables are based on the primary site and histology data fields submitted to SEER by the -registries. The site recode variables define the major cancer site/histology groups that are commonly used in the reporting of -cancer incidence data. For example, there is a section of the SEER Cancer Statistics Review for each major site corresponding to -groupings in a site recode variable. The site recode variables are added to SEER databases as a convenience for researchers. +The API supports three algorithms for recoding site: SEER site recode ("seer"), International Classification of Childhood Cancer Site Recode ("iccc"), +and Adolescents and Young Adults Site Recode ("aya"). The values of SEER site recode variables are based on the primary site, histology and +behavior data fields submitted to SEER by the registries. The site recode variables define the major cancer site/histology groups that +are commonly used in the reporting of cancer incidence data. For example, there is a section of the SEER Cancer Statistics Review for +each major site corresponding to groupings in a site recode variable. The site recode variables are added to SEER databases as a +convenience for researchers. ```java -api.siteRecode().siteGroup("C619", "8000").execute().body() +api.siteRecode().siteGroup("seer", "C619", "8000", null).execute().body() ``` ### Site-specific Surgery Codes (rest/surgery) diff --git a/build.gradle b/build.gradle index 2d4a8c5..68f44ea 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ plugins { } group = 'com.imsweb' -version = '5.6' +version = '5.7' description = 'Java client library for SEER*API' tasks.withType(JavaCompile).configureEach { From 12eea2ee516a786e6ad62dfc27edea52bbed0d04 Mon Sep 17 00:00:00 2001 From: may Date: Mon, 12 May 2025 10:55:07 -0400 Subject: [PATCH 227/243] Fix failing units --- build.gradle | 2 +- .../seerapi/client/disease/DiseaseTest.java | 2 +- .../seerapi/client/glossary/GlossaryTest.java | 23 +++++++++++-------- .../com/imsweb/seerapi/client/rx/RxTest.java | 4 ++-- .../seerapi/client/staging/StagingTest.java | 6 ++--- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 68f44ea..69dc5b7 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ description = 'Java client library for SEER*API' tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' - options.compilerArgs << "-Werror" + options.compilerArgs << "-Werror" << "-Xlint:-options" } java { diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index a12f1d6..0aec622 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -117,7 +117,7 @@ void testDiseaseById() throws IOException { assertEquals(2, disease.getTreatment().size()); assertNull(disease.getGenetics()); assertFalse(disease.getAlternateName().isEmpty()); - assertEquals("Acute erythremia", disease.getAlternateName().get(0).getValue()); + assertEquals("Acute erythemia [OBS]", disease.getAlternateName().get(0).getValue()); assertTrue(disease.getIcdO2Morphology().contains("9840/3")); assertTrue(disease.getIcdO1Morphology().contains("9840/3")); assertEquals("C94.0 Acute erythroid leukemia", disease.getIcd10CmCode().get(0).getValue()); diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index 65bd6e2..ea9af3a 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -21,6 +21,7 @@ import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor; import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters; import static com.imsweb.seerapi.client.glossary.Glossary.Category.GENERAL; +import static com.imsweb.seerapi.client.glossary.Glossary.Category.HEMATO; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -49,7 +50,7 @@ void testGlossaryVersions() throws IOException { assertEquals(1, versions.size()); GlossaryVersion version = versions.get(0); assertEquals("latest", version.getName()); - assertNull(version.getType()); // type not returned when no permisisons + assertNull(version.getType()); // type isn't returned when no permisisons assertNotNull(version.getFirstPublished()); assertNotNull(version.getCount()); } @@ -68,7 +69,7 @@ void testGlossaryById() throws IOException { assertNull(glossary.getPrimarySite()); assertNull(glossary.getHistology()); - assertTrue(glossary.getDefinition().startsWith("An x-ray of the lymphatic system.")); + assertTrue(glossary.getDefinition().startsWith("An x-ray or computer image of the lymphatic system.")); assertNull(glossary.getAlternateName()); assertNull(glossary.getHistory()); } @@ -87,15 +88,15 @@ void testGlossarySearch() throws IOException { assertEquals(Collections.singletonList(term), results.getTerms()); // add the category and verify there are no results - results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.SOLID_TUMOR)).execute().body(); + results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(GENERAL)).execute().body(); assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(0, results.getTotal().longValue()); - assertNull(results.getResults()); + assertTrue(results.getTotal().longValue() > 0); + assertFalse(results.getResults().isEmpty()); // add a second category and verify there are we get the results again - results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(Glossary.Category.SOLID_TUMOR, Glossary.Category.HEMATO)).execute().body(); + results = _GLOSSARY.search("latest", search.paramMap(), EnumSet.of(GENERAL, Glossary.Category.HEMATO)).execute().body(); assertNotNull(results); assertEquals(25, results.getCount().longValue()); @@ -126,19 +127,23 @@ void testGlossarySearchIterate() throws IOException { search.setOffset(search.getOffset() + results.getResults().size()); } - assertTrue(total > 100); + assertTrue(total > 0); } @Test void testGlossaryMatch() throws IOException { - String text = "This text contains summary stage which should be found."; + String text = "white blood cells that produce antibodies"; Set matches = _GLOSSARY.match(text, null, true).execute().body(); assertNotNull(matches); - assertEquals(1, matches.size()); + assertEquals(2, matches.size()); matches = _GLOSSARY.match(text, EnumSet.of(GENERAL), true).execute().body(); assertNotNull(matches); + assertEquals(2, matches.size()); + + matches = _GLOSSARY.match(text, EnumSet.of(HEMATO), true).execute().body(); + assertNotNull(matches); assertEquals(0, matches.size()); } diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 6834468..1db37a9 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -123,8 +123,8 @@ void testRxSearch() throws IOException { assertNotNull(results); assertEquals(25, results.getCount().longValue()); - assertEquals(7, results.getTotal().longValue()); - assertEquals(7, results.getResults().size()); + assertEquals(8, results.getTotal().longValue()); + assertEquals(8, results.getResults().size()); assertEquals(Collections.singletonList("abt"), results.getTerms()); search.setMode(PublishableSearch.SearchMode.OR); diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index dfcc2df..9e02f66 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -538,11 +538,11 @@ void testStagingWithErrors() throws IOException { void testStagingGlossary() throws IOException { Set matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", null, true).execute().body(); assertThat(matches).hasSize(26); - matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", EnumSet.of(Category.STAGING), true).execute().body(); - assertThat(matches).hasSize(1); + matches = _STAGING.schemaGlossary("eod_public", "2.0", "breast", EnumSet.of(Category.GENERAL), true).execute().body(); + assertThat(matches).hasSize(26); matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", null, true).execute().body(); - assertThat(matches).hasSize(24); + assertThat(matches).hasSize(23); matches = _STAGING.tableGlossary("eod_public", "2.0", "cea_pretx_lab_value_33864", EnumSet.of(Category.STAGING), true).execute().body(); assertThat(matches).isEmpty(); } From d516d4b0baa04acb6293121e1df08d9c7ce94c32 Mon Sep 17 00:00:00 2001 From: may Date: Mon, 12 May 2025 10:58:32 -0400 Subject: [PATCH 228/243] Fix build --- .github/workflows/integration.yml | 2 +- build.gradle | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index f0cb2c7..977415d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -20,7 +20,7 @@ jobs: distribution: 'adopt' java-version: '17' - name: Cache Gradle packages - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches diff --git a/build.gradle b/build.gradle index 69dc5b7..321f76b 100644 --- a/build.gradle +++ b/build.gradle @@ -2,14 +2,14 @@ plugins { id 'java-library' id 'checkstyle' id 'jacoco' - id "com.github.spotbugs" version "6.0.25" + id "com.github.spotbugs" version "6.1.11" id 'maven-publish' id 'signing' id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '4.0.0' - id "com.github.ben-manes.versions" version "0.51.0" - id 'org.sonatype.gradle.plugins.scan' version '2.8.3' - id "org.sonarqube" version "5.1.0.4882" + id "com.github.ben-manes.versions" version "0.52.0" + id 'org.sonatype.gradle.plugins.scan' version '3.1.1' + id "org.sonarqube" version "6.1.0.5360" } group = 'com.imsweb' @@ -34,19 +34,19 @@ repositories { } dependencies { - spotbugs 'com.github.spotbugs:spotbugs:4.8.6' + spotbugs 'com.github.spotbugs:spotbugs:4.9.3' api 'com.squareup.retrofit2:retrofit:2.11.0' api 'com.squareup.retrofit2:converter-jackson:2.11.0' // retrofit will not update these dependencies to fix vulnerabilities api 'com.squareup.okhttp3:okhttp:4.12.0' - api 'com.squareup.okio:okio:3.9.1' + api 'com.squareup.okio:okio:3.11.0' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.3' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.3' - testImplementation 'org.assertj:assertj-core:3.26.3' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.12.2' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.12.2' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.12.2' + testImplementation 'org.assertj:assertj-core:3.27.3' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } From 5596653d9f269caa16e37683f9f6bb5a8e800bdf Mon Sep 17 00:00:00 2001 From: may Date: Mon, 12 May 2025 11:05:13 -0400 Subject: [PATCH 229/243] Update Gradle wrapper --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43764 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 10 ++++++---- gradlew.bat | 6 ++++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 321f76b..64c3279 100644 --- a/build.gradle +++ b/build.gradle @@ -122,7 +122,7 @@ tasks.named("dependencyUpdates").configure { } wrapper { - gradleVersion = '8.8' + gradleVersion = '8.14' distributionType = Wrapper.DistributionType.ALL } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..1b33c55baabb587c669f562ae36f953de2481846 100644 GIT binary patch delta 35073 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 delta 34912 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

Gn4F+B~IivciU9^t0j-Mgao3 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 dDuazZG^u*-) zCV{{p$D*4m=Z;!QJ0C3EBfaUv#@3CmRgS-#a4+Uk9LtR(mzdSt-?*B-Q{Jgs!F;+_ zT&Jc~{N951OskjVtnWOLnfUacmSEkQ#fQojqa=HN?aN#ubFA){K&TrfoSnBphJ<43S zS5?OUrqPYpEqf;(zc;IIty0d`-n-Ke%PlArJt^DN>ZYW)ZS5z$Rnx=cxbM1#zPRNS1N0u>c z*gpBeTvyKAjdr#Uz%$J3C+p2~l9`-P6`=_1Y83#nAp`Kd5jfb*H#u;=%w#=&g~|Q% z1!N9S7n+#|tj#t98*^$X3S9)i3I*n?N+YghXJ9Z!QN%wvV7|W$;;Lx|1{)Ol%c4L- zlz|txtAK4ozLL`xMPZR7Sm6grRj@+Db&BXF9#sG|gMywm=IO1O01imHv3 zFjX9ri>su;HX}wK85k5$R0A&?fdtA5_Q_vX$jc(elo%M~QB>A-K~#2igOjH$d^80Z zC8#NjzZarXrcVZJJEF73z+ix4=7c`5N>TJt7>~rfl$^E}UAMlP2$P)vS26{cE?ONf_&Vd@-E2?PMU+S~pB diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6f7a6eb..6514f91 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf1..23d15a9 100644 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -203,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 25da30d..db3a6ac 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 05d8272ece916dbda02095277548f1ed2ec36554 Mon Sep 17 00:00:00 2001 From: may Date: Mon, 12 May 2025 11:31:51 -0400 Subject: [PATCH 230/243] Lower Jupiter test version --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 64c3279..668c25e 100644 --- a/build.gradle +++ b/build.gradle @@ -43,10 +43,10 @@ dependencies { api 'com.squareup.okhttp3:okhttp:4.12.0' api 'com.squareup.okio:okio:3.11.0' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.12.2' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.12.2' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.12.2' - testImplementation 'org.assertj:assertj-core:3.27.3' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.3' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.3' + testImplementation 'org.assertj:assertj-core:3.26.3' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } From 137ae6845b35222ba18d712c54ef64ff88b3c5ad Mon Sep 17 00:00:00 2001 From: may Date: Mon, 12 May 2025 13:44:43 -0400 Subject: [PATCH 231/243] Fixed JUnit issues --- build.gradle | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 668c25e..04dca12 100644 --- a/build.gradle +++ b/build.gradle @@ -43,10 +43,13 @@ dependencies { api 'com.squareup.okhttp3:okhttp:4.12.0' api 'com.squareup.okio:okio:3.11.0' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.11.3' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.11.3' - testImplementation 'org.assertj:assertj-core:3.26.3' + testImplementation platform('org.junit:junit-bom:5.12.2') + testImplementation 'org.junit.jupiter:junit-jupiter-api' + testImplementation 'org.junit.jupiter:junit-jupiter-params' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher:1.12.2' + + testImplementation 'org.assertj:assertj-core:3.27.3' testImplementation 'com.google.code.bean-matchers:bean-matchers:0.14' } From 481d3fcc5e498b078271cc90e1ee4dd6b1181d6a Mon Sep 17 00:00:00 2001 From: may Date: Mon, 12 May 2025 13:52:30 -0400 Subject: [PATCH 232/243] Fix Sonarqube warnings --- .../java/com/imsweb/seerapi/client/disease/DiseaseTest.java | 2 +- .../java/com/imsweb/seerapi/client/glossary/GlossaryTest.java | 2 +- src/test/java/com/imsweb/seerapi/client/rx/RxTest.java | 2 +- .../java/com/imsweb/seerapi/client/staging/StagingTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java index 0aec622..6efadbb 100644 --- a/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java +++ b/src/test/java/com/imsweb/seerapi/client/disease/DiseaseTest.java @@ -28,7 +28,7 @@ class DiseaseTest { private static DiseaseService _DISEASE; @BeforeAll - public static void setup() { + static void setup() { _DISEASE = new SeerApi.Builder().connect().disease(); } diff --git a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java index ea9af3a..505c9f7 100644 --- a/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java +++ b/src/test/java/com/imsweb/seerapi/client/glossary/GlossaryTest.java @@ -33,7 +33,7 @@ class GlossaryTest { private static GlossaryService _GLOSSARY; @BeforeAll - public static void setup() { + static void setup() { _GLOSSARY = new SeerApi.Builder().connect().glossary(); } diff --git a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java index 1db37a9..f2029c9 100644 --- a/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java +++ b/src/test/java/com/imsweb/seerapi/client/rx/RxTest.java @@ -30,7 +30,7 @@ class RxTest { private static RxService _RX; @BeforeAll - public static void setup() { + static void setup() { _RX = new SeerApi.Builder().connect().rx(); } diff --git a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java index 9e02f66..97e2ac9 100644 --- a/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java +++ b/src/test/java/com/imsweb/seerapi/client/staging/StagingTest.java @@ -95,7 +95,7 @@ class StagingTest { private static StagingService _STAGING; @BeforeAll - public static void setup() { + static void setup() { _STAGING = new SeerApi.Builder().connect().staging(); } From 4a6f5f2bcf44dbaedda5e6a24ae80c7d03d4c1b9 Mon Sep 17 00:00:00 2001 From: may Date: Tue, 13 May 2025 11:20:06 -0400 Subject: [PATCH 233/243] Convert to Maven Central Portal --- build.gradle | 179 +++++++++++++++++---------------------------------- 1 file changed, 59 insertions(+), 120 deletions(-) diff --git a/build.gradle b/build.gradle index 04dca12..4afba71 100644 --- a/build.gradle +++ b/build.gradle @@ -1,32 +1,26 @@ +import com.vanniktech.maven.publish.JavaLibrary +import com.vanniktech.maven.publish.JavadocJar +import com.vanniktech.maven.publish.SonatypeHost + plugins { id 'java-library' id 'checkstyle' id 'jacoco' id "com.github.spotbugs" version "6.1.11" - id 'maven-publish' - id 'signing' - id "io.codearte.nexus-staging" version "0.30.0" id 'com.adarshr.test-logger' version '4.0.0' id "com.github.ben-manes.versions" version "0.52.0" id 'org.sonatype.gradle.plugins.scan' version '3.1.1' id "org.sonarqube" version "6.1.0.5360" + id 'com.vanniktech.maven.publish' version '0.31.0' } group = 'com.imsweb' -version = '5.7' +version = '5.8-SNAPSHOT' description = 'Java client library for SEER*API' -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' - options.compilerArgs << "-Werror" << "-Xlint:-options" -} - java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 - - withJavadocJar() - withSourcesJar() } repositories { @@ -38,8 +32,6 @@ dependencies { api 'com.squareup.retrofit2:retrofit:2.11.0' api 'com.squareup.retrofit2:converter-jackson:2.11.0' - - // retrofit will not update these dependencies to fix vulnerabilities api 'com.squareup.okhttp3:okhttp:4.12.0' api 'com.squareup.okio:okio:3.11.0' @@ -54,11 +46,10 @@ dependencies { } jar { - // specify the archive name; otherwise the version is appended to the war file archiveFileName = 'seerapi-java.jar' - manifest { - attributes('Implementation-Title': 'SEER*API Java Client', + attributes( + 'Implementation-Title': 'SEER*API Java Client', 'Implementation-Version': archiveVersion, 'Implementation-Vendor': group, 'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")", @@ -70,6 +61,11 @@ jar { } } +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + options.compilerArgs << "-Werror" << "-Xlint:-options" +} + tasks.withType(Javadoc).configureEach { failOnError false options.addStringOption('Xdoclint:none', '-quiet') @@ -77,12 +73,26 @@ tasks.withType(Javadoc).configureEach { options.addStringOption('charSet', 'UTF-8') } +javadoc { + if (JavaVersion.current().isJava9Compatible()) { + options.addBooleanOption('html5', true) + } +} + test { useJUnitPlatform() } +test.finalizedBy jacocoTestReport + +jacocoTestReport { + reports { + xml.required = true + } +} + checkstyle { - toolVersion '8.29' + toolVersion = '8.29' configFile = file("config/checkstyle/checkstyle.xml") } @@ -90,13 +100,6 @@ spotbugs { excludeFilter = file('config/spotbugs/spotbugs-exclude.xml') } -jacocoTestReport { - reports { - xml.required = true - } -} -test.finalizedBy jacocoTestReport - sonarqube { properties { property "sonar.projectKey", "imsweb_seerapi-client-java" @@ -105,115 +108,51 @@ sonarqube { } } -// Nexus vulnerability scan (see https://github.com/sonatype-nexus-community/scan-gradle-plugin) ossIndexAudit { outputFormat = 'DEPENDENCY_GRAPH' printBanner = false } -def isNonStable = { String version -> - def stableKeyword = ['RELEASE', 'FINAL', 'GA'].any { it -> version.toUpperCase().contains(it) } - def regex = /^[0-9,.v-]+(-r)?$/ - return !stableKeyword && !(version ==~ regex) -} +mavenPublishing { + configure(new JavaLibrary(new JavadocJar.Javadoc(), true)) -// https://github.com/ben-manes/gradle-versions-plugin -tasks.named("dependencyUpdates").configure { - rejectVersionIf { - isNonStable(it.candidate.version) - } -} + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, true) + signAllPublications() -wrapper { - gradleVersion = '8.14' - distributionType = Wrapper.DistributionType.ALL -} + pom { + name = 'SEER*API Java Client' + description = 'API mapping for SEER*API in Java' + url = 'https://github.com/imsweb/seerapi-client-java' -// don't try to release a snapshot to a non-snapshot repository, that won't work anyway -if (version.endsWith('-SNAPSHOT')) { - gradle.startParameter.excludedTaskNames += 'signMavenJavaPublication' - gradle.startParameter.excludedTaskNames += 'closeAndReleaseRepository' -} - -publishing { - publications { - mavenJava(MavenPublication) { - artifactId = 'seerapi-client-java' - from components.java - versionMapping { - usage('java-api') { - fromResolutionOf('runtimeClasspath') - } - usage('java-runtime') { - fromResolutionResult() - } - } - pom { - name = 'SEER*API Java Client' - description = 'API mapping for SEER*API in Java' - url = 'https://github.com/imsweb/seerapi-client-java' - inceptionYear = '2014' - - licenses { - license { - name = 'The MIT License (MIT)' - url = 'http://www.opensource.org/licenses/mit-license.php' - distribution = 'repo' - } - } - - developers { - developer { - id = 'ctmay4' - name = 'Chuck May' - email = 'mayc@imsweb.com' - } - developer { - id = 'depryf' - name = 'Fabian Depry' - email = 'depryf@imsweb.com' - } - } - - scm { - url = 'https://github.com/imsweb/seerapi-client-java' - connection = 'scm:https://github.com/imsweb/seerapi-client-java.git' - developerConnection = 'scm:git@github.com:imsweb/seerapi-client-java.git' - } + licenses { + license { + name = 'The MIT License (MIT)' + url = 'http://www.opensource.org/licenses/mit-license.php' } } - } - repositories { - maven { - def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" - def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" - url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl - - credentials { - username = project.findProperty('nexusUsername') ?: '' - password = project.findProperty('nexusPassword') ?: '' + + developers { + developer { + id = 'ctmay4' + name = 'Chuck May' + email = 'mayc@imsweb.com' + } + developer { + id = 'depryf' + name = 'Fabian Depry' + email = 'depryf@imsweb.com' } } - } -} - -signing { - def signingKey = project.findProperty('signingKey') ?: '' - def signingPassword = project.findProperty('signingPassword') ?: '' - - useInMemoryPgpKeys(signingKey, signingPassword) - - sign publishing.publications.mavenJava -} -javadoc { - if (JavaVersion.current().isJava9Compatible()) { - options.addBooleanOption('html5', true) + scm { + url = 'https://github.com/imsweb/seerapi-client-java' + connection = 'scm:https://github.com/imsweb/seerapi-client-java.git' + developerConnection = 'scm:git@github.com:imsweb/seerapi-client-java.git' + } } } -// configure nexus staging plugin -nexusStaging { - numberOfRetries = 50 - delayBetweenRetriesInMillis = 5000 +wrapper { + gradleVersion = '8.14' + distributionType = Wrapper.DistributionType.ALL } From 09035cfc4e55eea89472f0e46cd9d1c36d9153e5 Mon Sep 17 00:00:00 2001 From: may Date: Tue, 13 May 2025 11:29:49 -0400 Subject: [PATCH 234/243] Updated Actions to publish on tag --- .github/workflows/integration.yml | 2 +- .github/workflows/publish.yml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 977415d..88ae06a 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -18,7 +18,7 @@ jobs: uses: actions/setup-java@v2 with: distribution: 'adopt' - java-version: '17' + java-version: '21' - name: Cache Gradle packages uses: actions/cache@v4 with: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5295861..8d2ef4a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,13 +20,13 @@ jobs: uses: actions/setup-java@v2 with: distribution: 'adopt' - java-version: '17' - - name: Publish + java-version: '21' + - name: Publish to Maven Central (Portal) run: | chmod +x gradlew - ./gradlew publish closeAndReleaseRepository + ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache env: - ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }} - ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }} - ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SEER_GPG_SECRET_KEY }} - ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SEER_GPG_PASSWORD }} + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} From 965795225ae3aafc0f9f2b69e841ef6db4b69335 Mon Sep 17 00:00:00 2001 From: may Date: Tue, 13 May 2025 11:41:27 -0400 Subject: [PATCH 235/243] Tweak --- build.gradle | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4afba71..fcb57c0 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,11 @@ group = 'com.imsweb' version = '5.8-SNAPSHOT' description = 'Java client library for SEER*API' +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + options.compilerArgs << "-Werror" << "-Xlint:-options" +} + java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 @@ -32,6 +37,8 @@ dependencies { api 'com.squareup.retrofit2:retrofit:2.11.0' api 'com.squareup.retrofit2:converter-jackson:2.11.0' + + // retrofit will not update these dependencies to fix vulnerabilities api 'com.squareup.okhttp3:okhttp:4.12.0' api 'com.squareup.okio:okio:3.11.0' @@ -46,10 +53,11 @@ dependencies { } jar { + // specify the archive name; otherwise the version is appended to the war file archiveFileName = 'seerapi-java.jar' + manifest { - attributes( - 'Implementation-Title': 'SEER*API Java Client', + attributes('Implementation-Title': 'SEER*API Java Client', 'Implementation-Version': archiveVersion, 'Implementation-Vendor': group, 'Created-By': System.properties['java.vm.version'] + " (" + System.properties['java.vm.vendor'] + ")", From 6f3d4bc9ffd9b008a22c09464c2b202942abb623 Mon Sep 17 00:00:00 2001 From: may Date: Tue, 13 May 2025 12:47:54 -0400 Subject: [PATCH 236/243] Prepare for release --- README.md | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9897b36..e849d88 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.7 + 5.8 ``` diff --git a/build.gradle b/build.gradle index fcb57c0..decf6b3 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ plugins { } group = 'com.imsweb' -version = '5.8-SNAPSHOT' +version = '5.8' description = 'Java client library for SEER*API' tasks.withType(JavaCompile).configureEach { From 2564ca358ce1827717c2d9d977400f347891187d Mon Sep 17 00:00:00 2001 From: may Date: Tue, 13 May 2025 12:48:35 -0400 Subject: [PATCH 237/243] Prepare for release --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e849d88..9024b86 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Download [the latest JAR][1] or grab via Maven: or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.7' +compile 'com.imsweb:seerapi-client-java:5.8' ``` ## Usage From af6e9159d55ba9d22d883fc01b20e742befcd8ed Mon Sep 17 00:00:00 2001 From: may Date: Wed, 14 May 2025 08:54:39 -0400 Subject: [PATCH 238/243] Remove duplicate entry --- build.gradle | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build.gradle b/build.gradle index decf6b3..24b0663 100644 --- a/build.gradle +++ b/build.gradle @@ -69,11 +69,6 @@ jar { } } -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' - options.compilerArgs << "-Werror" << "-Xlint:-options" -} - tasks.withType(Javadoc).configureEach { failOnError false options.addStringOption('Xdoclint:none', '-quiet') From 369c0067158e4beb6a7ad3fb1d66d0f2b1e800ac Mon Sep 17 00:00:00 2001 From: Chuck May Date: Fri, 23 May 2025 11:17:23 -0400 Subject: [PATCH 239/243] Update README.md Fixed Maven Central badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9024b86..2dce629 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # seerapi-client-java [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=imsweb_seerapi-client-java&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=imsweb_seerapi-client-java) [![integration](https://github.com/imsweb/seerapi-client-java/workflows/integration/badge.svg)](https://github.com/imsweb/seerapi-client-java/actions) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.imsweb/seerapi-client-java) +[![Maven Central](https://img.shields.io/maven-central/v/com.imsweb/seerapi-client-java.svg?label=Maven%20Central)](https://central.sonatype.com/artifact/com.imsweb/seerapi-client-java) A [SEER*API](https://api.seer.cancer.gov) client for Java applications. This library supports most of the APIs and makes them easy to incorporate into Java applications. From 10b1d488f9696eef9fc4572f2a94551eea503d16 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 11 Jul 2025 13:45:55 -0400 Subject: [PATCH 240/243] Updated NAACCR endpoint to new version --- build.gradle | 3 +- .../com/imsweb/seerapi/client/SeerApi.java | 3 + .../seerapi/client/naaccr/AllowedCode.java | 18 ++ .../client/naaccr/NaaccrFieldName.java | 28 -- .../client/naaccr/NaaccrFlatField.java | 80 ----- .../seerapi/client/naaccr/NaaccrItem.java | 305 ++++++++++++++++++ .../seerapi/client/naaccr/NaaccrItemInfo.java | 23 ++ .../seerapi/client/naaccr/NaaccrService.java | 55 +--- .../seerapi/client/naaccr/NaaccrSubField.java | 46 --- .../seerapi/client/naaccr/NaaccrVersion.java | 55 ++-- .../seerapi/client/naaccr/NaaccrXmlField.java | 94 ------ .../seerapi/client/naaccr/NaaccrTest.java | 148 +++------ 12 files changed, 424 insertions(+), 434 deletions(-) create mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java delete mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java delete mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java create mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java create mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java delete mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java delete mode 100644 src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java diff --git a/build.gradle b/build.gradle index 24b0663..effddd2 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ plugins { id 'com.adarshr.test-logger' version '4.0.0' id "com.github.ben-manes.versions" version "0.52.0" id 'org.sonatype.gradle.plugins.scan' version '3.1.1' - id "org.sonarqube" version "6.1.0.5360" + id "org.sonarqube" version "6.2.0.5505" id 'com.vanniktech.maven.publish' version '0.31.0' } @@ -37,6 +37,7 @@ dependencies { api 'com.squareup.retrofit2:retrofit:2.11.0' api 'com.squareup.retrofit2:converter-jackson:2.11.0' + api 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.19.1' // retrofit will not update these dependencies to fix vulnerabilities api 'com.squareup.okhttp3:okhttp:4.12.0' diff --git a/src/main/java/com/imsweb/seerapi/client/SeerApi.java b/src/main/java/com/imsweb/seerapi/client/SeerApi.java index 3d33294..45712a1 100644 --- a/src/main/java/com/imsweb/seerapi/client/SeerApi.java +++ b/src/main/java/com/imsweb/seerapi/client/SeerApi.java @@ -15,6 +15,7 @@ import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -110,6 +111,8 @@ static ObjectMapper getMapper() { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); mapper.setDateFormat(dateFormat); + mapper.registerModule(new JavaTimeModule()); + return mapper; } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java b/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java new file mode 100644 index 0000000..6efef4d --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java @@ -0,0 +1,18 @@ +package com.imsweb.seerapi.client.naaccr; + +public class AllowedCode { + + private String code; + private String description; + + public AllowedCode() { + } + + public String getCode() { + return code; + } + + public String getDescription() { + return description; + } +} \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java deleted file mode 100644 index 73ff8f8..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFieldName.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NaaccrFieldName { - - @JsonProperty("id") - protected String _id; - @JsonProperty("item") - protected Integer _item; - @JsonProperty("name") - protected String _name; - - public String getNaaccrId() { - return _id; - } - - public Integer getItemNum() { - return _item; - } - - public String getName() { - return _name; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java deleted file mode 100644 index 2eb9ed6..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrFlatField.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -@JsonPropertyOrder({"item", "name", "section", "start_col", "end_col", "alignment", "padding_char", "default_value", "documentation", "subfield"}) -public class NaaccrFlatField { - - @JsonProperty("id") - protected String _id; - @JsonProperty("item") - protected Integer _item; - @JsonProperty("name") - protected String _name; - @JsonProperty("section") - protected String _section; - @JsonProperty("start_col") - protected Integer _start; - @JsonProperty("end_col") - protected Integer _end; - @JsonProperty("alignment") - protected String _align; - @JsonProperty("padding_char") - protected String _padChar; - @JsonProperty("default_value") - protected String _defaultValue; - @JsonProperty("documentation") - protected String _documentation; - @JsonProperty("subfield") - protected List _subFields; - - public String getNaaccrId() { - return _id; - } - - public Integer getItemNum() { - return _item; - } - - public String getName() { - return _name; - } - - public String getSection() { - return _section; - } - - public Integer getStart() { - return _start; - } - - public Integer getEnd() { - return _end; - } - - public String getAlign() { - return _align; - } - - public String getPadChar() { - return _padChar; - } - - public String getDefaultValue() { - return _defaultValue; - } - - public String getDocumentation() { - return _documentation; - } - - public List getSubFields() { - return _subFields; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java new file mode 100644 index 0000000..39c9683 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItem.java @@ -0,0 +1,305 @@ +package com.imsweb.seerapi.client.naaccr; + +import java.time.OffsetDateTime; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class NaaccrItem { + + private NaaccrVersion version; + private String itemNumber; + private String itemName; + private String itemLength; + private String yearImplemented; + private String yearRetired; + private String versionImplemented; + private String versionRetired; + private String xmlNaaccrId; + private String xmlParentId; + private List recordTypes; + private String section; + private String sourceOfStandard; + private OffsetDateTime dateCreated; + private OffsetDateTime dateModified; + private String description; + private String rationale; + private String generalNotes; + private String clarification; + private String npcrCollect; + private String cocCollect; + private String seerCollect; + private String cccrCollect; + private List alternateNames; + private String format; + private String codeNote; + private String codeDescription; + private String itemDataType; + private String allowableValues; + private List allowedCodes; + + public NaaccrVersion getVersion() { + return version; + } + + public void setVersion(NaaccrVersion version) { + this.version = version; + } + + @JsonProperty("item_number") + public String getItemNumber() { + return itemNumber; + } + + public void setItemNumber(String itemNumber) { + this.itemNumber = itemNumber; + } + + @JsonProperty("item_name") + public String getItemName() { + return itemName; + } + + public void setItemName(String itemName) { + this.itemName = itemName; + } + + @JsonProperty("item_length") + public String getItemLength() { + return itemLength; + } + + public void setItemLength(String itemLength) { + this.itemLength = itemLength; + } + + @JsonProperty("year_implemented") + public String getYearImplemented() { + return yearImplemented; + } + + public void setYearImplemented(String yearImplemented) { + this.yearImplemented = yearImplemented; + } + + @JsonProperty("year_retired") + public String getYearRetired() { + return yearRetired; + } + + public void setYearRetired(String yearRetired) { + this.yearRetired = yearRetired; + } + + @JsonProperty("version_implemented") + public String getVersionImplemented() { + return versionImplemented; + } + + public void setVersionImplemented(String versionImplemented) { + this.versionImplemented = versionImplemented; + } + + @JsonProperty("version_retired") + public String getVersionRetired() { + return versionRetired; + } + + public void setVersionRetired(String versionRetired) { + this.versionRetired = versionRetired; + } + + @JsonProperty("xml_naaccr_id") + public String getXmlNaaccrId() { + return xmlNaaccrId; + } + + public void setXmlNaaccrId(String xmlNaaccrId) { + this.xmlNaaccrId = xmlNaaccrId; + } + + @JsonProperty("xml_parent_id") + public String getXmlParentId() { + return xmlParentId; + } + + public void setXmlParentId(String xmlParentId) { + this.xmlParentId = xmlParentId; + } + + @JsonProperty("record_types") + public List getRecordTypes() { + return recordTypes; + } + + public void setRecordTypes(List recordTypes) { + this.recordTypes = recordTypes; + } + + public String getSection() { + return section; + } + + public void setSection(String section) { + this.section = section; + } + + @JsonProperty("source_of_standard") + public String getSourceOfStandard() { + return sourceOfStandard; + } + + public void setSourceOfStandard(String sourceOfStandard) { + this.sourceOfStandard = sourceOfStandard; + } + + @JsonProperty("date_created") + public OffsetDateTime getDateCreated() { + return dateCreated; + } + + public void setDateCreated(OffsetDateTime dateCreated) { + this.dateCreated = dateCreated; + } + + @JsonProperty("date_modified") + public OffsetDateTime getDateModified() { + return dateModified; + } + + public void setDateModified(OffsetDateTime dateModified) { + this.dateModified = dateModified; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRationale() { + return rationale; + } + + public void setRationale(String rationale) { + this.rationale = rationale; + } + + @JsonProperty("general_notes") + public String getGeneralNotes() { + return generalNotes; + } + + public void setGeneralNotes(String generalNotes) { + this.generalNotes = generalNotes; + } + + public String getClarification() { + return clarification; + } + + public void setClarification(String clarification) { + this.clarification = clarification; + } + + @JsonProperty("npcr_collect") + public String getNpcrCollect() { + return npcrCollect; + } + + public void setNpcrCollect(String npcrCollect) { + this.npcrCollect = npcrCollect; + } + + @JsonProperty("coc_collect") + public String getCocCollect() { + return cocCollect; + } + + public void setCocCollect(String cocCollect) { + this.cocCollect = cocCollect; + } + + @JsonProperty("seer_collect") + public String getSeerCollect() { + return seerCollect; + } + + public void setSeerCollect(String seerCollect) { + this.seerCollect = seerCollect; + } + + @JsonProperty("cccr_collect") + public String getCccrCollect() { + return cccrCollect; + } + + public void setCccrCollect(String cccrCollect) { + this.cccrCollect = cccrCollect; + } + + @JsonProperty("alternate_names") + public List getAlternateNames() { + return alternateNames; + } + + public void setAlternateNames(List alternateNames) { + this.alternateNames = alternateNames; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + @JsonProperty("code_note") + public String getCodeNote() { + return codeNote; + } + + public void setCodeNote(String codeNote) { + this.codeNote = codeNote; + } + + @JsonProperty("code_description") + public String getCodeDescription() { + return codeDescription; + } + + public void setCodeDescription(String codeDescription) { + this.codeDescription = codeDescription; + } + + @JsonProperty("item_data_type") + public String getItemDataType() { + return itemDataType; + } + + public void setItemDataType(String itemDataType) { + this.itemDataType = itemDataType; + } + + @JsonProperty("allowable_values") + public String getAllowableValues() { + return allowableValues; + } + + public void setAllowableValues(String allowableValues) { + this.allowableValues = allowableValues; + } + + @JsonProperty("allowed_codes") + public List getAllowedCodes() { + return allowedCodes; + } + + public void setAllowedCodes(List allowedCodes) { + this.allowedCodes = allowedCodes; + } + +} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java new file mode 100644 index 0000000..d5920c8 --- /dev/null +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java @@ -0,0 +1,23 @@ +package com.imsweb.seerapi.client.naaccr; + +public class NaaccrItemInfo { + + private String id; + private String item; + private String name; + + public NaaccrItemInfo() { + } + + public String getId() { + return id; + } + + public String getItem() { + return item; + } + + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java index c155e4f..c2b9609 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrService.java @@ -12,60 +12,27 @@ public interface NaaccrService { /** - * Return a collection of NaaccrVersion objects which descibe the available flat file versions + * Return a collection of NaaccrVersion objects which descibe the available versions * @return a list of the available NAACCR versions and information about each of them */ - @GET("naaccr/flat/versions") - Call> flatVersions(); + @GET("naaccr/versions") + Call> versions(); /** - * Return a collection of NaaccrVersion objects which descibe the available XML versions - * @return a list of the available NAACCR versions and information about each of them - */ - @GET("naaccr/xml/versions") - Call> xmlVersions(); - - /** - * Return a list of all the field identifiers and names from a specified NAACCR flat file version - * @param version NAACCR version - * @return a list of NaaccrFieldName objects - */ - @GET("naaccr/flat/{version}") - Call> flatFieldNames(@Path("version") String version); - - /** - * Return a list of all the field identifiers and names from a specified NAACCR XML version - * @param version NAACCR version - * @return a list of NaaccrFieldName objects - */ - @GET("naaccr/xml/{version}") - Call> xmlFieldNames(@Path("version") String version); - - /** - * Return a list of all the field identifiers and names from a specified NAACCR flat file version - * @param version NAACCR version - * @param item NAACCR item number - * @return a list of NaaccrFieldName objects - */ - @GET("naaccr/flat/{version}/item/{item}") - Call flatField(@Path("version") String version, @Path("item") Integer item); - - /** - * Return a list of all the field identifiers and names from a specified NAACCR XML version + * Return a list of all the field identifiers and names from a specified NAACCR version * @param version NAACCR version - * @param id NAACCR XML id * @return a list of NaaccrFieldName objects */ - @GET("naaccr/xml/{version}/id/{id}") - Call xmlField(@Path("version") String version, @Path("id") String id); + @GET("naaccr/{version}") + Call> fieldNames(@Path("version") String version); /** - * Return a list of all the field identifiers and names from a specified NAACCR XML version + * Return a single item from a NAACCR version * @param version NAACCR version - * @param item NAACCR item number - * @return a list of NaaccrFieldName objects + * @param item NAACCR item number or XML identifier + * @return a NaaccrItem */ - @GET("naaccr/xml/{version}/item/{item}") - Call xmlField(@Path("version") String version, @Path("item") Integer item); + @GET("naaccr/{version}/{item}") + Call item(@Path("version") String version, @Path("item") String item); } diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java deleted file mode 100644 index f91e27a..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrSubField.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class NaaccrSubField { - - @JsonProperty("item") - protected Integer _item; - @JsonProperty("name") - protected String _name; - @JsonProperty("start_col") - protected Integer _start; - @JsonProperty("end_col") - protected Integer _end; - @JsonProperty("alignment") - protected String _align; - @JsonProperty("padding_char") - protected String _padChar; - - public Integer getItem() { - return _item; - } - - public String getName() { - return _name; - } - - public Integer getStart() { - return _start; - } - - public Integer getEnd() { - return _end; - } - - public String getAlign() { - return _align; - } - - public String getPadChar() { - return _padChar; - } -} diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java index ff918b8..c9be312 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrVersion.java @@ -1,54 +1,41 @@ package com.imsweb.seerapi.client.naaccr; +import java.time.OffsetDateTime; + import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +@JsonPropertyOrder({"version", "year_implemented", "date_of_publication"}) public class NaaccrVersion { - @JsonProperty("version") - protected String _version; - @JsonProperty("name") - protected String _name; - @JsonProperty("length") - protected Integer _length; - @JsonProperty("description") - protected String _description; - @JsonProperty("style") - protected String _style; - @JsonProperty("dictionary_uri") - protected String dictionaryUri; - @JsonProperty("dictionary_description") - protected String dictionaryDescription; - @JsonProperty("specification_version") - protected String specificationVersion; + private String version; + private Integer yearImplemented; + private OffsetDateTime dateOfPublication; public String getVersion() { - return _version; + return version; } - public String getName() { - return _name; + public void setVersion(String version) { + this.version = version; } - public Integer getLength() { - return _length; + @JsonProperty("year_implemented") + public Integer getYearImplemented() { + return yearImplemented; } - public String getDescription() { - return _description; + public void setYearImplemented(Integer yearImplemented) { + this.yearImplemented = yearImplemented; } - public String getStyle() { - return _style; + @JsonProperty("date_of_publication") + public OffsetDateTime getDateOfPublication() { + return dateOfPublication; } - public String getDictionaryUri() { - return dictionaryUri; + public void setDateOfPublication(OffsetDateTime dateOfPublication) { + this.dateOfPublication = dateOfPublication; } - public String getDictionaryDescription() { - return dictionaryDescription; - } - public String getSpecificationVersion() { - return specificationVersion; - } -} +} \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java deleted file mode 100644 index f9ba8c7..0000000 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrXmlField.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2011 Information Management Services, Inc. - */ -package com.imsweb.seerapi.client.naaccr; - -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonPropertyOrder; - -@JsonPropertyOrder({"id", "item", "name", "section", "parent_xml_element", "record_types", "data_type", "length", "start_col", - "pad_type", "trim_type", "allow_unlimited_text", "documentation"}) -public class NaaccrXmlField { - - @JsonProperty("id") - protected String _naaccrId; - @JsonProperty("item") - protected Integer _naaccrItemNum; - @JsonProperty("name") - protected String _name; - @JsonProperty("section") - protected String _section; - @JsonProperty("start_col") - protected Integer _start; - @JsonProperty("record_types") - protected List _recordTypes; - @JsonProperty("length") - protected Integer _length; - @JsonProperty("pad_type") - protected String _padType; - @JsonProperty("data_type") - protected String _dataType; - @JsonProperty("trim_type") - protected String _trimType; - @JsonProperty("allow_unlimited_text") - protected Boolean _allowUnlimitedText; - @JsonProperty("parent_xml_element") - protected String _parentXmlElement; - @JsonProperty("documentation") - protected String _documentation; - - public String getNaaccrId() { - return _naaccrId; - } - - public Integer getItemNum() { - return _naaccrItemNum; - } - - public String getName() { - return _name; - } - - public String getSection() { - return _section; - } - - public Integer getStart() { - return _start; - } - - public List getRecordTypes() { - return _recordTypes; - } - - public Integer getLength() { - return _length; - } - - public String getPadType() { - return _padType; - } - - public String getDataType() { - return _dataType; - } - - public String getTrimType() { - return _trimType; - } - - public Boolean getAllowUnlimitedText() { - return _allowUnlimitedText; - } - - public String getParentXmlElement() { - return _parentXmlElement; - } - - public String getDocumentation() { - return _documentation; - } - -} diff --git a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java index 4172f7d..3a80a40 100644 --- a/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java +++ b/src/test/java/com/imsweb/seerapi/client/naaccr/NaaccrTest.java @@ -5,10 +5,8 @@ import java.io.IOException; import java.util.List; -import java.util.Objects; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import com.imsweb.seerapi.client.SeerApi; @@ -25,128 +23,64 @@ public static void setup() { } @Test - void testNaaccrFlatVersions() throws IOException { - List versions = _NAACCR.flatVersions().execute().body(); + void testVersions() throws IOException { + List versions = _NAACCR.versions().execute().body(); assertThat(versions).isNotNull().isNotEmpty(); for (NaaccrVersion version : versions) { assertThat(version.getVersion()).isNotEmpty(); - assertThat(version.getName()).isNotEmpty(); - assertThat(version.getLength()).isGreaterThanOrEqualTo(22824); - assertThat(version.getDescription()).isNull(); - assertThat(version.getStyle()).isNotEmpty(); + assertThat(version.getYearImplemented()).isGreaterThan(2020); + assertThat(version.getDateOfPublication()).isNotNull(); } } @Test - void testNaaccrXmlVersions() throws IOException { - List versions = _NAACCR.xmlVersions().execute().body(); - - assertThat(versions).isNotNull().isNotEmpty(); - for (NaaccrVersion version : versions) { - assertThat(version.getVersion()).isNotEmpty(); - assertThat(version.getName()).isNotEmpty(); - assertThat(version.getLength()).isNull(); - assertThat(version.getDescription()).isNull(); - assertThat(version.getStyle()).isNotEmpty(); - assertThat(version.getDictionaryUri()).isNotEmpty(); - assertThat(version.getDictionaryDescription()).isNotEmpty(); - assertThat(version.getSpecificationVersion()).isNotEmpty(); - } - } - - @Test - void testNaaccrFlatFieldNames() throws IOException { - List names = _NAACCR.flatFieldNames("latest").execute().body(); + void testNaaccrFieldNames() throws IOException { + List names = _NAACCR.fieldNames("latest").execute().body(); assertThat(names).isNotNull(); - for (NaaccrFieldName name : names) { - assertThat(name.getItemNum()).isPositive(); + for (NaaccrItemInfo name : names) { + assertThat(name.getItem()).isNotEmpty(); assertThat(name.getName()).isNotEmpty(); } } @Test - void testNaaccrXmlFieldNames() throws IOException { - List names = _NAACCR.xmlFieldNames("latest").execute().body(); - - assertThat(names).isNotNull(); - for (NaaccrFieldName name : names) { - assertThat(name.getNaaccrId()).isNotEmpty(); - assertThat(name.getItemNum()).isPositive(); - assertThat(name.getName()).isNotEmpty(); - } + void testNaaccrItem() throws IOException { + validateItem(_NAACCR.item("25", "80").execute().body()); + validateItem(_NAACCR.item("25", "addrAtDxState").execute().body()); } - @Test - void testNaaccrFlatField() throws IOException { - NaaccrFlatField name = _NAACCR.flatField("16", 521).execute().body(); - - assertThat(name).isNotNull(); - assertThat(name.getItemNum()).isEqualTo(521); - assertThat(name.getNaaccrId()).isEqualTo("morphTypebehavIcdO3"); - assertThat(name.getName()).isEqualTo("Morph--Type&Behav ICD-O-3"); - assertThat(name.getSection()).isEqualTo("Cancer Identification"); - assertThat(name.getAlign()).isEqualTo("LEFT"); - assertThat(name.getPadChar()).isEqualTo(" "); - assertThat(name.getDocumentation()).startsWith("

"); - assertThat(name.getStart()).isEqualTo(550); - assertThat(name.getEnd()).isEqualTo(554); - - assertThat(name.getSubFields()).hasSize(2); - assertThat(name.getSubFields()).extracting("item").contains(522, 523); - - NaaccrSubField sub = name.getSubFields().get(0); - assertThat(sub.getName()).isEqualTo("Histologic Type ICD-O-3"); - assertThat(sub.getStart()).isEqualTo(550); - assertThat(sub.getEnd()).isEqualTo(553); - assertThat(sub.getAlign()).isEqualTo("LEFT"); - assertThat(sub.getPadChar()).isEqualTo(" "); - - // test one with default value - NaaccrFlatField recordID = _NAACCR.flatField("18", 10).execute().body(); - assertThat(recordID).isNotNull(); - assertThat(recordID.getName()).isEqualTo("Record Type"); - assertThat(recordID.getSection()).isEqualTo("Record ID"); - assertThat(recordID.getDefaultValue()).isEqualTo("A"); - } - - @Test - void testNaaccrXmlField() throws IOException { - NaaccrXmlField name = _NAACCR.xmlField("21", "phase2RadiationExternalBeamTech").execute().body(); - - assertThat(name).isNotNull(); - assertThat(name.getNaaccrId()).isEqualTo("phase2RadiationExternalBeamTech"); - assertThat(name.getItemNum()).isEqualTo(1512); - assertThat(name.getName()).isEqualTo("Phase II Radiation External Beam Planning Tech"); - assertThat(name.getSection()).isEqualTo("Treatment-1st Course"); - assertThat(name.getParentXmlElement()).isEqualTo("Tumor"); - assertThat(name.getRecordTypes()).containsExactly("A", "M", "C", "I"); - assertThat(name.getDataType()).isEqualTo("digits"); - assertThat(name.getLength()).isEqualTo(2); - assertThat(name.getPadType()).isEqualTo("none"); - assertThat(name.getTrimType()).isEqualTo("all"); - assertThat(name.getAllowUnlimitedText()).isFalse(); - assertThat(name.getDocumentation()).isNotEmpty(); - } - - // these two tests are slow so don't run them all the time; they verify that all the items from flat and NAACR can be read without error - - @Disabled("Slow test so do not run all the time") - public void loadAllFlat() throws IOException { - for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.flatFieldNames("latest").execute().body())) { - NaaccrFlatField field = _NAACCR.flatField("latest", name.getItemNum()).execute().body(); - - assertThat(field).isNotNull(); - } + private void validateItem(NaaccrItem item) { + assertThat(item).isNotNull(); + assertThat(item.getItemNumber()).isEqualTo("80"); + assertThat(item.getItemName()).isEqualTo("Addr at DX--State"); + assertThat(item.getItemDataType()).isEqualTo("alpha"); + assertThat(item.getItemLength()).isEqualTo("2"); + assertThat(item.getYearImplemented()).isEqualTo("2011"); + assertThat(item.getVersionImplemented()).isEqualTo("12.2"); + assertThat(item.getXmlNaaccrId()).isEqualTo("addrAtDxState"); + assertThat(item.getXmlParentId()).isEqualTo("Tumor"); + assertThat(item.getRecordTypes()).containsExactlyInAnyOrder("A", "C", "I", "M"); + assertThat(item.getSection()).isEqualTo("Demographic"); + assertThat(item.getSourceOfStandard()).isEqualTo("CoC"); + assertThat(item.getDateCreated()).isInThePast(); + assertThat(item.getDateModified()).isInThePast(); + assertThat(item.getDescription()).isNotEmpty(); + assertThat(item.getRationale()).isNotEmpty(); + assertThat(item.getNpcrCollect()).isEqualTo("Required"); + assertThat(item.getCocCollect()).isEqualTo("Required"); + assertThat(item.getSeerCollect()).isEqualTo("Required"); + assertThat(item.getCccrCollect()).isEqualTo("No recommendation"); + assertThat(item.getAlternateNames()).containsExactlyInAnyOrder("State at Diagnosis (CoC)", "State (pre-96 CoC)"); + assertThat(item.getFormat()).isEqualTo("Upper case"); + assertThat(item.getCodeDescription()).isEqualTo("In addition to USPS abbreviations"); + assertThat(item.getAllowableValues()).isEqualTo("Refer to EDITS table STATE.DBF in Appendix B; CD, US, XX, YY, ZZ"); + assertThat(item.getAllowedCodes()) + .hasSize(5) + .allMatch(allowedCode -> allowedCode.getDescription() != null) + .extracting("code") + .containsExactlyInAnyOrder("CD", "US", "XX", "YY", "ZZ"); } - @Disabled("Slow test so do not run all the time") - public void loadAllXml() throws IOException { - for (NaaccrFieldName name : Objects.requireNonNull(_NAACCR.xmlFieldNames("latest").execute().body())) { - NaaccrXmlField field = _NAACCR.xmlField("latest", name.getNaaccrId()).execute().body(); - - assertThat(field).isNotNull(); - } - } } From 71d97e5f439745fa8beddec3bc6e32c5707eecb2 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 11 Jul 2025 13:51:13 -0400 Subject: [PATCH 241/243] Fixed Spotbugs --- .../imsweb/seerapi/client/naaccr/AllowedCode.java | 9 +++++++++ .../seerapi/client/naaccr/NaaccrItemInfo.java | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java b/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java index 6efef4d..414b345 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/AllowedCode.java @@ -12,7 +12,16 @@ public String getCode() { return code; } + public void setCode(String code) { + this.code = code; + } + public String getDescription() { return description; } + + public void setDescription(String description) { + this.description = description; + } + } \ No newline at end of file diff --git a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java index d5920c8..cefeee6 100644 --- a/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java +++ b/src/main/java/com/imsweb/seerapi/client/naaccr/NaaccrItemInfo.java @@ -13,11 +13,24 @@ public String getId() { return id; } + public void setId(String id) { + this.id = id; + } + public String getItem() { return item; } + public void setItem(String item) { + this.item = item; + } + public String getName() { return name; } + + public void setName(String name) { + this.name = name; + } + } \ No newline at end of file From 73a8289e3ba2c5feee2b2fe51f5f6159b3d0bc06 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 11 Jul 2025 14:10:15 -0400 Subject: [PATCH 242/243] Prepare for release --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2dce629..16a88c1 100644 --- a/README.md +++ b/README.md @@ -30,14 +30,14 @@ Download [the latest JAR][1] or grab via Maven: com.imsweb seerapi-client-java - 5.8 + 5.9 ``` or via Gradle: ``` -compile 'com.imsweb:seerapi-client-java:5.8' +compile 'com.imsweb:seerapi-client-java:5.9' ``` ## Usage From 7d333607a9008437d9fb940adb798df5d4513d54 Mon Sep 17 00:00:00 2001 From: mayc Date: Fri, 11 Jul 2025 14:10:38 -0400 Subject: [PATCH 243/243] Prepare for release --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index effddd2..e9c7110 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ plugins { } group = 'com.imsweb' -version = '5.8' +version = '5.9' description = 'Java client library for SEER*API' tasks.withType(JavaCompile).configureEach {