You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by un...@apache.org on 2014/12/10 14:45:36 UTC
svn commit: r1644408 - in
/jackrabbit/branches/2.8/jackrabbit-spi-commons/src:
main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java
test/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiffTest.java
Author: unico
Date: Wed Dec 10 13:45:36 2014
New Revision: 1644408
URL: http://svn.apache.org/r1644408
Log:
JCR-3840 take same-name child type definitions into account when reregistering node types
Modified:
jackrabbit/branches/2.8/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java
jackrabbit/branches/2.8/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiffTest.java
Modified: jackrabbit/branches/2.8/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.8/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java?rev=1644408&r1=1644407&r2=1644408&view=diff
==============================================================================
--- jackrabbit/branches/2.8/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java (original)
+++ jackrabbit/branches/2.8/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java Wed Dec 10 13:45:36 2014
@@ -27,6 +27,9 @@ import org.apache.jackrabbit.spi.commons
import javax.jcr.PropertyType;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -280,50 +283,43 @@ public class NodeTypeDefDiff {
*/
private int buildChildNodeDefDiffs() {
int maxType = NONE;
- QNodeDefinition[] cnda1 = oldDef.getChildNodeDefs();
- Map<QNodeDefinitionId, QNodeDefinition> defs1 = new HashMap<QNodeDefinitionId, QNodeDefinition>();
- for (QNodeDefinition def1 : cnda1) {
- defs1.put(new QNodeDefinitionId(def1), def1);
- }
+ final Map<QNodeDefinitionId, List<QNodeDefinition>> oldDefs = collectChildNodeDefs(oldDef.getChildNodeDefs());
+ final Map<QNodeDefinitionId, List<QNodeDefinition>> newDefs = collectChildNodeDefs(newDef.getChildNodeDefs());
- QNodeDefinition[] cnda2 = newDef.getChildNodeDefs();
- Map<QNodeDefinitionId, QNodeDefinition> defs2 = new HashMap<QNodeDefinitionId, QNodeDefinition>();
- for (QNodeDefinition def2 : cnda2) {
- defs2.put(new QNodeDefinitionId(def2), def2);
+ for (QNodeDefinitionId defId : oldDefs.keySet()) {
+ final ChildNodeDefDiffs childNodeDefDiffs = new ChildNodeDefDiffs(oldDefs.get(defId), newDefs.get(defId));
+ this.childNodeDefDiffs.addAll(childNodeDefDiffs.getChildNodeDefDiffs());
+ newDefs.remove(defId);
}
- /**
- * walk through defs1 and process all entries found in
- * both defs1 & defs2 and those found only in defs1
- */
- for (Map.Entry<QNodeDefinitionId, QNodeDefinition> entry1 : defs1.entrySet()) {
- QNodeDefinitionId id = entry1.getKey();
- QNodeDefinition def1 = entry1.getValue();
- QNodeDefinition def2 = defs2.get(id);
- ChildNodeDefDiff diff = new ChildNodeDefDiff(def1, def2);
- if (diff.getType() > maxType) {
- maxType = diff.getType();
- }
- childNodeDefDiffs.add(diff);
- defs2.remove(id);
+ for (QNodeDefinitionId defId : newDefs.keySet()) {
+ final ChildNodeDefDiffs childNodeDefDiffs = new ChildNodeDefDiffs(null, newDefs.get(defId));
+ this.childNodeDefDiffs.addAll(childNodeDefDiffs.getChildNodeDefDiffs());
}
- /**
- * defs2 by now only contains entries found in defs2 only;
- * walk through defs2 and process all remaining entries
- */
- for (Map.Entry<QNodeDefinitionId, QNodeDefinition> entry2 : defs2.entrySet()) {
- QNodeDefinition def2 = entry2.getValue();
- ChildNodeDefDiff diff = new ChildNodeDefDiff(null, def2);
+ for (ChildNodeDefDiff diff : childNodeDefDiffs) {
if (diff.getType() > maxType) {
maxType = diff.getType();
}
- childNodeDefDiffs.add(diff);
}
return maxType;
}
+ private Map<QNodeDefinitionId, List<QNodeDefinition>> collectChildNodeDefs(final QNodeDefinition[] cnda1) {
+ Map<QNodeDefinitionId, List<QNodeDefinition>> defs1 = new HashMap<QNodeDefinitionId, List<QNodeDefinition>>();
+ for (QNodeDefinition def1 : cnda1) {
+ final QNodeDefinitionId def1Id = new QNodeDefinitionId(def1);
+ List<QNodeDefinition> list = defs1.get(def1Id);
+ if (list == null) {
+ list = new ArrayList<QNodeDefinition>();
+ defs1.put(def1Id, list);
+ }
+ list.add(def1);
+ }
+ return defs1;
+ }
+
@Override
public String toString() {
String result = getClass().getName() + "[\n\tnodeTypeName="
@@ -699,4 +695,67 @@ public class NodeTypeDefDiff {
return h;
}
}
+
+ private class ChildNodeDefDiffs {
+
+ private final List<QNodeDefinition> defs1;
+ private final List<QNodeDefinition> defs2;
+
+ private ChildNodeDefDiffs(final List<QNodeDefinition> defs1, final List<QNodeDefinition> defs2) {
+ this.defs1 = defs1 != null ? defs1 : Collections.<QNodeDefinition>emptyList();
+ this.defs2 = defs2 != null ? defs2 : Collections.<QNodeDefinition>emptyList();
+ }
+
+ private Collection<ChildNodeDefDiff> getChildNodeDefDiffs() {
+ // gather all possible combinations of diffs
+ final List<ChildNodeDefDiff> diffs = new ArrayList<ChildNodeDefDiff>();
+ for (QNodeDefinition def1 : defs1) {
+ for (QNodeDefinition def2 : defs2) {
+ diffs.add(new ChildNodeDefDiff(def1, def2));
+ }
+ }
+ if (defs2.size() < defs1.size()) {
+ for (QNodeDefinition def1 : defs1) {
+ diffs.add(new ChildNodeDefDiff(def1, null));
+ }
+ }
+ if (defs1.size() < defs2.size()) {
+ for (QNodeDefinition def2 : defs2) {
+ diffs.add(new ChildNodeDefDiff(null, def2));
+ }
+ }
+ // sort them according to decreasing compatibility
+ Collections.sort(diffs, new Comparator<ChildNodeDefDiff>() {
+ @Override
+ public int compare(final ChildNodeDefDiff o1, final ChildNodeDefDiff o2) {
+ return o1.getType() - o2.getType();
+ }
+ });
+ // select the most compatible ones
+ final int size = defs1.size() > defs2.size() ? defs1.size() : defs2.size();
+ final List<ChildNodeDefDiff> results = new ArrayList<ChildNodeDefDiff>();
+ for (ChildNodeDefDiff diff : diffs) {
+ if (!alreadyMatched(results, diff.getNewDef(), diff.getOldDef())) {
+ results.add(diff);
+ }
+ if (results.size() == size) {
+ break;
+ }
+ }
+ return results;
+ }
+
+ private boolean alreadyMatched(final List<ChildNodeDefDiff> result, final QNodeDefinition newDef, final QNodeDefinition oldDef) {
+ boolean containsNewDef = false, containsOldDef = false;
+ for (ChildNodeDefDiff d : result) {
+ if (d.getNewDef() != null && d.getNewDef().equals(newDef)) {
+ containsNewDef = true;
+ }
+ if (d.getOldDef() != null && d.getOldDef().equals(oldDef)) {
+ containsOldDef = true;
+ }
+ }
+ return containsNewDef || containsOldDef;
+ }
+ }
}
Modified: jackrabbit/branches/2.8/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiffTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.8/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiffTest.java?rev=1644408&r1=1644407&r2=1644408&view=diff
==============================================================================
--- jackrabbit/branches/2.8/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiffTest.java (original)
+++ jackrabbit/branches/2.8/jackrabbit-spi-commons/src/test/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiffTest.java Wed Dec 10 13:45:36 2014
@@ -70,7 +70,6 @@ public class NodeTypeDefDiffTest extends
newDef.setPropertyDefs(new QPropertyDefinition[]{newPropDef.build()});
QNodeDefinitionBuilder newChildDef = new QNodeDefinitionBuilder();
- newChildDef.setRequiredPrimaryTypes(new Name[]{ NameConstants.NT_BASE, NODE_TYPE1, NameConstants.NT_FOLDER });
newChildDef.setRequiredPrimaryTypes(new Name[]{ NODE_TYPE1, NameConstants.NT_BASE });
newChildDef.setName(CHILD_NAME);
newChildDef.setDeclaringNodeType(oldDef.getName());
@@ -87,4 +86,54 @@ public class NodeTypeDefDiffTest extends
nodeTypeDefDiff = NodeTypeDefDiff.create(newDef.build(), oldDef.build());
assertTrue(nodeTypeDefDiff.isMajor());
}
+
+ public void testChangedSameNameChildNodeDefinition() throws Exception {
+ // old node type definition
+ QNodeTypeDefinitionBuilder oldDef = new QNodeTypeDefinitionBuilder();
+ oldDef.setName(NODE_TYPE1);
+ oldDef.setSupertypes(new Name[] { NameConstants.NT_BASE });
+
+ QNodeDefinitionBuilder oldChildDef1 = new QNodeDefinitionBuilder();
+ oldChildDef1.setRequiredPrimaryTypes(new Name[]{ NameConstants.NT_FOLDER });
+ oldChildDef1.setName(CHILD_NAME);
+ oldChildDef1.setDeclaringNodeType(oldDef.getName());
+
+ QNodeDefinitionBuilder oldChildDef2 = new QNodeDefinitionBuilder();
+ oldChildDef2.setRequiredPrimaryTypes(new Name[]{ NameConstants.NT_FILE });
+ oldChildDef2.setName(CHILD_NAME);
+ oldChildDef2.setDeclaringNodeType(oldDef.getName());
+
+ oldDef.setChildNodeDefs(new QNodeDefinition[] { oldChildDef1.build(), oldChildDef2.build() });
+
+ // new node type definition
+ QNodeTypeDefinitionBuilder newDef = new QNodeTypeDefinitionBuilder();
+ newDef.setName(NODE_TYPE1);
+ newDef.setSupertypes(new Name[] { NameConstants.NT_BASE });
+
+ QNodeDefinitionBuilder newChildDef1 = new QNodeDefinitionBuilder();
+ newChildDef1.setRequiredPrimaryTypes(new Name[]{ NameConstants.NT_FOLDER });
+ newChildDef1.setName(CHILD_NAME);
+ newChildDef1.setDeclaringNodeType(oldDef.getName());
+
+ QNodeDefinitionBuilder newChildDef2 = new QNodeDefinitionBuilder();
+ newChildDef2.setRequiredPrimaryTypes(new Name[]{ NameConstants.NT_FILE });
+ newChildDef2.setName(CHILD_NAME);
+ newChildDef2.setDeclaringNodeType(oldDef.getName());
+
+ QNodeDefinitionBuilder newChildDef3 = new QNodeDefinitionBuilder();
+ newChildDef3.setRequiredPrimaryTypes(new Name[]{ NameConstants.NT_RESOURCE });
+ newChildDef3.setName(CHILD_NAME);
+ newChildDef3.setDeclaringNodeType(oldDef.getName());
+
+ newDef.setChildNodeDefs(new QNodeDefinition[] { newChildDef1.build(), newChildDef2.build(), newChildDef3.build() });
+
+ // from old to new is trivial
+ NodeTypeDefDiff nodeTypeDefDiff = NodeTypeDefDiff.create(oldDef.build(), newDef.build());
+ assertTrue(nodeTypeDefDiff.isTrivial());
+
+ // .. but the reverse is not
+ nodeTypeDefDiff = NodeTypeDefDiff.create(newDef.build(), oldDef.build());
+ assertTrue(nodeTypeDefDiff.isMajor());
+
+ }
}
\ No newline at end of file