1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.argeo.slc.client.ui.dist.commands;
17
18 import javax.jcr.Credentials;
19 import javax.jcr.NoSuchWorkspaceException;
20 import javax.jcr.Node;
21 import javax.jcr.Repository;
22 import javax.jcr.RepositoryException;
23 import javax.jcr.RepositoryFactory;
24 import javax.jcr.Session;
25 import javax.jcr.query.Query;
26 import javax.jcr.query.QueryResult;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.argeo.eclipse.ui.EclipseJcrMonitor;
31 import org.argeo.jcr.JcrMonitor;
32 import org.argeo.jcr.JcrUtils;
33 import org.argeo.node.security.Keyring;
34 import org.argeo.slc.SlcException;
35 import org.argeo.slc.client.ui.dist.DistPlugin;
36 import org.argeo.slc.repo.RepoUtils;
37 import org.eclipse.core.commands.AbstractHandler;
38 import org.eclipse.core.commands.ExecutionEvent;
39 import org.eclipse.core.commands.ExecutionException;
40 import org.eclipse.core.runtime.IProgressMonitor;
41 import org.eclipse.core.runtime.IStatus;
42 import org.eclipse.core.runtime.Status;
43 import org.eclipse.core.runtime.jobs.Job;
44
45
46 public class MergeWorkspaces extends AbstractHandler {
47 private final static Log log = LogFactory.getLog(MergeWorkspaces.class);
48
49 public final static String ID = DistPlugin.PLUGIN_ID + ".mergeWorkspaces";
50 public final static String DEFAULT_LABEL = "Merge";
51
52 public final static String PARAM_SOURCE_WORKSPACE_NAME = "srcWkspName";
53 public final static String PARAM_SOURCE_REPO_PATH = "srcRepoPath";
54 public final static String PARAM_TARGET_WORKSPACE_NAME = "targetWkspName";
55 public final static String PARAM_TARGET_REPO_PATH = "targetRepoPath";
56
57
58 private RepositoryFactory repositoryFactory;
59 private Keyring keyring;
60 private Repository nodeRepository;
61
62 public Object execute(ExecutionEvent event) throws ExecutionException {
63 String targetRepoPath = event.getParameter(PARAM_TARGET_REPO_PATH);
64 String targetWkspName = event.getParameter(PARAM_TARGET_WORKSPACE_NAME);
65 String sourceRepoPath = event.getParameter(PARAM_SOURCE_REPO_PATH);
66 String sourceWkspName = event.getParameter(PARAM_SOURCE_WORKSPACE_NAME);
67
68 Session nodeSession = null;
69 try {
70 nodeSession = nodeRepository.login();
71 Node srcRepoNode = nodeSession.getNode(sourceRepoPath);
72 Repository srcRepository = RepoUtils.getRepository(repositoryFactory, keyring, srcRepoNode);
73 Credentials srcCredentials = RepoUtils.getRepositoryCredentials(keyring, srcRepoNode);
74
75 Node targetRepoNode = nodeSession.getNode(targetRepoPath);
76 Repository targetRepository = RepoUtils.getRepository(repositoryFactory, keyring, targetRepoNode);
77 Credentials targetCredentials = RepoUtils.getRepositoryCredentials(keyring, targetRepoNode);
78
79
80
81
82
83
84
85
86
87
88
89
90 Session sourceSession = srcRepository.login(srcCredentials, sourceWkspName);
91 Session targetSession;
92 try {
93 targetSession = targetRepository.login(targetCredentials, targetWkspName);
94 } catch (NoSuchWorkspaceException e) {
95 Session defaultSession = targetRepository.login(targetCredentials);
96 try {
97 defaultSession.getWorkspace().createWorkspace(targetWkspName);
98 } catch (Exception e1) {
99 throw new SlcException("Cannot create new workspace " + targetWkspName, e);
100 } finally {
101 JcrUtils.logoutQuietly(defaultSession);
102 }
103 targetSession = targetRepository.login(targetCredentials, targetWkspName);
104 }
105
106 Job workspaceMergeJob = new WorkspaceMergeJob(sourceSession, targetSession);
107 workspaceMergeJob.setUser(true);
108 workspaceMergeJob.schedule();
109 } catch (RepositoryException re) {
110 throw new SlcException("Unexpected error while merging workspaces.", re);
111 } finally {
112 JcrUtils.logoutQuietly(nodeSession);
113 }
114 return null;
115 }
116
117 private static class WorkspaceMergeJob extends Job {
118 private Session sourceSession;
119 private Session targetSession;
120
121 public WorkspaceMergeJob(Session sourceSession, Session targetSession) {
122 super("Workspace merge");
123 this.sourceSession = sourceSession;
124 this.targetSession = targetSession;
125 }
126
127 @Override
128 protected IStatus run(IProgressMonitor eclipseMonitor) {
129 long begin = System.currentTimeMillis();
130 try {
131 Query countQuery = sourceSession.getWorkspace().getQueryManager()
132 .createQuery("select file from [nt:file] as file", Query.JCR_SQL2);
133 QueryResult result = countQuery.execute();
134 Long expectedCount = result.getNodes().getSize();
135 if (log.isDebugEnabled())
136 log.debug("Will copy " + expectedCount + " files...");
137
138 JcrMonitor monitor = new EclipseJcrMonitor(eclipseMonitor);
139 eclipseMonitor.beginTask("Copy files", expectedCount.intValue());
140
141 Long count = JcrUtils.copyFiles(sourceSession.getRootNode(), targetSession.getRootNode(), true, monitor,
142 true);
143
144 monitor.done();
145 long duration = (System.currentTimeMillis() - begin) / 1000;
146
147 if (log.isDebugEnabled())
148 log.debug("Copied " + count + " files in " + (duration / 60) + "min " + (duration % 60) + "s");
149
150 return Status.OK_STATUS;
151 } catch (RepositoryException e) {
152 return new Status(IStatus.ERROR, DistPlugin.PLUGIN_ID, "Cannot merge", e);
153 } finally {
154 JcrUtils.logoutQuietly(sourceSession);
155 JcrUtils.logoutQuietly(targetSession);
156 }
157 }
158 }
159
160
161 public void setNodeRepository(Repository nodeRepository) {
162 this.nodeRepository = nodeRepository;
163 }
164
165 public void setRepositoryFactory(RepositoryFactory repositoryFactory) {
166 this.repositoryFactory = repositoryFactory;
167 }
168
169 public void setKeyring(Keyring keyring) {
170 this.keyring = keyring;
171 }
172 }