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
.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
;
28 /** Backups a JCR repository */
29 public class JcrRepositoryBackup
implements Runnable
{
30 private final static CmsLog log
= CmsLog
.getLog(JcrRepositoryBackup
.class);
32 private String sourceRepo
;
33 private String sourceDatastore
;
34 private String targetFile
;
36 private String sourceWksp
;
38 private String sourceUsername
;
39 private char[] sourcePassword
;
41 private RepositoryFactory repositoryFactory
;
42 private FileSystemManager fileSystemManager
;
45 Session sourceDefaultSession
= null;
47 long begin
= System
.currentTimeMillis();
49 FileObject archiveRoot
= fileSystemManager
.resolveFile(targetFile
);
50 archiveRoot
.createFolder();
52 String datastoreFolderName
= "datastore";
54 backupDataStore(archiveRoot
.resolveFile(datastoreFolderName
));
56 Repository sourceRepository
= CmsJcrUtils
.getRepositoryByUri(
57 repositoryFactory
, sourceRepo
);
58 Credentials sourceCredentials
= null;
59 if (sourceUsername
!= null)
60 sourceCredentials
= new SimpleCredentials(sourceUsername
,
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();
72 if (sourceWksp
!= null && !sourceWksp
.trim().equals("")
73 && !sourceWorkspaceName
.equals(sourceWksp
))
75 Session sourceSession
= null;
76 JarOutputStream out
= null;
77 FileObject workspaceBackup
= null;
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");
91 out
= new JarOutputStream(workspaceBackup
.getContent()
92 .getOutputStream(), manifest
);
93 sourceSession
= sourceRepository
.login(sourceCredentials
,
95 backupWorkspace(sourceSession
, out
);
97 JcrUtils
.logoutQuietly(sourceSession
);
98 IOUtils
.closeQuietly(out
);
99 if (workspaceBackup
!= null)
100 workspaceBackup
.close();
104 // in case some binaries have been added during the backup
106 backupDataStore(archiveRoot
.resolveFile(datastoreFolderName
));
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
);
114 JcrUtils
.logoutQuietly(sourceDefaultSession
);
118 protected Boolean
hasDatastore() {
119 return sourceDatastore
!= null && !sourceDatastore
.trim().equals("");
122 protected void backupWorkspace(Session sourceSession
, JarOutputStream out
) {
124 if (log
.isTraceEnabled())
125 log
.trace("Backup " + sourceSession
.getWorkspace().getName()
127 Boolean skipBinaries
= hasDatastore();
128 for (NodeIterator it
= sourceSession
.getRootNode().getNodes(); it
130 if (Thread
.interrupted()) {
131 log
.error("Node backup interrupted");
132 Thread
.currentThread().interrupt();
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);
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
);
151 protected void backupDataStore(final FileObject targetDatastore
) {
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
)
164 public boolean includeFile(FileSelectInfo fileInfo
)
166 String relativeName
= fileInfo
171 sourceDataStore
.getName().getPath()
173 FileObject target
= targetDatastore
174 .resolveFile(relativeName
);
175 if (target
.exists()) {
182 if (log
.isDebugEnabled())
183 log
.debug("Backed-up " + sourceDatastore
);
184 } catch (FileSystemException e
) {
185 throw new SlcException("Cannot backup datastore", e
);
189 public void setSourceRepo(String sourceRepo
) {
190 this.sourceRepo
= sourceRepo
;
193 public void setSourceWksp(String sourceWksp
) {
194 this.sourceWksp
= sourceWksp
;
197 public void setRepositoryFactory(RepositoryFactory repositoryFactory
) {
198 this.repositoryFactory
= repositoryFactory
;
201 public void setSourceUsername(String sourceUsername
) {
202 this.sourceUsername
= sourceUsername
;
205 public void setSourcePassword(char[] sourcePassword
) {
206 this.sourcePassword
= sourcePassword
;
209 public void setFileSystemManager(FileSystemManager fileSystemManager
) {
210 this.fileSystemManager
= fileSystemManager
;
213 public void setTargetFile(String targetFile
) {
214 this.targetFile
= targetFile
;
217 public void setSourceDatastore(String sourceDatastore
) {
218 this.sourceDatastore
= sourceDatastore
;