From d065b5be207a06b43c1136dc6412e987565be38e Mon Sep 17 00:00:00 2001
From: Sean Arms <67096+lesserwhirls@users.noreply.github.com>
Date: Mon, 3 Nov 2025 16:16:01 -0700
Subject: [PATCH] Dap4 null valued attributes
Represent null-valued attributes in the DMR as , which matches
Hyrax behavior.
Sets the stage for fixing Unidata/tds#632
---
dap4/build.gradle.kts | 2 ++
.../main/java/dap4/core/dmr/DMRPrinter.java | 16 +++++++----
.../core/dmr/TestDMRPrinterEdgeCases.java | 28 +++++++++++++++++++
3 files changed, 40 insertions(+), 6 deletions(-)
create mode 100644 dap4/src/test/java/dap4/core/dmr/TestDMRPrinterEdgeCases.java
diff --git a/dap4/build.gradle.kts b/dap4/build.gradle.kts
index 1e39869bdc..cbb23db686 100644
--- a/dap4/build.gradle.kts
+++ b/dap4/build.gradle.kts
@@ -22,6 +22,8 @@ dependencies {
testImplementation(project(":cdm-test-utils"))
+ testImplementation(libs.google.truth)
+
testCompileOnly(libs.junit4)
testRuntimeOnly(libs.junit5.platformLauncher)
diff --git a/dap4/src/main/java/dap4/core/dmr/DMRPrinter.java b/dap4/src/main/java/dap4/core/dmr/DMRPrinter.java
index be0d681dee..6d52b872c6 100644
--- a/dap4/src/main/java/dap4/core/dmr/DMRPrinter.java
+++ b/dap4/src/main/java/dap4/core/dmr/DMRPrinter.java
@@ -1,6 +1,6 @@
/*
- * Copyright 2012, UCAR/Unidata.
- * See the LICENSE file for more information.
+ * Copyright (c) 2012-2025 University Corporation for Atmospheric Research/Unidata
+ * See LICENSE for license information.
*/
package dap4.core.dmr;
@@ -531,10 +531,14 @@ void printAttribute(DapAttribute attr) throws IOException {
printer.marginPrintln(cs);
}
} else {
- for (int i = 0; i < svec.length; i++) {
- String s = Escape.entityEscape(svec[i], null);
- String cs = String.format("", s);
- printer.marginPrintln(cs);
+ if (svec.length == 0) {
+ printer.marginPrintln("");
+ } else {
+ for (String string : svec) {
+ String s = Escape.entityEscape(string, null);
+ String cs = String.format("", s);
+ printer.marginPrintln(cs);
+ }
}
}
printer.outdent();
diff --git a/dap4/src/test/java/dap4/core/dmr/TestDMRPrinterEdgeCases.java b/dap4/src/test/java/dap4/core/dmr/TestDMRPrinterEdgeCases.java
new file mode 100644
index 0000000000..88dafabb6a
--- /dev/null
+++ b/dap4/src/test/java/dap4/core/dmr/TestDMRPrinterEdgeCases.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2025 University Corporation for Atmospheric Research/Unidata
+ * See LICENSE for license information.
+ */
+
+package dap4.core.dmr;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import dap4.core.util.IndentWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import org.junit.Test;
+
+public class TestDMRPrinterEdgeCases {
+ @Test
+ public void testNullValueAttr() throws IOException {
+ DapAttribute attr = new DapAttribute("name", DapType.STRING);
+ attr.setValues(new String[] {});
+ DMRPrinter dmrPrinter = new DMRPrinter();
+ StringWriter sw = new StringWriter();
+ dmrPrinter.printer = new IndentWriter(sw);
+ dmrPrinter.printAttribute(attr);
+ String encodedAttribute = sw.toString();
+ assertThat(encodedAttribute).isNotEmpty();
+ assertThat(encodedAttribute).ignoringCase().contains("");
+ }
+}