Sync repos
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 4 Feb 2013 13:20:39 +0000 (13:20 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 4 Feb 2013 13:20:39 +0000 (13:20 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6069 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

lib/org.argeo.slc.lib.repo/META-INF/spring/sync.xml
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoSync.java

index 34e0d47b517c6c8144045b16d12f09541877c139..a33af23682a54e49bb71f8ce55faec82c6c339dd 100644 (file)
@@ -14,6 +14,9 @@
                        <flow:primitive name="sourceUsername" value="${user.name}" />\r
                        <flow:primitive name="sourcePassword" type="password"\r
                                value="" />\r
+                       <flow:primitive name="targetUsername" value="${user.name}" />\r
+                       <flow:primitive name="targetPassword" type="password"\r
+                               value="" />\r
                        <flow:primitive name="targetRepo" value="vm:///java/" />\r
                </flow:spec>\r
                <bean class="org.argeo.slc.repo.RepoSync">\r
@@ -22,6 +25,8 @@
                        <property name="sourceWksp" value="@{sourceWksp}" />\r
                        <property name="sourceUsername" value="@{sourceUsername}" />\r
                        <property name="sourcePassword" value="@{sourcePassword}" />\r
+                       <property name="targetUsername" value="@{sourceUsername}" />\r
+                       <property name="targetPassword" value="@{sourcePassword}" />\r
                        <property name="targetRepo" value="@{targetRepo}" />\r
                        <property name="repositoryFactory" ref="repositoryFactory" />\r
                </bean>\r
index 4f8e924f4cb31a9fd70303b3cc1e823faf277695..bdde722dea68934c2b8cbe28b1cb1842f03ff0e9 100644 (file)
 package org.argeo.slc.repo;
 
 import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
 
 import javax.jcr.Credentials;
 import javax.jcr.ImportUUIDBehavior;
@@ -42,6 +46,8 @@ import org.xml.sax.SAXException;
 public class RepoSync implements Runnable {
        private final static Log log = LogFactory.getLog(RepoSync.class);
 
+       private final Calendar zero;
+
        private String sourceRepo;
        private String targetRepo;
 
@@ -49,9 +55,16 @@ public class RepoSync implements Runnable {
 
        private String sourceUsername;
        private char[] sourcePassword;
+       private String targetUsername;
+       private char[] targetPassword;
 
        private RepositoryFactory repositoryFactory;
 
+       public RepoSync() {
+               zero = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+               zero.setTimeInMillis(0);
+       }
+
        public void run() {
                Session sourceDefaultSession = null;
                Session targetDefaultSession = null;
@@ -67,11 +80,22 @@ public class RepoSync implements Runnable {
                                sourceCredentials = new SimpleCredentials(sourceUsername,
                                                sourcePassword);
                        Credentials targetCredentials = null;
+                       if (targetUsername != null)
+                               targetCredentials = new SimpleCredentials(targetUsername,
+                                               targetPassword);
 
+                       Map<String, Exception> errors = new HashMap<String, Exception>();
                        sourceDefaultSession = sourceRepository.login(sourceCredentials);
                        targetDefaultSession = targetRepository.login(targetCredentials);
                        for (String sourceWorkspaceName : sourceDefaultSession
                                        .getWorkspace().getAccessibleWorkspaceNames()) {
+                               if (sourceWksp != null && !sourceWksp.trim().equals("")
+                                               && !sourceWorkspaceName.equals(sourceWksp))
+                                       continue;
+                               if (sourceWorkspaceName.equals("security"))
+                                       continue;
+                               if (sourceWorkspaceName.equals("localrepo"))
+                                       continue;
                                Session sourceSession = null;
                                Session targetSession = null;
                                try {
@@ -87,6 +111,9 @@ public class RepoSync implements Runnable {
                                        sourceSession = sourceRepository.login(sourceCredentials,
                                                        sourceWorkspaceName);
                                        syncWorkspace(sourceSession, targetSession);
+                               } catch (Exception e) {
+                                       errors.put("Could not sync workspace "
+                                                       + sourceWorkspaceName, e);
                                } finally {
                                        JcrUtils.logoutQuietly(sourceSession);
                                        JcrUtils.logoutQuietly(targetSession);
@@ -107,6 +134,10 @@ public class RepoSync implements Runnable {
                                        + (duration / 60)
 
                                        + "min " + (duration % 60) + "s");
+
+                       if (errors.size() > 0) {
+                               throw new SlcException("Sync failed " + errors);
+                       }
                } catch (RepositoryException e) {
                        throw new SlcException("Cannot sync " + sourceRepo + " to "
                                        + targetRepo, e);
@@ -149,6 +180,12 @@ public class RepoSync implements Runnable {
        protected void syncNode(Node sourceNode, Node targetParentNode)
                        throws RepositoryException, SAXException {
                Boolean noRecurse = noRecurse(sourceNode);
+               Calendar sourceLastModified = null;
+               if (sourceNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+                       sourceLastModified = sourceNode.getProperty(
+                                       Property.JCR_LAST_MODIFIED).getDate();
+               }
+
                if (!targetParentNode.hasNode(sourceNode.getName())) {
                        ContentHandler contentHandler = targetParentNode
                                        .getSession()
@@ -158,12 +195,10 @@ public class RepoSync implements Runnable {
                        sourceNode.getSession().exportSystemView(sourceNode.getPath(),
                                        contentHandler, false, noRecurse);
                        if (log.isDebugEnabled())
-                               log.debug("Add " + sourceNode.getPath());
+                               log.debug("Added " + sourceNode.getPath());
                } else {
                        Node targetNode = targetParentNode.getNode(sourceNode.getName());
-                       if (sourceNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
-                               Calendar sourceLastModified = sourceNode.getProperty(
-                                               Property.JCR_LAST_MODIFIED).getDate();
+                       if (sourceLastModified != null) {
                                Calendar targetLastModified = null;
                                if (targetNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
                                        targetLastModified = targetNode.getProperty(
@@ -182,10 +217,12 @@ public class RepoSync implements Runnable {
                                                        sourceNode.getPath(), contentHandler, false,
                                                        noRecurse);
                                        if (log.isDebugEnabled())
-                                               log.debug("Update " + targetNode.getPath());
+                                               log.debug("Updated " + targetNode.getPath());
                                } else {
                                        if (log.isDebugEnabled())
-                                               log.debug("Skip up to date " + targetNode.getPath());
+                                               log.debug("Skipped up to date " + targetNode.getPath());
+                                       // if (!noRecurse)
+                                       return;
                                }
                        }
                }
@@ -193,9 +230,22 @@ public class RepoSync implements Runnable {
                if (noRecurse) {
                        // recurse
                        Node targetNode = targetParentNode.getNode(sourceNode.getName());
+                       if (sourceLastModified != null) {
+                               Calendar zero = new GregorianCalendar();
+                               zero.setTimeInMillis(0);
+                               targetNode.setProperty(Property.JCR_LAST_MODIFIED, zero);
+                               targetNode.getSession().save();
+                       }
+
                        for (NodeIterator it = sourceNode.getNodes(); it.hasNext();) {
                                syncNode(it.nextNode(), targetNode);
                        }
+
+                       if (sourceLastModified != null) {
+                               targetNode.setProperty(Property.JCR_LAST_MODIFIED,
+                                               sourceLastModified);
+                               targetNode.getSession().save();
+                       }
                }
 
        }