1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.setup;
35
36 import info.magnolia.cms.core.version.VersionManager;
37 import info.magnolia.jcr.util.NodeTypes;
38 import info.magnolia.jcr.util.NodeUtil;
39 import info.magnolia.module.InstallContext;
40 import info.magnolia.module.delta.AbstractRepositoryTask;
41 import info.magnolia.module.delta.TaskExecutionException;
42 import info.magnolia.repository.RepositoryConstants;
43 import info.magnolia.repository.RepositoryManager;
44
45 import java.util.Collections;
46 import java.util.HashMap;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.stream.Collectors;
50
51 import javax.jcr.ItemNotFoundException;
52 import javax.jcr.Node;
53 import javax.jcr.RepositoryException;
54 import javax.jcr.Session;
55
56 import org.apache.commons.lang3.StringUtils;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
61
62
63
64
65
66 public class MigrateVersionWorkspacesToNewStructureTask extends AbstractRepositoryTask {
67
68 private static final Logger log = LoggerFactory.getLogger(MigrateVersionWorkspacesToNewStructureTask.class);
69
70 private static final String FOUND_IN_MULTIPLE_WORKSPACES_MESSAGE = "Node [%s:%s:%s] found in multiple workspaces [%s]. This means that versions for both nodes are most likely broken and versions needs to be removed.";
71 private static final String ORIGINAL_NODE_NOT_FOUND_MESSAGE = "Version found for node [%s:%s:%s], but original node no longer exists";
72
73 private final RepositoryManager repositoryManager;
74
75 private Map<String, Session> sessions = new HashMap<>();
76
77 public MigrateVersionWorkspacesToNewStructureTask(RepositoryManager repositoryManager) {
78 super("Migrate version workspace", "Migrate version workspace to new structure");
79 this.repositoryManager = repositoryManager;
80 }
81
82 @Override
83 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
84 List<String> versionWorkspaces = repositoryManager.getWorkspaceNames().stream().filter(input -> StringUtils.endsWith(input, RepositoryConstants.VERSION_STORE)).collect(Collectors.toList());
85
86 List<String> workspacesToSearchIn = repositoryManager.getWorkspaceNames().stream().filter(input -> !(StringUtils.endsWith(input, RepositoryConstants.VERSION_STORE) || StringUtils.endsWith(input, RepositoryConstants.SYSTEM))).collect(Collectors.toList());
87
88 Collections.swap(workspacesToSearchIn, workspacesToSearchIn.indexOf(RepositoryConstants.WEBSITE), 0);
89 if (workspacesToSearchIn.contains("dam")) {
90 Collections.swap(workspacesToSearchIn, workspacesToSearchIn.indexOf("dam"), 1);
91 }
92 if (workspacesToSearchIn.contains("contacts")) {
93 Collections.swap(workspacesToSearchIn, workspacesToSearchIn.indexOf("contacts"), 2);
94 }
95 if (workspacesToSearchIn.contains("segments")) {
96 Collections.swap(workspacesToSearchIn, workspacesToSearchIn.indexOf("segments"), 3);
97 }
98 if (workspacesToSearchIn.contains("personas")) {
99 Collections.swap(workspacesToSearchIn, workspacesToSearchIn.indexOf("personas"), 4);
100 }
101
102 for (String versionWorkspace : versionWorkspaces) {
103 Session versionSession = installContext.getJCRSession(versionWorkspace);
104 for (Node versionNode : NodeUtil.getNodes(versionSession.getRootNode())) {
105 if (versionNode.getName().equals(VersionManager.TMP_REFERENCED_NODES) || StringUtils.startsWith(versionNode.getName(), NodeTypes.REP_PREFIX)) {
106 continue;
107 }
108 String uuid = versionNode.getIdentifier();
109
110 Map<String, Node> found = new HashMap<>();
111 Node originalNode = null;
112 for (String workspace : workspacesToSearchIn) {
113 if (!sessions.containsKey(workspace)) {
114 sessions.put(workspace, installContext.getJCRSession(workspace));
115 }
116 try {
117 Node node = sessions.get(workspace).getNodeByIdentifier(uuid);
118 if (node.getPrimaryNodeType().getName().equals(versionNode.getPrimaryNodeType().getName())) {
119 originalNode = node;
120 }
121 found.put(workspace, node);
122 } catch (ItemNotFoundException e) {
123
124 }
125 }
126
127 if (found.size() == 0 || originalNode == null) {
128
129 installContext.warn(String.format(ORIGINAL_NODE_NOT_FOUND_MESSAGE, versionNode.getName(), versionNode.getIdentifier(), versionNode.getPrimaryNodeType().getName()));
130 continue;
131 } else if (found.size() > 1) {
132
133 installContext.warn(String.format(FOUND_IN_MULTIPLE_WORKSPACES_MESSAGE, versionNode.getName(), versionNode.getIdentifier(), versionNode.getPrimaryNodeType().getName(), StringUtils.join(found, ":")));
134 }
135
136
137 Node newParent = NodeUtil.createPath(versionSession.getRootNode(), getSavePath(originalNode), NodeTypes.Folder.NAME, true);
138 NodeUtil.moveNode(versionNode, newParent);
139 originalNode.addMixin(NodeTypes.HasVersion.NAME);
140 log.debug("Moved [{}] to the new location [{}]", newParent.getPath() + "/" + versionNode.getName());
141 }
142 }
143 }
144
145 String getSavePath(Node node) throws RepositoryException {
146 String uuid = node.getIdentifier();
147 return String.format("%s/%s/%s", StringUtils.substring(uuid, 0, 2), StringUtils.substring(uuid, 9, 11), StringUtils.substring(uuid, 14, 16));
148 }
149 }