This is an automated email from the ASF dual-hosted git repository.

duncangrant pushed a commit to branch prettyPrintWinrmXml
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 4b59a9ee17f971bdcca0f5036bb3b21234f3d9aa
Author: Duncan Grant <duncan.gr...@cloudsoft.io>
AuthorDate: Mon Jan 18 16:36:05 2021 +0000

    Now pretty prints XML
    
    Fails if stream breaks mid tag - I don't expect this to happen
---
 .../internal/winrm/winrm4j/PrettyXmlWriter.java    |  96 +++++++++++++++
 .../core/internal/winrm/winrm4j/Winrm4jTool.java   |   7 +-
 .../winrm/winrm4j/PrettyXmlWriterTest.java         | 136 +++++++++++++++++++++
 3 files changed, 234 insertions(+), 5 deletions(-)

diff --git 
a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/PrettyXmlWriter.java
 
b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/PrettyXmlWriter.java
new file mode 100644
index 0000000..4c26646
--- /dev/null
+++ 
b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/PrettyXmlWriter.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.util.core.internal.winrm.winrm4j;
+
+import java.io.IOException;
+import java.io.Writer;
+
+public class PrettyXmlWriter extends Writer {
+    private Writer wrappedWriter;
+    private boolean tagClosed = Boolean.FALSE;
+    private int indentLevel = 0;
+    private boolean newLine = true;
+    private char lastChar = '\n';
+
+    public PrettyXmlWriter(Writer writer) {
+        super(writer);
+        wrappedWriter = writer;
+    }
+
+    @Override
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        for (int i = off; i < off + len; i++) {
+            char c = cbuf[i];
+            if (c == '<') {
+                lastChar = '<';
+                if(!newLine) {
+                    indentLevel--;
+                } else if (i + 1 < off + len && cbuf[i + 1] == '/') {
+                    indentLevel--;
+                    printIndent();
+                    indentLevel--;
+                } else {
+                    printIndent();
+                }
+            }
+            writeChar(c);
+            if ('>' == c || tagClosed) {
+                if (i + 1 < off + len) {
+                    if (cbuf[i + 1] == '<') {
+                        writeNewLine();
+                        if (lastChar != '/') {
+                            indentLevel++;
+                        }
+                    }
+                } else {
+                    tagClosed = true;
+                }
+            } else {
+                tagClosed = false;
+            }
+            lastChar = c;
+        }
+    }
+
+    private void writeNewLine() throws IOException {
+        wrappedWriter.write('\n');
+        newLine = true;
+    }
+
+    private void writeChar(char c) throws IOException {
+        wrappedWriter.write(c);
+        newLine = false;
+    }
+
+    private void printIndent() throws IOException {
+        for (int j = 0; j < indentLevel; j++) {
+            wrappedWriter.write('\t');
+        }
+    }
+
+    @Override
+    public void flush() throws IOException {
+        wrappedWriter.flush();
+    }
+
+    @Override
+    public void close() throws IOException {
+        wrappedWriter.close();
+    }
+}
diff --git 
a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
 
b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
index 0ce9bc5..5cb7824 100644
--- 
a/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
+++ 
b/software/winrm/src/main/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/Winrm4jTool.java
@@ -30,14 +30,11 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.config.Sanitizer;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
 import org.apache.brooklyn.util.core.internal.winrm.WinRmException;
 import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.javalang.Threads;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
@@ -119,7 +116,7 @@ public class Winrm4jTool implements 
org.apache.brooklyn.util.core.internal.winrm
             OutputStream outputStream = bag.get(ShellTool.PROP_OUT_STREAM);
             OutputStream errorStream = bag.get(ShellTool.PROP_ERR_STREAM);
             Writer out = outputStream != null ? new BufferedWriter(new 
OutputStreamWriter(outputStream)): new StringWriter();
-            Writer err = errorStream != null ? new BufferedWriter(new 
OutputStreamWriter(errorStream)): new StringWriter();
+            Writer err = errorStream != null ? new BufferedWriter(new 
PrettyXmlWriter(new OutputStreamWriter(errorStream))): new StringWriter();
             return tool.executeCommand(commands, out, err);
         });
     }
@@ -136,7 +133,7 @@ public class Winrm4jTool implements 
org.apache.brooklyn.util.core.internal.winrm
             OutputStream outputStream = bag.get(ShellTool.PROP_OUT_STREAM);
             OutputStream errorStream = bag.get(ShellTool.PROP_ERR_STREAM);
             Writer out = outputStream != null ? new BufferedWriter(new 
OutputStreamWriter(outputStream)): new StringWriter();
-            Writer err = errorStream != null ? new BufferedWriter(new 
OutputStreamWriter(errorStream)): new StringWriter();
+            Writer err = errorStream != null ? new BufferedWriter(new 
PrettyXmlWriter(new OutputStreamWriter(errorStream))): new StringWriter();
             return tool.executePs(commands, out, err);
         });
     }
