1 package org
.argeo
.slc
.client
.ui
.dist
.commands
;
4 import javax
.jcr
.NodeIterator
;
5 import javax
.jcr
.Property
;
6 import javax
.jcr
.PropertyIterator
;
7 import javax
.jcr
.Repository
;
8 import javax
.jcr
.RepositoryException
;
9 import javax
.jcr
.Session
;
10 import javax
.jcr
.nodetype
.NodeType
;
12 import org
.apache
.commons
.logging
.Log
;
13 import org
.apache
.commons
.logging
.LogFactory
;
14 import org
.argeo
.ArgeoException
;
15 import org
.argeo
.jcr
.JcrUtils
;
16 import org
.argeo
.slc
.client
.ui
.dist
.DistPlugin
;
17 import org
.argeo
.slc
.client
.ui
.dist
.utils
.CommandHelpers
;
18 import org
.argeo
.slc
.jcr
.SlcTypes
;
19 import org
.eclipse
.core
.commands
.AbstractHandler
;
20 import org
.eclipse
.core
.commands
.ExecutionEvent
;
21 import org
.eclipse
.core
.commands
.ExecutionException
;
22 import org
.eclipse
.jface
.dialogs
.InputDialog
;
23 import org
.eclipse
.ui
.IWorkbenchWindow
;
26 * Create a copy of the chosen workspace in the current repository.
29 public class CopyWorkspace
extends AbstractHandler
{
30 private static final Log log
= LogFactory
.getLog(CopyWorkspace
.class);
31 public final static String ID
= DistPlugin
.ID
+ ".copyWorkspace";
32 public final static String PARAM_WORKSPACE_NAME
= DistPlugin
.ID
34 public final static String DEFAULT_LABEL
= "Duplicate";
35 public final static String DEFAULT_ICON_PATH
= "icons/addItem.gif";
37 /* DEPENDENCY INJECTION */
38 private Repository repository
;
40 public Object
execute(ExecutionEvent event
) throws ExecutionException
{
41 String srcWorkspaceName
= event
.getParameter(PARAM_WORKSPACE_NAME
);
43 if (log
.isTraceEnabled())
44 log
.debug("WORKSPACE " + srcWorkspaceName
+ " About to be copied");
46 // MessageDialog.openWarning(DistPlugin.getDefault()
47 // .getWorkbench().getDisplay().getActiveShell(),
48 // "WARNING", "Not yet implemented");
51 IWorkbenchWindow iww
= DistPlugin
.getDefault().getWorkbench()
52 .getActiveWorkbenchWindow();
53 InputDialog inputDialog
= new InputDialog(iww
.getShell(),
54 "New copy of the current workspace",
55 "Choose a name for the workspace to create", "", null);
57 String newWorkspaceName
= inputDialog
.getValue();
58 Session srcSession
= null;
59 Session newSession
= null;
61 srcSession
= repository
.login(srcWorkspaceName
);
63 // Create the workspace
64 srcSession
.getWorkspace().createWorkspace(newWorkspaceName
);
65 Node srcRootNode
= srcSession
.getRootNode();
66 // log in the newly created workspace
67 newSession
= repository
.login(newWorkspaceName
);
69 Node newRootNode
= newSession
.getRootNode();
70 copy(srcRootNode
, newRootNode
);
73 CommandHelpers
.callCommand(RefreshDistributionsView
.ID
);
74 } catch (RepositoryException re
) {
75 throw new ArgeoException(
76 "Unexpected error while creating the new workspace.", re
);
78 if (srcSession
!= null)
80 if (newSession
!= null)
86 // FIXME : commons is frozen, cannot fix the problem directly there.
87 // test and report corresponding patch
88 private void copy(Node fromNode
, Node toNode
) {
90 if (log
.isDebugEnabled())
91 log
.debug("copy node :" + fromNode
.getPath());
93 // FIXME : small hack to enable specific workspace copy
94 if (fromNode
.isNodeType("rep:ACL")
95 || fromNode
.isNodeType("rep:system")) {
96 if (log
.isTraceEnabled())
97 log
.trace("node skipped");
102 for (NodeType mixinType
: fromNode
.getMixinNodeTypes()) {
103 toNode
.addMixin(mixinType
.getName());
107 for (NodeType mixinType
: toNode
.getMixinNodeTypes()) {
108 if (log
.isDebugEnabled())
109 log
.debug(mixinType
.getName());
112 // process properties
113 PropertyIterator pit
= fromNode
.getProperties();
114 properties
: while (pit
.hasNext()) {
115 Property fromProperty
= pit
.nextProperty();
116 String propName
= fromProperty
.getName();
118 String propertyName
= fromProperty
.getName();
119 if (toNode
.hasProperty(propertyName
)
120 && toNode
.getProperty(propertyName
).getDefinition()
124 if (fromProperty
.getDefinition().isProtected())
127 if (propertyName
.equals("jcr:created")
128 || propertyName
.equals("jcr:createdBy")
129 || propertyName
.equals("jcr:lastModified")
130 || propertyName
.equals("jcr:lastModifiedBy"))
133 if (fromProperty
.isMultiple()) {
134 toNode
.setProperty(propertyName
,
135 fromProperty
.getValues());
137 toNode
.setProperty(propertyName
,
138 fromProperty
.getValue());
140 } catch (RepositoryException e
) {
141 throw new ArgeoException("Cannot property " + propName
, e
);
145 // recursively process children nodes
146 NodeIterator nit
= fromNode
.getNodes();
147 while (nit
.hasNext()) {
148 Node fromChild
= nit
.nextNode();
149 Integer index
= fromChild
.getIndex();
150 String nodeRelPath
= fromChild
.getName() + "[" + index
+ "]";
152 if (toNode
.hasNode(nodeRelPath
))
153 toChild
= toNode
.getNode(nodeRelPath
);
155 toChild
= toNode
.addNode(fromChild
.getName(), fromChild
156 .getPrimaryNodeType().getName());
157 copy(fromChild
, toChild
);
160 // update jcr:lastModified and jcr:lastModifiedBy in toNode in case
162 if (!toNode
.getDefinition().isProtected()
163 && toNode
.isNodeType(NodeType
.MIX_LAST_MODIFIED
))
164 JcrUtils
.updateLastModified(toNode
);
166 // Workaround to reduce session size: artifact is a saveable unity
167 if (toNode
.isNodeType(SlcTypes
.SLC_ARTIFACT
))
168 toNode
.getSession().save();
170 } catch (RepositoryException e
) {
171 throw new ArgeoException("Cannot copy " + fromNode
+ " to "
176 /* DEPENDENCY INJECTION */
177 public void setRepository(Repository repository
) {
178 this.repository
= repository
;