From 012a7a165a2b241f5a7fd0630502502856bb06ab Mon Sep 17 00:00:00 2001
From: Laurent SCHOELENS <61973605+laurentschoelens@users.noreply.github.com>
Date: Wed, 6 Sep 2023 21:50:37 +0200
Subject: [PATCH] =?UTF-8?q?[#1707]=C2=A0Fix=20indent=20of=20DataWriter=20a?=
 =?UTF-8?q?nd=20adding=20test=20case?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../jaxb/core/marshaller/DataWriter.java      | 19 +++++--
 .../v2/schemagen/MarshallingAbstractTest.java | 56 +++++++++++++++++++
 2 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/jaxb-ri/core/src/main/java/org/glassfish/jaxb/core/marshaller/DataWriter.java b/jaxb-ri/core/src/main/java/org/glassfish/jaxb/core/marshaller/DataWriter.java
index 65d6ea222..46a8d6eb8 100644
--- a/jaxb-ri/core/src/main/java/org/glassfish/jaxb/core/marshaller/DataWriter.java
+++ b/jaxb-ri/core/src/main/java/org/glassfish/jaxb/core/marshaller/DataWriter.java
@@ -218,7 +218,7 @@ public void startElement (String uri, String localName,
         stateStack.push(SEEN_ELEMENT);
         state = SEEN_NOTHING;
         if (depth > 0) {
-            super.characters("\n");
+            super.characters("\n".toCharArray(), 0, 1);
         }
         doIndent();
         super.startElement(uri, localName, qName, atts);
@@ -250,7 +250,7 @@ public void endElement (String uri, String localName, String qName)
     {
         depth--;
         if (state == SEEN_ELEMENT) {
-            super.characters("\n");
+            super.characters("\n".toCharArray(), 0, 1);
             doIndent();
         }
         super.endElement(uri, localName, qName);
@@ -314,8 +314,17 @@ public void endDocument() throws SAXException {
     public void characters (char[] ch, int start, int length)
         throws SAXException
     {
-        state = SEEN_DATA;
-        super.characters(ch, start, length);
+        boolean hasContent = false;
+        for (int i = start; i < length; i++) {
+            if (!Character.isWhitespace(ch[i])) {
+                hasContent = true;
+                break;
+            }
+        }
+        if (hasContent) {
+            state = SEEN_DATA;
+            super.characters(ch, start, length);
+        }
     }
 
 
@@ -338,7 +347,7 @@ private void doIndent ()
         if (depth > 0) {
             char[] ch = indentStep.toCharArray();
             for( int i=0; i<depth; i++ )
-                characters(ch, 0, ch.length);
+                super.characters(ch, 0, ch.length);
         }
     }
 
diff --git a/jaxb-ri/runtime/impl/src/test/java/org/glassfish/jaxb/runtime/v2/schemagen/MarshallingAbstractTest.java b/jaxb-ri/runtime/impl/src/test/java/org/glassfish/jaxb/runtime/v2/schemagen/MarshallingAbstractTest.java
index b46d2fde4..1eac76175 100644
--- a/jaxb-ri/runtime/impl/src/test/java/org/glassfish/jaxb/runtime/v2/schemagen/MarshallingAbstractTest.java
+++ b/jaxb-ri/runtime/impl/src/test/java/org/glassfish/jaxb/runtime/v2/schemagen/MarshallingAbstractTest.java
@@ -14,10 +14,12 @@
 import org.glassfish.jaxb.runtime.v2.schemagen.xmlschema.JaxbDistribution;
 import org.glassfish.jaxb.runtime.v2.schemagen.xmlschema.JaxbEnvironmentModel;
 import org.junit.Assert;
+import org.junit.ComparisonFailure;
 import org.junit.Test;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
 import jakarta.xml.bind.annotation.XmlAccessorType;
+import jakarta.xml.bind.annotation.XmlAnyElement;
 import jakarta.xml.bind.annotation.XmlElement;
 import jakarta.xml.bind.annotation.XmlElementWrapper;
 import jakarta.xml.bind.annotation.XmlRootElement;
@@ -25,6 +27,7 @@
 import jakarta.xml.bind.annotation.XmlType;
 import jakarta.xml.bind.annotation.XmlValue;
 import javax.xml.XMLConstants;
+import jakarta.xml.bind.Element;
 import jakarta.xml.bind.JAXBContext;
 import jakarta.xml.bind.JAXBElement;
 import jakarta.xml.bind.Marshaller;
@@ -40,6 +43,7 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import junit.framework.TestCase;
 import junit.textui.TestRunner;
@@ -84,6 +88,14 @@ static class Mapping {
         A element2;
     }
 
+    @XmlRootElement
+    static class Job {
+
+        @XmlAnyElement
+        private List<Element> content;
+
+    }
+
     @Test
     public void testMarshalSingleElement() throws Exception {
         JAXBContext jc = JAXBContext.newInstance(Mapping.class);
@@ -164,6 +176,50 @@ public void testUnmarshalCollection() throws Exception {
         }
     }
 
+    @Test
+    public void testMarshallerJob() throws Exception {
+        JAXBContext jc = JAXBContext.newInstance(Job.class);
+        Unmarshaller unmarshaller = jc.createUnmarshaller();
+
+        Marshaller marshaller = jc.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+        String sourceXml = "<job type=\"NewMethod\">\n" +
+                "\n" +
+                "<foo id=\"1\">\n" +
+                "<bar>\n" +
+                "<baz>\n" +
+                "<value name=\"xxx\"/>\n" +
+                "  </baz>\n" +
+                "  </bar>\n" +
+                " </foo>\n" +
+                "\n" +
+                "</job>";
+
+        String expectedOutput = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
+                "<job>\n" +
+                "    <foo id=\"1\">\n" +
+                "        <bar>\n" +
+                "            <baz>\n" +
+                "                <value name=\"xxx\"/>\n" +
+                "            </baz>\n" +
+                "        </bar>\n" +
+                "    </foo>\n" +
+                "</job>\n";
+
+        try {
+            JAXBElement<Job> job = unmarshaller.unmarshal(new StreamSource(new StringReader(sourceXml)), Job.class);
+
+            StringWriter sw = new StringWriter();
+            marshaller.marshal(job.getValue(), sw);
+            String output = sw.toString();
+            Assert.assertEquals(expectedOutput, output);
+        } catch (ComparisonFailure e) {
+            throw e;
+        } catch (Throwable t) {
+            Assert.fail("Exception is thrown " + t);
+        }
+    }
+
     @Test
     public void testXmlIDRefMarshal() throws Exception {