Work on logical backups.
[lgpl/argeo-commons.git] / org.argeo.maintenance / src / org / argeo / maintenance / backup / BackupContentHandler.java
index 745d39d1d36f9ad22fabf44bd5d2e8c41d6883bb..ef83c1ff9f0f393253d9768be790fd131fd99f4f 100644 (file)
@@ -3,15 +3,18 @@ package org.argeo.maintenance.backup;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Writer;
+import java.util.Arrays;
 import java.util.Base64;
 import java.util.Set;
 import java.util.TreeSet;
 
 import javax.jcr.Binary;
+import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.commons.io.IOUtils;
+import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrException;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -39,12 +42,17 @@ public class BackupContentHandler extends DefaultHandler {
        private Session session;
        private Set<String> contentPaths = new TreeSet<>();
 
-       private boolean inSystem = false;
+       boolean prettyPrint = true;
 
-       public BackupContentHandler(Writer out, Session session) {
+       private final String parentPath;
+
+//     private boolean inSystem = false;
+
+       public BackupContentHandler(Writer out, Node node) {
                super();
                this.out = out;
-               this.session = session;
+               this.session = Jcr.getSession(node);
+               parentPath = Jcr.getParentPath(node);
        }
 
        private int currentDepth = -1;
@@ -75,18 +83,31 @@ public class BackupContentHandler extends DefaultHandler {
                if (isNode) {
                        String nodeName = attributes.getValue(SV_NAMESPACE_URI, NAME);
                        currentDepth = currentDepth + 1;
-                       if (currentDepth > 0)
-                               currentPath[currentDepth - 1] = nodeName;
+//                     if (currentDepth >= 0)
+                       currentPath[currentDepth] = nodeName;
 //                     System.out.println(getCurrentPath() + " , depth=" + currentDepth);
-                       if ("jcr:system".equals(nodeName)) {
-                               inSystem = true;
-                       }
+//                     if ("jcr:system".equals(nodeName)) {
+//                             inSystem = true;
+//                     }
                }
-               if (inSystem)
-                       return;
+//             if (inSystem)
+//                     return;
 
                if (SV_NAMESPACE_URI.equals(uri))
                        try {
+                               if (prettyPrint) {
+                                       if (isNode) {
+                                               out.write(spaces());
+                                               out.write("<!-- ");
+                                               out.write(getCurrentJcrPath());
+                                               out.write(" -->\n");
+                                               out.write(spaces());
+                                       } else if (isProperty)
+                                               out.write(spaces());
+                                       else if (currentPropertyIsMultiple)
+                                               out.write(spaces());
+                               }
+
                                out.write("<");
                                out.write(SV_PREFIX + ":" + localName);
                                if (isProperty)
@@ -108,9 +129,9 @@ public class BackupContentHandler extends DefaultHandler {
                                                        else if (TYPE.equals(attrName)) {
                                                                if (BINARY.equals(attrValue)) {
                                                                        if (JCR_CONTENT.equals(getCurrentName())) {
-                                                                               contentPaths.add(getCurrentPath());
+                                                                               contentPaths.add(getCurrentJcrPath());
                                                                        } else {
-                                                                               Binary binary = session.getNode(getCurrentPath()).getProperty(attrName)
+                                                                               Binary binary = session.getNode(getCurrentJcrPath()).getProperty(attrName)
                                                                                                .getBinary();
                                                                                try (InputStream in = binary.getStream()) {
                                                                                        currentEncoded = base64encore.encodeToString(IOUtils.toByteArray(in));
@@ -128,10 +149,12 @@ public class BackupContentHandler extends DefaultHandler {
                                        out.write(" xmlns:" + SV_PREFIX + "=\"" + SV_NAMESPACE_URI + "\"");
                                }
                                out.write(">");
-                               if (isNode)
-                                       out.write("\n");
-                               else if (isProperty && currentPropertyIsMultiple)
-                                       out.write("\n");
+
+                               if (prettyPrint)
+                                       if (isNode)
+                                               out.write("\n");
+                                       else if (isProperty && currentPropertyIsMultiple)
+                                               out.write("\n");
                        } catch (IOException e) {
                                throw new RuntimeException(e);
                        } catch (RepositoryException e) {
@@ -141,23 +164,32 @@ public class BackupContentHandler extends DefaultHandler {
 
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
-               if (localName.equals(NODE)) {
+               boolean isNode = localName.equals(NODE);
+               boolean isValue = localName.equals(VALUE);
+               if (prettyPrint)
+                       if (!isValue)
+                               try {
+                                       if (isNode || currentPropertyIsMultiple)
+                                               out.write(spaces());
+                               } catch (IOException e1) {
+                                       throw new RuntimeException(e1);
+                               }
+               if (isNode) {
 //                     System.out.println("endElement " + getCurrentPath() + " , depth=" + currentDepth);
-                       if (currentDepth > 0)
-                               currentPath[currentDepth - 1] = null;
+//                     if (currentDepth > 0)
+                       currentPath[currentDepth] = null;
                        currentDepth = currentDepth - 1;
-                       if (inSystem) {
-                               // System.out.println("Skip " + getCurrentPath()+" ,
-                               // currentDepth="+currentDepth);
-                               if (currentDepth == 0) {
-                                       inSystem = false;
-                                       return;
-                               }
-                       }
+//                     if (inSystem) {
+//                             // System.out.println("Skip " + getCurrentPath()+" ,
+//                             // currentDepth="+currentDepth);
+//                             if (currentDepth == 0) {
+//                                     inSystem = false;
+//                                     return;
+//                             }
+//                     }
                }
-               if (inSystem)
-                       return;
-               boolean isValue = localName.equals(VALUE);
+//             if (inSystem)
+//                     return;
                if (SV_NAMESPACE_URI.equals(uri))
                        try {
                                if (isValue && currentEncoded != null) {
@@ -167,21 +199,31 @@ public class BackupContentHandler extends DefaultHandler {
                                out.write("</");
                                out.write(SV_PREFIX + ":" + localName);
                                out.write(">");
-                               if (!isValue)
-                                       out.write("\n");
-                               else {
-                                       if (currentPropertyIsMultiple)
+                               if (prettyPrint)
+                                       if (!isValue)
                                                out.write("\n");
-                               }
+                                       else {
+                                               if (currentPropertyIsMultiple)
+                                                       out.write("\n");
+                                       }
+                               if (currentDepth == 0)
+                                       out.flush();
                        } catch (IOException e) {
                                throw new RuntimeException(e);
                        }
+
+       }
+
+       private char[] spaces() {
+               char[] arr = new char[currentDepth];
+               Arrays.fill(arr, ' ');
+               return arr;
        }
 
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
-               if (inSystem)
-                       return;
+//             if (inSystem)
+//                     return;
                try {
                        out.write(ch, start, length);
                } catch (IOException e) {
@@ -191,18 +233,18 @@ public class BackupContentHandler extends DefaultHandler {
 
        protected String getCurrentName() {
                assert currentDepth >= 0;
-               if (currentDepth == 0)
-                       return "jcr:root";
-               return currentPath[currentDepth - 1];
+//             if (currentDepth == 0)
+//                     return "jcr:root";
+               return currentPath[currentDepth];
        }
 
-       protected String getCurrentPath() {
-               if (currentDepth == 0)
-                       return "/";
-               StringBuilder sb = new StringBuilder("/");
-               for (int i = 0; i < currentDepth; i++) {
-                       if (i != 0)
-                               sb.append('/');
+       protected String getCurrentJcrPath() {
+//             if (currentDepth == 0)
+//                     return "/";
+               StringBuilder sb = new StringBuilder(parentPath.equals("/") ? "" : parentPath);
+               for (int i = 0; i <= currentDepth; i++) {
+//                     if (i != 0)
+                       sb.append('/');
                        sb.append(currentPath[i]);
                }
                return sb.toString();