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.for5_0;
35
36 import info.magnolia.module.InstallContext;
37 import info.magnolia.module.delta.AbstractRepositoryTask;
38 import info.magnolia.module.delta.TaskExecutionException;
39
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.Iterator;
43 import java.util.LinkedHashMap;
44 import java.util.List;
45 import java.util.Set;
46
47 import javax.jcr.NamespaceException;
48 import javax.jcr.RepositoryException;
49 import javax.jcr.nodetype.NodeTypeDefinition;
50 import javax.jcr.nodetype.NodeTypeManager;
51 import javax.jcr.nodetype.NodeTypeTemplate;
52
53 import org.apache.commons.lang3.StringUtils;
54 import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
55 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
56 import org.apache.jackrabbit.spi.Name;
57 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 public abstract class AbstractNodeTypeRegistrationTask extends AbstractRepositoryTask {
95
96 private final Logger log = LoggerFactory.getLogger(AbstractNodeTypeRegistrationTask.class);
97
98 private String workspaceName;
99
100 public AbstractNodeTypeRegistrationTask(String name, String description, String workspaceName) {
101 super(name, description);
102 this.workspaceName = workspaceName;
103 }
104
105 @Override
106 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
107 if (StringUtils.isBlank(workspaceName)) {
108 log.warn("No workspace defined. This task will resume");
109 return;
110 }
111
112 NodeTypeManager nodeTypeManager = installContext.getJCRSession(workspaceName).getWorkspace().getNodeTypeManager();
113
114
115 List<NodeTypeDefinition> nodeTypeToRegister = getNodeTypesToRegister(nodeTypeManager);
116 if (nodeTypeToRegister == null || nodeTypeToRegister.isEmpty()) {
117 log.info("No NodeType defined to register for the following workspace '{}'", workspaceName);
118 } else {
119
120 registerNodeTypes(nodeTypeManager, nodeTypeToRegister, installContext);
121 }
122
123 List<String> nodeTypeToUnregister = getNodeTypesToUnregister(nodeTypeManager);
124 if (nodeTypeToUnregister == null || nodeTypeToUnregister.isEmpty()) {
125 log.info("No NodeType defined to unregister for the following workspace '{}'", workspaceName);
126 } else {
127 try {
128 unregisterNodeTypes(nodeTypeManager, nodeTypeToUnregister);
129 } catch (RepositoryException e) {
130 installContext.warn("Un-registration of NodeTypes generated exceptions. NodeType will not be Unregistered. Please check the NodeType dependency.");
131 log.warn("Not able to un-register the following node type {}. The original definition is kept.", nodeTypeToUnregister, e);
132 }
133 }
134
135 }
136
137
138
139
140 public abstract List<NodeTypeDefinition> getNodeTypesToRegister(NodeTypeManager nodeTypeManager) throws RepositoryException;
141
142
143
144
145 public abstract List<String> getNodeTypesToUnregister(NodeTypeManager nodeTypeManager) throws RepositoryException;
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 private void registerNodeTypes(NodeTypeManager nodeTypeManager, List<NodeTypeDefinition> nodeTypesToRegister, InstallContext installContext) throws RepositoryException {
162 NodeTypeRegistry registry = ((NodeTypeManagerImpl) nodeTypeManager).getNodeTypeRegistry();
163 NamePathResolver namePathResolver = ((NodeTypeManagerImpl) nodeTypeManager).getNamePathResolver();
164
165 for (NodeTypeDefinition nodeType : nodeTypesToRegister) {
166
167 String nodeTypeName = nodeType.getName();
168
169 if (nodeTypeManager.hasNodeType(nodeTypeName)) {
170
171
172 NodeTypeDefinition originalNodeType = nodeTypeManager.getNodeType(nodeTypeName);
173
174
175 Set<Name> dependentNodeTypeQNames = registry.getDependentNodeTypes(namePathResolver.getQName(nodeTypeName));
176
177
178 List<String> dependentNodeTypeNames = getNodeTypeNames(namePathResolver, dependentNodeTypeQNames);
179
180
181 List<NodeTypeDefinition> dependentNodeTypeDefinitions = getNodeTypeDefinitions(nodeTypeManager, dependentNodeTypeNames);
182
183
184 log.info("In order to register '{}', the following depending node types have to be unregistered first: {}.", nodeTypeName, dependentNodeTypeNames);
185
186 dependentNodeTypeNames.add(nodeTypeName);
187 unregisterNodeTypes(nodeTypeManager, dependentNodeTypeNames);
188
189
190
191 log.info("Registering {} and the following depending nodeTypes: {}", nodeTypeName, dependentNodeTypeQNames);
192 try {
193 registerNodeType(nodeTypeManager, nodeType);
194 } catch (RepositoryException e) {
195
196 registerNodeType(nodeTypeManager, originalNodeType);
197 String error = String.format("Registration (update of an existing NodeType) of the following NodeType generated exceptions '%s'. " +
198 "The original version of the definition is kept. Please check the NodeType dependency and the input list order.", nodeTypeName);
199 installContext.warn(error);
200 log.warn("Not able to register the following node type {}. The original definition is kept.", nodeTypeName, e);
201 }
202
203 for (NodeTypeDefinition nodeTypeDefinition : dependentNodeTypeDefinitions) {
204 try {
205 registerNodeType(nodeTypeManager, nodeTypeDefinition);
206 } catch (RepositoryException e) {
207 String error = String.format("Re-registration of the NodeType '%s' as a dependent nodeType of '%s' failed.", nodeTypeDefinition.getName(), nodeTypeName);
208 installContext.warn(error);
209 log.error(error, e);
210 }
211 }
212
213 } else {
214
215 nodeTypeManager.registerNodeType(nodeType, false);
216 log.info("Registering new '{}' node type.", nodeTypeName);
217 }
218 }
219 }
220
221
222
223
224 private void registerNodeType(NodeTypeManager nodeTypeManager, NodeTypeDefinition nodeTypeDefinition) throws RepositoryException {
225
226 final NodeTypeTemplate nodeTypeTemplate = nodeTypeManager.createNodeTypeTemplate(nodeTypeDefinition);
227 log.debug("Registering the following '{}' node type.", nodeTypeTemplate.getName());
228 nodeTypeManager.registerNodeType(nodeTypeTemplate, true);
229 }
230
231
232
233
234
235 private void unregisterNodeTypes(final NodeTypeManager nodeTypeManager, List<String> nodeTypeNames) throws RepositoryException {
236 Iterator<String> it = nodeTypeNames.iterator();
237 while(it.hasNext()) {
238 String nodeTypeName = it.next();
239 if (!nodeTypeManager.hasNodeType(nodeTypeName)) {
240 log.warn("Node type '{}' is not registered . No un-registration will be performed for this nodeType.", nodeTypeName);
241 it.remove();
242 }
243 }
244
245 NodeTypeRegistry.disableCheckForReferencesInContentException = true;
246 nodeTypeManager.unregisterNodeTypes(nodeTypeNames.toArray(new String[nodeTypeNames.size()]));
247 log.info("Unregistered the following NodeTypes '{}'.", nodeTypeNames);
248 NodeTypeRegistry.disableCheckForReferencesInContentException = false;
249 }
250
251 private List<NodeTypeDefinition> getNodeTypeDefinitions(NodeTypeManager nodeTypeManager, List<String> nodeTypeNames) throws RepositoryException {
252 List<NodeTypeDefinition> nodeTypeDefinitions = new ArrayList<>();
253 for (String ntn : nodeTypeNames) {
254 nodeTypeDefinitions.add(nodeTypeManager.getNodeType(ntn));
255 }
256 return nodeTypeDefinitions;
257 }
258
259
260
261
262 private List<String> getNodeTypeNames(NamePathResolver namePathResolver, Set<Name> nodeTypeQNames) throws NamespaceException {
263 List<String> names = new ArrayList<>();
264
265 for (Name qName : nodeTypeQNames) {
266 names.add(namePathResolver.getJCRName(qName));
267 }
268 return names;
269 }
270
271
272
273
274
275
276
277
278
279
280
281 @Deprecated
282 protected HashMap<String, NodeTypeDefinition> getDependentNodeTypes(NodeTypeDefinition nodeType, NodeTypeRegistry registry, NamePathResolver namePathResolver, NodeTypeManager nodeTypeManager) throws RepositoryException {
283
284 HashMap<String, NodeTypeDefinition> dependentNodeType = new LinkedHashMap<String, NodeTypeDefinition>();
285
286 Name qName = namePathResolver.getQName(nodeType.getName());
287 Set<Name> dependentNodesName = registry.getDependentNodeTypes(qName);
288
289 if (dependentNodesName != null && !dependentNodesName.isEmpty()) {
290 for (Name name : dependentNodesName) {
291 dependentNodeType.putAll(getDependentNodeTypes(nodeTypeManager.getNodeType(namePathResolver.getJCRName(name)), registry, namePathResolver, nodeTypeManager));
292 }
293 }
294
295 dependentNodeType.put(nodeType.getName(), nodeType);
296 return dependentNodeType;
297
298 }
299 }