diff --git 
a/software/winrm/src/test/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/PrettyXmlWriterTest.java
 
b/software/winrm/src/test/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/PrettyXmlWriterTest.java
new file mode 100644
index 0000000..7e28e35
--- /dev/null
+++ 
b/software/winrm/src/test/java/org/apache/brooklyn/util/core/internal/winrm/winrm4j/PrettyXmlWriterTest.java
@@ -0,0 +1,136 @@
+package org.apache.brooklyn.util.core.internal.winrm.winrm4j;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Arrays;
+
+import static org.testng.Assert.*;
+
+public class PrettyXmlWriterTest {
+
+    public static final String XML = "<?xml version=\"1.0\" ?><Objs 
xmlns=\"http://schemas.microsoft.com/powershell/2004/04\"; 
Version=\"1.1.0.1\"><Obj S=\"progress\" RefId=\"0\"><TN 
RefId=\"0\"><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64
 N=\"SourceId\">1</I64><PR N=\"Record\"><AV>Preparing modules for first 
use.</AV><AI>0</AI><Nil/><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD/></PR></MS></Obj></Objs>";
+    private RecordingWriter writer;
+    private PrettyXmlWriter prettyXmlWriter;
+
+    @BeforeMethod
+    public void setUp() {
+        writer = new RecordingWriter();
+        prettyXmlWriter = new PrettyXmlWriter(writer);
+    }
+
+    @Test
+    public void testInsertNewLines() throws IOException {
+        prettyXmlWriter.write(XML, 0, XML.length());
+
+        int newLines = countNewLines();
+        assertEquals(newLines,21);
+    }
+
+    @Test
+    public void testNoNewLineIfTagSurroundsText() throws IOException {
+        String xml = "<tag>fdskljdfsljkfsd</tag>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        int newLines = countNewLines();
+        assertEquals(newLines,0);
+    }
+
+    @Test
+    public void testNewLineIfPartialString() throws  IOException {
+        String xmlPart1 = "<t1><t2>fdskljfds</t2>";
+        String xmlPart2 = "<t3>djskdsjk</t3></t1>";
+
+        prettyXmlWriter.write(xmlPart1, 0, xmlPart1.length());
+        prettyXmlWriter.write(xmlPart2, 0, xmlPart2.length());
+
+        int newLines = countNewLines();
+        assertEquals(newLines,3);
+    }
+
+    @Test
+    public void testIndentOnNewLine() throws IOException {
+        String xml = "<t1><t2>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        assertEquals(writer.out.toString(), "<t1>\n\t<t2>");
+    }
+
+    @Test
+    public void testIncreaseIndentOnEachOpenTag() throws IOException {
+        String xml = "<t1><t2><t3>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        assertEquals(writer.out.toString(), "<t1>\n\t<t2>\n\t\t<t3>");
+    }
+
+    @Test
+    public void testOutdentBeforeClosingTag() throws IOException {
+        String xml = "<t1><t2></t2>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        assertEquals(writer.out.toString(), "<t1>\n\t<t2>\n\t</t2>");
+    }
+
+    @Test
+    public void testDontIndentAfterClosingTag() throws IOException {
+        String xml = "<t1><t2></t2></t1>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        assertEquals(writer.out.toString(), "<t1>\n\t<t2>\n\t</t2>\n</t1>");
+    }
+
+    @Test
+    public void testDontIndentWithoutNewLine() throws IOException {
+        String xml = "<t1><t2><t3>Some Text</t3></t2></t1>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        assertEquals(writer.out.toString(), "<t1>\n\t<t2>\n\t\t<t3>Some 
Text</t3>\n\t</t2>\n</t1>");
+    }
+
+    @Test
+    public void testDontIndentSelfClosingTag() throws IOException {
+        String xml = "<t1><t2><t3/></t2></t1>";
+        prettyXmlWriter.write(xml, 0, xml.length());
+
+        assertEquals(writer.out.toString(), 
"<t1>\n\t<t2>\n\t\t<t3/>\n\t</t2>\n</t1>");
+    }
+
+    private int countNewLines() {
+        int newLines = 0;
+        String s = writer.out.toString();
+        for (char c : s.toCharArray()) {
+            if(c=='\n') newLines++;
+        }
+        return newLines;
+    }
+
+    static class RecordingWriter extends Writer {
+
+        StringBuffer out = new StringBuffer();
+
+        @Override
+        public void write(int c) throws IOException {
+            out.append((char) c);
+        }
+
+        @Override
+        public void write(char[] cbuf, int off, int len) throws IOException {
+            out.append(Arrays.copyOfRange(cbuf, off, off + len));
+        }
+
+        @Override
+        public void flush() throws IOException {
+
+        }
+
+        @Override
+        public void close() throws IOException {
+
+        }
+    }
+}
\ No newline at end of file

Reply via email to