1 package org
.argeo
.slc
.lib
.jcr
;
4 import java
.util
.jar
.Attributes
;
5 import java
.util
.jar
.JarEntry
;
6 import java
.util
.jar
.JarOutputStream
;
7 import java
.util
.jar
.Manifest
;
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
;
17 import org
.apache
.commons
.io
.IOUtils
;
18 import org
.apache
.commons
.logging
.Log
;
19 import org
.apache
.commons
.logging
.LogFactory
;
20 import org
.apache
.commons
.vfs2
.FileObject
;
21 import org
.apache
.commons
.vfs2
.FileSelectInfo
;
22 import org
.apache
.commons
.vfs2
.FileSelector
;
23 import org
.apache
.commons
.vfs2
.FileSystemException
;
24 import org
.apache
.commons
.vfs2
.FileSystemManager
;
25 import org
.argeo
.jcr
.JcrUtils
;
26 import org
.argeo
.api
.NodeUtils
;
27 import org
.argeo
.slc
.SlcException
;
29 /** Backups a JCR repository */
30 public class JcrRepositoryBackup
implements Runnable
{
31 private final static Log log
= LogFactory
.getLog(JcrRepositoryBackup
.class);
33 private String sourceRepo
;
34 private String sourceDatastore
;
35 private String targetFile
;
37 private String sourceWksp
;
39 private String sourceUsername
;
40 private char[] sourcePassword
;
42 private RepositoryFactory repositoryFactory
;
43 private FileSystemManager fileSystemManager
;
46 Session sourceDefaultSession
= null;
48 long begin
= System
.currentTimeMillis();
50 FileObject archiveRoot
= fileSystemManager
.resolveFile(targetFile
);
51 archiveRoot
.createFolder();
53 String datastoreFolderName
= "datastore";
55 backupDataStore(archiveRoot
.resolveFile(datastoreFolderName
));
57 Repository sourceRepository
= NodeUtils
.getRepositoryByUri(
58 repositoryFactory
, sourceRepo
);
59 Credentials sourceCredentials
= null;
60 if (sourceUsername
!= null)
61 sourceCredentials
= new SimpleCredentials(sourceUsername
,
64 sourceDefaultSession
= sourceRepository
.login(sourceCredentials
);
65 for (String sourceWorkspaceName
: sourceDefaultSession
66 .getWorkspace().getAccessibleWorkspaceNames()) {
67 if (Thread
.interrupted()) {
68 log
.error("Workspace backup interrupted");
69 Thread
.currentThread().interrupt();
73 if (sourceWksp
!= null && !sourceWksp
.trim().equals("")
74 && !sourceWorkspaceName
.equals(sourceWksp
))
76 Session sourceSession
= null;
77 JarOutputStream out
= null;
78 FileObject workspaceBackup
= null;
80 Manifest manifest
= new Manifest();
81 manifest
.getMainAttributes().put(
82 Attributes
.Name
.MANIFEST_VERSION
, "1.0");
83 manifest
.getMainAttributes().putValue("Backup-UUID",
84 UUID
.randomUUID().toString());
85 manifest
.getMainAttributes().putValue("Backup-Timestamp",
86 Long
.toString(System
.currentTimeMillis()));
87 manifest
.getMainAttributes().putValue(
88 "Backup-JCR-Workspace", sourceWorkspaceName
);
89 workspaceBackup
= fileSystemManager
.resolveFile(targetFile
90 + "/" + sourceWorkspaceName
+ ".jar");
92 out
= new JarOutputStream(workspaceBackup
.getContent()
93 .getOutputStream(), manifest
);
94 sourceSession
= sourceRepository
.login(sourceCredentials
,
96 backupWorkspace(sourceSession
, out
);
98 JcrUtils
.logoutQuietly(sourceSession
);
99 IOUtils
.closeQuietly(out
);
100 if (workspaceBackup
!= null)
101 workspaceBackup
.close();
105 // in case some binaries have been added during the backup
107 backupDataStore(archiveRoot
.resolveFile(datastoreFolderName
));
109 long duration
= (System
.currentTimeMillis() - begin
) / 1000;// s
110 log
.info("Backed-up " + sourceRepo
+ " in " + (duration
/ 60)
111 + "min " + (duration
% 60) + "s");
112 } catch (Exception e
) {
113 throw new SlcException("Cannot backup " + sourceRepo
, e
);
115 JcrUtils
.logoutQuietly(sourceDefaultSession
);
119 protected Boolean
hasDatastore() {
120 return sourceDatastore
!= null && !sourceDatastore
.trim().equals("");
123 protected void backupWorkspace(Session sourceSession
, JarOutputStream out
) {
125 if (log
.isTraceEnabled())
126 log
.trace("Backup " + sourceSession
.getWorkspace().getName()
128 Boolean skipBinaries
= hasDatastore();
129 for (NodeIterator it
= sourceSession
.getRootNode().getNodes(); it
131 if (Thread
.interrupted()) {
132 log
.error("Node backup interrupted");
133 Thread
.currentThread().interrupt();
136 Node node
= it
.nextNode();
137 JarEntry entry
= new JarEntry(node
.getPath());
138 out
.putNextEntry(entry
);
139 sourceSession
.exportSystemView(node
.getPath(), out
,
140 skipBinaries
, false);
144 if (log
.isDebugEnabled())
145 log
.debug("Backed up " + sourceSession
.getWorkspace().getName());
146 } catch (Exception e
) {
147 throw new SlcException("Cannot backup "
148 + sourceSession
.getWorkspace().getName(), e
);
152 protected void backupDataStore(final FileObject targetDatastore
) {
154 targetDatastore
.createFolder();
155 final FileObject sourceDataStore
= fileSystemManager
156 .resolveFile(sourceDatastore
);
157 if (log
.isDebugEnabled())
158 log
.debug("Backup " + sourceDatastore
);
159 targetDatastore
.copyFrom(sourceDataStore
, new FileSelector() {
160 public boolean traverseDescendents(FileSelectInfo fileInfo
)
165 public boolean includeFile(FileSelectInfo fileInfo
)
167 String relativeName
= fileInfo
172 sourceDataStore
.getName().getPath()
174 FileObject target
= targetDatastore
175 .resolveFile(relativeName
);
176 if (target
.exists()) {
183 if (log
.isDebugEnabled())
184 log
.debug("Backed-up " + sourceDatastore
);
185 } catch (FileSystemException e
) {
186 throw new SlcException("Cannot backup datastore", e
);
190 public void setSourceRepo(String sourceRepo
) {
191 this.sourceRepo
= sourceRepo
;
194 public void setSourceWksp(String sourceWksp
) {
195 this.sourceWksp
= sourceWksp
;
198 public void setRepositoryFactory(RepositoryFactory repositoryFactory
) {
199 this.repositoryFactory
= repositoryFactory
;
202 public void setSourceUsername(String sourceUsername
) {
203 this.sourceUsername
= sourceUsername
;
206 public void setSourcePassword(char[] sourcePassword
) {
207 this.sourcePassword
= sourcePassword
;
210 public void setFileSystemManager(FileSystemManager fileSystemManager
) {
211 this.fileSystemManager
= fileSystemManager
;
214 public void setTargetFile(String targetFile
) {
215 this.targetFile
= targetFile
;
218 public void setSourceDatastore(String sourceDatastore
) {
219 this.sourceDatastore
= sourceDatastore
;