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.ui.contentapp.setup.for5_3;
35
36 import info.magnolia.jcr.RuntimeRepositoryException;
37 import info.magnolia.jcr.predicate.AbstractPredicate;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.module.InstallContext;
40 import info.magnolia.module.delta.NodeVisitorTask;
41 import info.magnolia.module.delta.TaskExecutionException;
42 import info.magnolia.repository.RepositoryConstants;
43
44 import java.util.HashSet;
45 import java.util.Set;
46
47 import javax.jcr.Node;
48 import javax.jcr.Property;
49 import javax.jcr.PropertyIterator;
50 import javax.jcr.RepositoryException;
51 import javax.jcr.Session;
52
53 import org.apache.jackrabbit.commons.predicate.Predicate;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58
59
60
61
62
63
64
65
66 public class MigrateJcrPropertiesToContentConnectorTask extends NodeVisitorTask {
67
68 private static final Logger log = LoggerFactory.getLogger(MigrateJcrPropertiesToContentConnectorTask.class);
69
70 private static final String WORKBENCH_NODENAME = "workbench";
71 private static final String EDITOR_NODENAME = "editor";
72 private static final String CONTENTCONNECTOR_NODENAME = "contentConnector";
73 private static final String PATH_PROPERTY = "path";
74 private static final String ROOTPATH_PROPERTY = "rootPath";
75
76 private final Set<Node> nodesToRemove = new HashSet<Node>();
77
78 public MigrateJcrPropertiesToContentConnectorTask(String path) {
79 super("Migrate properties workspace, path from workbench and migrate workspace from editor and add them to a node called contentConnector and add this new node to workbench respectively editor.",
80 "Migrating properties workspace, path from workbench and migrating workspace from editor and adding them to a node called contentConnector and adding the new node to workbench respectively editor.",
81 RepositoryConstants.CONFIG, path);
82 }
83
84 public MigrateJcrPropertiesToContentConnectorTask() {
85 this("/");
86 }
87
88 @Override
89 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
90 super.doExecute(installContext);
91
92 if (!nodesToRemove.isEmpty()) {
93 for (Node node : nodesToRemove) {
94 node.remove();
95 }
96 }
97 }
98
99 @Override
100 protected boolean nodeMatches(Node node) {
101 try {
102 return node.getPrimaryNodeType().getName().equals(NodeTypes.ContentNode.NAME) &&
103 (node.getName().equals(WORKBENCH_NODENAME) || node.getName().equals(EDITOR_NODENAME));
104 } catch (RepositoryException e) {
105 log.error("Couldn't evaluate visited node's name or node-type", e);
106 }
107 return false;
108 }
109
110 @Override
111 protected void operateOnNode(InstallContext installContext, Node node) {
112
113 try {
114 Node subAppNode = node.getParent();
115 if (!"subApps".equals(subAppNode.getParent().getName()) && !subAppNode.hasProperty("subAppClass")) {
116 return;
117 }
118
119 Node contentConnectorNode = subAppNode.hasNode(CONTENTCONNECTOR_NODENAME) ? subAppNode.getNode(CONTENTCONNECTOR_NODENAME) : subAppNode.addNode(CONTENTCONNECTOR_NODENAME, NodeTypes.ContentNode.NAME);
120
121
122 if (WORKBENCH_NODENAME.equals(node.getName())) {
123 migrateProperty("workspace", node, contentConnectorNode);
124 migrateProperty("path", node, contentConnectorNode);
125 migrateProperty("includeProperties", node, contentConnectorNode);
126 migrateProperty("includeSystemNodes", node, contentConnectorNode);
127 migrateProperty("defaultOrder", node, contentConnectorNode);
128 migrateNode("nodeTypes", node, contentConnectorNode, installContext.getJCRSession(RepositoryConstants.CONFIG));
129 }
130
131 else {
132 migrateProperty("workspace", node, contentConnectorNode);
133 }
134
135 boolean nodeCleared = !node.getNodes().hasNext();
136 for (final PropertyIterator it = node.getProperties(); nodeCleared && it.hasNext();) {
137 final String propertyName = it.nextProperty().getName();
138 nodeCleared = propertyName.startsWith(NodeTypes.MGNL_PREFIX) || propertyName.startsWith(NodeTypes.JCR_PREFIX) || propertyName.equals("extends");
139 }
140
141 if (nodeCleared) {
142
143 nodesToRemove.add(node);
144 }
145 } catch (RepositoryException e) {
146 throw new RuntimeRepositoryException("Failed to migrate JCR-properties to contentConnector.",e);
147 }
148 }
149
150 private void migrateNode(String nodeName, Node sourceNode, Node destNode, Session jcrSession) throws RepositoryException {
151 if (sourceNode.hasNode(nodeName)) {
152 if (destNode.hasNode(nodeName)) {
153 destNode.getNode(nodeName).remove();
154 }
155
156 jcrSession.move(sourceNode.getNode(nodeName).getPath(), destNode.getPath() + "/" + nodeName);
157 }
158 }
159
160
161
162
163
164 private void migrateProperty(String propertyName, Node sourceNode, Node destNode) throws RepositoryException {
165 if (sourceNode.hasProperty(propertyName)) {
166 Property sourceNodeProperty = sourceNode.getProperty(propertyName);
167 if (!PATH_PROPERTY.equals(propertyName)) {
168 destNode.setProperty(propertyName, sourceNodeProperty.getString());
169 } else {
170 destNode.setProperty(ROOTPATH_PROPERTY, sourceNodeProperty.getString());
171 }
172 sourceNodeProperty.remove();
173 }
174 }
175
176 @Override
177 protected Predicate getFilteringPredicate() {
178 return new AbstractPredicate<Node>() {
179
180 @Override
181 public boolean evaluateTyped(Node node) {
182 try {
183
184 if (nodesToRemove.contains(node.getParent())) {
185 return false;
186 }
187 } catch (RepositoryException e) {
188 log.warn("Couldn't get parent of visited node, not filtering subtree for NodeVisitor.");
189 }
190 return true;
191 }
192 };
193 }
194 }