]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoSync.java
Work on repo sync
[gpl/argeo-slc.git] / runtime / org.argeo.slc.repo / src / main / java / org / argeo / slc / repo / RepoSync.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.slc.repo;
17
18 import java.util.Calendar;
19
20 import javax.jcr.Credentials;
21 import javax.jcr.ImportUUIDBehavior;
22 import javax.jcr.NoSuchWorkspaceException;
23 import javax.jcr.Node;
24 import javax.jcr.NodeIterator;
25 import javax.jcr.Property;
26 import javax.jcr.Repository;
27 import javax.jcr.RepositoryException;
28 import javax.jcr.RepositoryFactory;
29 import javax.jcr.Session;
30 import javax.jcr.SimpleCredentials;
31 import javax.jcr.nodetype.NodeType;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.argeo.jcr.ArgeoJcrUtils;
36 import org.argeo.jcr.JcrUtils;
37 import org.argeo.slc.SlcException;
38 import org.xml.sax.ContentHandler;
39 import org.xml.sax.SAXException;
40
41 /** Sync to from software repositories */
42 public class RepoSync implements Runnable {
43 private final static Log log = LogFactory.getLog(RepoSync.class);
44
45 private String sourceRepo;
46 private String targetRepo;
47
48 private String sourceWksp;
49
50 private String sourceUsername;
51 private char[] sourcePassword;
52
53 private RepositoryFactory repositoryFactory;
54
55 public void run() {
56 Session sourceDefaultSession = null;
57 Session targetDefaultSession = null;
58 try {
59 long begin = System.currentTimeMillis();
60
61 Repository sourceRepository = ArgeoJcrUtils.getRepositoryByUri(
62 repositoryFactory, sourceRepo);
63 Repository targetRepository = ArgeoJcrUtils.getRepositoryByUri(
64 repositoryFactory, targetRepo);
65 Credentials sourceCredentials = null;
66 if (sourceUsername != null)
67 sourceCredentials = new SimpleCredentials(sourceUsername,
68 sourcePassword);
69 Credentials targetCredentials = null;
70
71 sourceDefaultSession = sourceRepository.login(sourceCredentials);
72 targetDefaultSession = targetRepository.login(targetCredentials);
73 for (String sourceWorkspaceName : sourceDefaultSession
74 .getWorkspace().getAccessibleWorkspaceNames()) {
75 Session sourceSession = null;
76 Session targetSession = null;
77 try {
78 try {
79 targetSession = targetRepository.login(
80 targetCredentials, sourceWorkspaceName);
81 } catch (NoSuchWorkspaceException e) {
82 targetDefaultSession.getWorkspace().createWorkspace(
83 sourceWorkspaceName);
84 targetSession = targetRepository.login(
85 targetCredentials, sourceWorkspaceName);
86 }
87 sourceSession = sourceRepository.login(sourceCredentials,
88 sourceWorkspaceName);
89 syncWorkspace(sourceSession, targetSession);
90 } finally {
91 JcrUtils.logoutQuietly(sourceSession);
92 JcrUtils.logoutQuietly(targetSession);
93 }
94 }
95 // Session sourceSession = sourceRepository.login(sourceCredentials,
96 // sourceWksp);
97 //
98 // Credentials targetCredentials = null;
99 // Session targetSession = targetRepository.login(targetCredentials,
100 // sourceWksp);
101 //
102 // Long count = JcrUtils.copyFiles(sourceSession.getRootNode(),
103 // targetSession.getRootNode(), true, null);
104
105 long duration = (System.currentTimeMillis() - begin) / 1000;// s
106 log.info("Sync " + sourceRepo + " to " + targetRepo + " in "
107 + (duration / 60)
108
109 + "min " + (duration % 60) + "s");
110 } catch (RepositoryException e) {
111 throw new SlcException("Cannot sync " + sourceRepo + " to "
112 + targetRepo, e);
113 } finally {
114 JcrUtils.logoutQuietly(sourceDefaultSession);
115 JcrUtils.logoutQuietly(targetDefaultSession);
116 }
117 }
118
119 protected void syncWorkspace(Session sourceSession, Session targetSession) {
120 try {
121 if (log.isDebugEnabled())
122 log.debug("Syncing " + sourceSession.getWorkspace().getName()
123 + "...");
124 for (NodeIterator it = sourceSession.getRootNode().getNodes(); it
125 .hasNext();) {
126 Node node = it.nextNode();
127 if (node.getName().equals("jcr:system"))
128 continue;
129 // ContentHandler targetHandler = targetSession
130 // .getWorkspace()
131 // .getImportContentHandler(
132 // "/",
133 // ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
134 // sourceSession.exportSystemView(node.getPath(), targetHandler,
135 // true, false);
136 // if (log.isDebugEnabled())
137 // log.debug(" " + node.getPath());
138 syncNode(node, targetSession.getRootNode());
139 }
140 if (log.isDebugEnabled())
141 log.debug("Synced " + sourceSession.getWorkspace().getName());
142 } catch (Exception e) {
143 throw new SlcException("Cannot sync "
144 + sourceSession.getWorkspace().getName() + " to "
145 + targetSession.getWorkspace().getName(), e);
146 }
147 }
148
149 protected void syncNode(Node sourceNode, Node targetParentNode)
150 throws RepositoryException, SAXException {
151 Boolean noRecurse = noRecurse(sourceNode);
152 if (!targetParentNode.hasNode(sourceNode.getName())) {
153 ContentHandler contentHandler = targetParentNode
154 .getSession()
155 .getWorkspace()
156 .getImportContentHandler(targetParentNode.getPath(),
157 ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
158 sourceNode.getSession().exportSystemView(sourceNode.getPath(),
159 contentHandler, false, noRecurse);
160 if (log.isDebugEnabled())
161 log.debug("Add " + sourceNode.getPath());
162 } else {
163 Node targetNode = targetParentNode.getNode(sourceNode.getName());
164 if (sourceNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
165 Calendar sourceLastModified = sourceNode.getProperty(
166 Property.JCR_LAST_MODIFIED).getDate();
167 Calendar targetLastModified = null;
168 if (targetNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
169 targetLastModified = targetNode.getProperty(
170 Property.JCR_LAST_MODIFIED).getDate();
171 }
172
173 if (targetLastModified == null
174 || targetLastModified.before(sourceLastModified)) {
175 ContentHandler contentHandler = targetParentNode
176 .getSession()
177 .getWorkspace()
178 .getImportContentHandler(
179 targetParentNode.getPath(),
180 ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
181 sourceNode.getSession().exportSystemView(
182 sourceNode.getPath(), contentHandler, false,
183 noRecurse);
184 if (log.isDebugEnabled())
185 log.debug("Update " + targetNode.getPath());
186 } else {
187 if (log.isDebugEnabled())
188 log.debug("Skip up to date " + targetNode.getPath());
189 }
190 }
191 }
192
193 if (noRecurse) {
194 // recurse
195 Node targetNode = targetParentNode.getNode(sourceNode.getName());
196 for (NodeIterator it = sourceNode.getNodes(); it.hasNext();) {
197 syncNode(it.nextNode(), targetNode);
198 }
199 }
200
201 }
202
203 protected Boolean noRecurse(Node sourceNode) throws RepositoryException {
204 if (sourceNode.isNodeType(NodeType.NT_FILE))
205 return false;
206 return true;
207 }
208
209 public void setSourceRepo(String sourceRepo) {
210 this.sourceRepo = sourceRepo;
211 }
212
213 public void setTargetRepo(String targetRepo) {
214 this.targetRepo = targetRepo;
215 }
216
217 public void setSourceWksp(String sourceWksp) {
218 this.sourceWksp = sourceWksp;
219 }
220
221 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
222 this.repositoryFactory = repositoryFactory;
223 }
224
225 public void setSourceUsername(String sourceUsername) {
226 this.sourceUsername = sourceUsername;
227 }
228
229 public void setSourcePassword(char[] sourcePassword) {
230 this.sourcePassword = sourcePassword;
231 }
232 }