]> git.argeo.org Git - gpl/argeo-slc.git/blob - legacy/org.argeo.slc.support/src/org/argeo/slc/lib/jcr/JcrRepositoryBackup.java
ef0c4fa9ef77789d5e468be038920a16a9e3f3a4
[gpl/argeo-slc.git] / legacy / org.argeo.slc.support / src / org / argeo / slc / lib / jcr / JcrRepositoryBackup.java
1 package org.argeo.slc.lib.jcr;
2
3 import java.util.UUID;
4 import java.util.jar.Attributes;
5 import java.util.jar.JarEntry;
6 import java.util.jar.JarOutputStream;
7 import java.util.jar.Manifest;
8
9 import javax.jcr.Credentials;
10 import javax.jcr.Node;
11 import javax.jcr.NodeIterator;
12 import javax.jcr.Repository;
13 import javax.jcr.RepositoryFactory;
14 import javax.jcr.Session;
15 import javax.jcr.SimpleCredentials;
16
17 import org.apache.commons.io.IOUtils;
18 import org.apache.commons.vfs2.FileObject;
19 import org.apache.commons.vfs2.FileSelectInfo;
20 import org.apache.commons.vfs2.FileSelector;
21 import org.apache.commons.vfs2.FileSystemException;
22 import org.apache.commons.vfs2.FileSystemManager;
23 import org.argeo.api.cms.CmsLog;
24 import org.argeo.cms.jcr.CmsJcrUtils;
25 import org.argeo.jcr.JcrUtils;
26 import org.argeo.slc.SlcException;
27
28 /** Backups a JCR repository */
29 public class JcrRepositoryBackup implements Runnable {
30 private final static CmsLog log = CmsLog.getLog(JcrRepositoryBackup.class);
31
32 private String sourceRepo;
33 private String sourceDatastore;
34 private String targetFile;
35
36 private String sourceWksp;
37
38 private String sourceUsername;
39 private char[] sourcePassword;
40
41 private RepositoryFactory repositoryFactory;
42 private FileSystemManager fileSystemManager;
43
44 public void run() {
45 Session sourceDefaultSession = null;
46 try {
47 long begin = System.currentTimeMillis();
48
49 FileObject archiveRoot = fileSystemManager.resolveFile(targetFile);
50 archiveRoot.createFolder();
51
52 String datastoreFolderName = "datastore";
53 if (hasDatastore())
54 backupDataStore(archiveRoot.resolveFile(datastoreFolderName));
55
56 Repository sourceRepository = CmsJcrUtils.getRepositoryByUri(
57 repositoryFactory, sourceRepo);
58 Credentials sourceCredentials = null;
59 if (sourceUsername != null)
60 sourceCredentials = new SimpleCredentials(sourceUsername,
61 sourcePassword);
62
63 sourceDefaultSession = sourceRepository.login(sourceCredentials);
64 for (String sourceWorkspaceName : sourceDefaultSession
65 .getWorkspace().getAccessibleWorkspaceNames()) {
66 if (Thread.interrupted()) {
67 log.error("Workspace backup interrupted");
68 Thread.currentThread().interrupt();
69 return;
70 }
71
72 if (sourceWksp != null && !sourceWksp.trim().equals("")
73 && !sourceWorkspaceName.equals(sourceWksp))
74 continue;
75 Session sourceSession = null;
76 JarOutputStream out = null;
77 FileObject workspaceBackup = null;
78 try {
79 Manifest manifest = new Manifest();
80 manifest.getMainAttributes().put(
81 Attributes.Name.MANIFEST_VERSION, "1.0");
82 manifest.getMainAttributes().putValue("Backup-UUID",
83 UUID.randomUUID().toString());
84 manifest.getMainAttributes().putValue("Backup-Timestamp",
85 Long.toString(System.currentTimeMillis()));
86 manifest.getMainAttributes().putValue(
87 "Backup-JCR-Workspace", sourceWorkspaceName);
88 workspaceBackup = fileSystemManager.resolveFile(targetFile
89 + "/" + sourceWorkspaceName + ".jar");
90
91 out = new JarOutputStream(workspaceBackup.getContent()
92 .getOutputStream(), manifest);
93 sourceSession = sourceRepository.login(sourceCredentials,
94 sourceWorkspaceName);
95 backupWorkspace(sourceSession, out);
96 } finally {
97 JcrUtils.logoutQuietly(sourceSession);
98 IOUtils.closeQuietly(out);
99 if (workspaceBackup != null)
100 workspaceBackup.close();
101 }
102 }
103
104 // in case some binaries have been added during the backup
105 if (hasDatastore())
106 backupDataStore(archiveRoot.resolveFile(datastoreFolderName));
107
108 long duration = (System.currentTimeMillis() - begin) / 1000;// s
109 log.info("Backed-up " + sourceRepo + " in " + (duration / 60)
110 + "min " + (duration % 60) + "s");
111 } catch (Exception e) {
112 throw new SlcException("Cannot backup " + sourceRepo, e);
113 } finally {
114 JcrUtils.logoutQuietly(sourceDefaultSession);
115 }
116 }
117
118 protected Boolean hasDatastore() {
119 return sourceDatastore != null && !sourceDatastore.trim().equals("");
120 }
121
122 protected void backupWorkspace(Session sourceSession, JarOutputStream out) {
123 try {
124 if (log.isTraceEnabled())
125 log.trace("Backup " + sourceSession.getWorkspace().getName()
126 + "...");
127 Boolean skipBinaries = hasDatastore();
128 for (NodeIterator it = sourceSession.getRootNode().getNodes(); it
129 .hasNext();) {
130 if (Thread.interrupted()) {
131 log.error("Node backup interrupted");
132 Thread.currentThread().interrupt();
133 return;
134 }
135 Node node = it.nextNode();
136 JarEntry entry = new JarEntry(node.getPath());
137 out.putNextEntry(entry);
138 sourceSession.exportSystemView(node.getPath(), out,
139 skipBinaries, false);
140 out.flush();
141 out.closeEntry();
142 }
143 if (log.isDebugEnabled())
144 log.debug("Backed up " + sourceSession.getWorkspace().getName());
145 } catch (Exception e) {
146 throw new SlcException("Cannot backup "
147 + sourceSession.getWorkspace().getName(), e);
148 }
149 }
150
151 protected void backupDataStore(final FileObject targetDatastore) {
152 try {
153 targetDatastore.createFolder();
154 final FileObject sourceDataStore = fileSystemManager
155 .resolveFile(sourceDatastore);
156 if (log.isDebugEnabled())
157 log.debug("Backup " + sourceDatastore);
158 targetDatastore.copyFrom(sourceDataStore, new FileSelector() {
159 public boolean traverseDescendents(FileSelectInfo fileInfo)
160 throws Exception {
161 return true;
162 }
163
164 public boolean includeFile(FileSelectInfo fileInfo)
165 throws Exception {
166 String relativeName = fileInfo
167 .getFile()
168 .getName()
169 .getPath()
170 .substring(
171 sourceDataStore.getName().getPath()
172 .length());
173 FileObject target = targetDatastore
174 .resolveFile(relativeName);
175 if (target.exists()) {
176 return false;
177 } else {
178 return true;
179 }
180 }
181 });
182 if (log.isDebugEnabled())
183 log.debug("Backed-up " + sourceDatastore);
184 } catch (FileSystemException e) {
185 throw new SlcException("Cannot backup datastore", e);
186 }
187 }
188
189 public void setSourceRepo(String sourceRepo) {
190 this.sourceRepo = sourceRepo;
191 }
192
193 public void setSourceWksp(String sourceWksp) {
194 this.sourceWksp = sourceWksp;
195 }
196
197 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
198 this.repositoryFactory = repositoryFactory;
199 }
200
201 public void setSourceUsername(String sourceUsername) {
202 this.sourceUsername = sourceUsername;
203 }
204
205 public void setSourcePassword(char[] sourcePassword) {
206 this.sourcePassword = sourcePassword;
207 }
208
209 public void setFileSystemManager(FileSystemManager fileSystemManager) {
210 this.fileSystemManager = fileSystemManager;
211 }
212
213 public void setTargetFile(String targetFile) {
214 this.targetFile = targetFile;
215 }
216
217 public void setSourceDatastore(String sourceDatastore) {
218 this.sourceDatastore = sourceDatastore;
219 }
220
221 }