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.HashMap;
41 import java.util.LinkedList;
42 import java.util.List;
43 import java.util.Set;
44
45 import javax.jcr.RepositoryException;
46 import javax.jcr.nodetype.NodeTypeDefinition;
47 import javax.jcr.nodetype.NodeTypeManager;
48
49 import org.apache.commons.lang.StringUtils;
50 import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
51 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
52 import org.apache.jackrabbit.spi.Name;
53 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public abstract class AbstractNodeTypeRegistrationTask extends AbstractRepositoryTask {
77
78 private final Logger log = LoggerFactory.getLogger(AbstractNodeTypeRegistrationTask.class);
79
80 private String workspaceName;
81
82 public AbstractNodeTypeRegistrationTask(String name, String description, String workspaceName) {
83 super(name, description);
84 this.workspaceName = workspaceName;
85 }
86
87 @Override
88 protected void doExecute(InstallContext installContext) throws RepositoryException, TaskExecutionException {
89 if (StringUtils.isBlank(workspaceName)) {
90 log.warn("No workspace defined. This task will resume");
91 return;
92 }
93
94 NodeTypeManager nodeTypeManager = installContext.getJCRSession(workspaceName).getWorkspace().getNodeTypeManager();
95
96
97 List<NodeTypeDefinition> nodeTypeToRegister = getNodeTypesToRegister(nodeTypeManager);
98 if (nodeTypeToRegister == null || nodeTypeToRegister.isEmpty()) {
99 log.info("No NodeType defined to register for the following workspace '{}'", workspaceName);
100 } else {
101 registerNodeTypes(nodeTypeManager, nodeTypeToRegister, installContext);
102 }
103
104 List<String> nodeTypeToUnregister = getNodeTypesToUnregister(nodeTypeManager);
105 if (nodeTypeToUnregister == null || nodeTypeToUnregister.isEmpty()) {
106 log.info("No NodeType defined to unregister for the following workspace '{}'", workspaceName);
107 } else {
108 unregisterNodeTypes(nodeTypeManager, nodeTypeToUnregister, installContext);
109 }
110
111 }
112
113
114
115
116 public abstract List<NodeTypeDefinition> getNodeTypesToRegister(NodeTypeManager nodeTypeManager) throws RepositoryException;
117
118
119
120
121 public abstract List<String> getNodeTypesToUnregister(NodeTypeManager nodeTypeManager) throws RepositoryException;
122
123
124
125
126
127
128
129
130
131
132
133 private void registerNodeTypes(NodeTypeManager nodeTypeManager, List<NodeTypeDefinition> nodeTypesToRegister, InstallContext installContext) throws RepositoryException {
134 NodeTypeRegistry registry = ((NodeTypeManagerImpl) nodeTypeManager).getNodeTypeRegistry();
135 NamePathResolver namePathResolver = ((NodeTypeManagerImpl) nodeTypeManager).getNamePathResolver();
136
137 for (NodeTypeDefinition nodeType : nodeTypesToRegister) {
138
139 if (nodeTypeManager.hasNodeType(nodeType.getName())) {
140
141 NodeTypeDefinition originalNodeType = nodeTypeManager.getNodeType(nodeType.getName());
142
143 HashMap<String, NodeTypeDefinition> nodeTypeToUnregister = getDependentNodeTypes(nodeType, registry, namePathResolver, nodeTypeManager);
144
145 NodeTypeRegistry.disableCheckForReferencesInContentException = true;
146 nodeTypeManager.unregisterNodeTypes(nodeTypeToUnregister.keySet().toArray(new String[nodeTypeToUnregister.keySet().size()]));
147 log.info("In order to register '" + nodeType.getName() + "', the following depending node types had to be unregistered first", nodeTypeToUnregister.keySet().toArray());
148 NodeTypeRegistry.disableCheckForReferencesInContentException = false;
149
150 try {
151 nodeTypeManager.registerNodeTypes(nodeTypeToUnregister.values().toArray(new NodeTypeDefinition[nodeTypeToUnregister.values().size()]), true);
152 log.info("Registering the following '" + nodeType.getName() + "' node type. Reregister the following dependency", nodeTypeToUnregister.keySet().toArray());
153 } catch (RepositoryException re) {
154
155 nodeTypeManager.registerNodeType(originalNodeType, false);
156
157 nodeTypeToUnregister.remove(nodeType.getName());
158 nodeTypeManager.registerNodeTypes(nodeTypeToUnregister.values().toArray(new NodeTypeDefinition[nodeTypeToUnregister.values().size()]), true);
159 installContext.warn("Registration (update of an existing NodeType) of the following NodeType generated exceptions '" + nodeType.getName() + "'.The original version of the definition is kept. Please check the NodeType dependency and the input list order");
160 log.warn("Not able to register the following node type {}. The original definition is kept.", nodeType.getName(), re);
161 }
162 } else {
163
164 nodeTypeManager.registerNodeType(nodeType, false);
165 log.info("Registering new '{}' node type.", nodeType.getName());
166 }
167 }
168 }
169
170
171
172
173
174
175 protected HashMap<String, NodeTypeDefinition> getDependentNodeTypes(NodeTypeDefinition nodeType, NodeTypeRegistry registry, NamePathResolver namePathResolver, NodeTypeManager nodeTypeManager) throws RepositoryException {
176
177 HashMap<String, NodeTypeDefinition> dependentNodeType = new HashMap<String, NodeTypeDefinition>();
178
179 Name qName = namePathResolver.getQName(nodeType.getName());
180 Set<Name> dependentNodesName = registry.getDependentNodeTypes(qName);
181
182 if (dependentNodesName != null && !dependentNodesName.isEmpty()) {
183 for (Name name : dependentNodesName) {
184 dependentNodeType.putAll(getDependentNodeTypes(nodeTypeManager.getNodeType(namePathResolver.getJCRName(name)), registry, namePathResolver, nodeTypeManager));
185 }
186 }
187
188 dependentNodeType.put(nodeType.getName(), nodeType);
189 return dependentNodeType;
190
191 }
192
193
194
195
196 private void unregisterNodeTypes(NodeTypeManager nodeTypeManager, List<String> nodeTypesToUnregister, InstallContext installContext) throws RepositoryException {
197 LinkedList<String> filteredNodeTypeToUnregister = getFilteredNodesToUnregister(nodeTypeManager, nodeTypesToUnregister);
198 try {
199 NodeTypeRegistry.disableCheckForReferencesInContentException = true;
200 nodeTypeManager.unregisterNodeTypes(filteredNodeTypeToUnregister.toArray(new String[filteredNodeTypeToUnregister.size()]));
201 log.info("Unregistered the following NodeTypes '{}'", filteredNodeTypeToUnregister.toArray());
202 NodeTypeRegistry.disableCheckForReferencesInContentException = false;
203 } catch (RepositoryException re) {
204
205 installContext.warn("Unregistration of NodeTypes generated exceptions. NodeType will not be Unregistered. Please check the NodeType dependency");
206 log.warn("Not able to unregister the following node type {}. The original definition is kept.", filteredNodeTypeToUnregister.toArray(), re);
207 }
208 }
209
210
211
212
213
214 private LinkedList<String> getFilteredNodesToUnregister(NodeTypeManager nodeTypeManager, List<String> nodeTypeToUnregister) throws RepositoryException {
215 LinkedList<String> filteredNodeTypes = new LinkedList<String>();
216 for (String nodeTypeName : nodeTypeToUnregister) {
217 if (nodeTypeManager.hasNodeType(nodeTypeName)) {
218 filteredNodeTypes.add(nodeTypeName);
219 } else {
220 log.warn("Node type '{}' is not registered . No unregistration will be performed", nodeTypeName);
221 }
222 }
223 return filteredNodeTypes;
224 }
225 }