diff --git a/magnolia-core/src/main/java/info/magnolia/setup/for5_0/AbstractNodeTypeRegistrationTask.java b/magnolia-core/src/main/java/info/magnolia/setup/for5_0/AbstractNodeTypeRegistrationTask.java index 67f2470..4347bf7 100644 --- a/magnolia-core/src/main/java/info/magnolia/setup/for5_0/AbstractNodeTypeRegistrationTask.java +++ b/magnolia-core/src/main/java/info/magnolia/setup/for5_0/AbstractNodeTypeRegistrationTask.java @@ -36,19 +36,6 @@ package info.magnolia.setup.for5_0; import info.magnolia.module.InstallContext; import info.magnolia.module.delta.AbstractRepositoryTask; import info.magnolia.module.delta.TaskExecutionException; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.jcr.RepositoryException; -import javax.jcr.nodetype.NodeTypeDefinition; -import javax.jcr.nodetype.NodeTypeManager; -import javax.jcr.nodetype.NodeTypeTemplate; - import org.apache.commons.lang3.StringUtils; import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; @@ -57,6 +44,15 @@ import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeTypeDefinition; +import javax.jcr.nodetype.NodeTypeManager; +import javax.jcr.nodetype.NodeTypeTemplate; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + /** * Task allowing to register or unregister nodeTypes.
*
@@ -142,35 +138,35 @@ public abstract class AbstractNodeTypeRegistrationTask extends AbstractRepositor // Get the original NodeType definition. Useful in case of dependency issue (the original NodeType is re-registered in case of exception). NodeTypeDefinition originalNodeType = nodeTypeManager.getNodeType(nodeType.getName()); // Get the list of NodeType that reference the current nodeType - HashMap nodeTypeToUnregister = getDependentNodeTypes(nodeType, registry, namePathResolver, nodeTypeManager); + List nodeTypeToUnregister = new ArrayList<>(); + findDependentNodeTypes(nodeTypeToUnregister, nodeType, registry, namePathResolver, nodeTypeManager); + final String[] nodeTypesToUnregisterNames = nodeTypeToUnregister.stream().map(NodeTypeDefinition::getName).toArray(String[]::new); + // UNREGISTRATION NodeTypeRegistry.disableCheckForReferencesInContentException = true; - log.info("In order to register '{}', the following depending node types have to be unregistered first: {}.", nodeType.getName(), nodeTypeToUnregister.keySet()); - final String[] nodeTypesToUnregisterNames = nodeTypeToUnregister.keySet().toArray(new String[nodeTypeToUnregister.keySet().size()]); + log.info("In order to register '{}', the following depending node types have to be unregistered first: {}.", nodeType.getName(), nodeTypesToUnregisterNames); nodeTypeManager.unregisterNodeTypes(nodeTypesToUnregisterNames); NodeTypeRegistry.disableCheckForReferencesInContentException = false; // RE-REGISTRATION - final Map templates = new LinkedHashMap(); - try { - for (NodeTypeDefinition nodeTypeDefinition : nodeTypeToUnregister.values()) { - // "transforming" each definition into a template, so that nodeTypeManager.registerNodeTypes doesn't barf unnecessary exceptions. - templates.put(nodeTypeDefinition.getName(), nodeTypeManager.createNodeTypeTemplate(nodeTypeDefinition)); + log.info("Registering {} and the following dependending nodetypes: {}", nodeType.getName(), nodeTypesToUnregisterNames); + for (NodeTypeDefinition nodeTypeDefinition : nodeTypeToUnregister) { + try { + // "transforming" each definition into a template, so that nodeTypeManager.registerNodeType doesn't barf unnecessary exceptions. + final NodeTypeTemplate nodeTypeTemplate = nodeTypeManager.createNodeTypeTemplate(nodeTypeDefinition); + + log.debug("Registering the following '{}' node type.", nodeTypeTemplate.getName()); + nodeTypeManager.registerNodeType(nodeTypeTemplate, true); + + } catch (Exception e) { + // Register the previous version of the NodeType + NodeTypeTemplate originalTemplate = nodeTypeManager.createNodeTypeTemplate(originalNodeType); + nodeTypeManager.registerNodeType(originalTemplate, false); + 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"); + log.warn("Not able to register the following node type {}. The original definition is kept.", nodeType.getName(), e); } - - log.info("Registering the following '{}' node type. Reregistered the following dependency: {}", nodeType.getName(), nodeTypeToUnregister.keySet()); - nodeTypeManager.registerNodeTypes(templates.values().toArray(new NodeTypeDefinition[nodeTypeToUnregister.values().size()]), true); - - } catch (Exception e) { - // Register the previous version of the NodeType - NodeTypeTemplate originalTemplate = nodeTypeManager.createNodeTypeTemplate(originalNodeType); - nodeTypeManager.registerNodeType(originalTemplate, false); - // Register the dependent child - templates.remove(nodeType.getName()); - nodeTypeManager.registerNodeTypes(templates.values().toArray(new NodeTypeDefinition[templates.values().size()]), true); - 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"); - log.warn("Not able to register the following node type {}. The original definition is kept.", nodeType.getName(), e); } + } else { // NodeType is new, Create (register) nodeTypeManager.registerNodeType(nodeType, false); @@ -180,26 +176,25 @@ public abstract class AbstractNodeTypeRegistrationTask extends AbstractRepositor } /** - * Create a Map containing all child NodeType of.
- * - key = NodeType name.
+ * Create a List containing all child NodeType of.
* - value = {@link NodeTypeDefinition}. */ - protected HashMap getDependentNodeTypes(NodeTypeDefinition nodeType, NodeTypeRegistry registry, NamePathResolver namePathResolver, NodeTypeManager nodeTypeManager) throws RepositoryException { - - HashMap dependentNodeType = new LinkedHashMap(); + protected void findDependentNodeTypes(List dependentNodeTypes, NodeTypeDefinition nodeType, NodeTypeRegistry registry, NamePathResolver namePathResolver, NodeTypeManager nodeTypeManager) throws RepositoryException { + dependentNodeTypes.add(nodeType); // Get the Name in order to get the Dependent Node type Name qName = namePathResolver.getQName(nodeType.getName()); Set dependentNodesName = registry.getDependentNodeTypes(qName); // for every dependent node type, call recursively in order to get all the dependency tree. if (dependentNodesName != null && !dependentNodesName.isEmpty()) { for (Name name : dependentNodesName) { - dependentNodeType.putAll(getDependentNodeTypes(nodeTypeManager.getNodeType(namePathResolver.getJCRName(name)), registry, namePathResolver, nodeTypeManager)); + NodeTypeDefinition dependentNodeType = nodeTypeManager.getNodeType(namePathResolver.getJCRName(name)); + if (!dependentNodeTypes.contains(dependentNodeType)) { + findDependentNodeTypes(dependentNodeTypes, dependentNodeType, registry, namePathResolver, nodeTypeManager); + } else { + log.debug("Nodetype already in list, not recursing for " + name); + } } } - - dependentNodeType.put(nodeType.getName(), nodeType); - return dependentNodeType; - } /** @@ -235,3 +230,4 @@ public abstract class AbstractNodeTypeRegistrationTask extends AbstractRepositor return filteredNodeTypes; } } +