You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2004/10/18 19:14:39 UTC
svn commit: rev 55021 - incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype
Author: stefan
Date: Mon Oct 18 10:14:38 2004
New Revision: 55021
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java
Log:
fixing bug http://nagoya.apache.org/jira/browse/JCR-8:
- Multiple PropertyDefs with same name not possible
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeType.java Mon Oct 18 10:14:38 2004
@@ -24,10 +24,7 @@
import javax.jcr.ValueFormatException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.TreeSet;
+import java.util.*;
/**
* An <code>EffectiveNodeType</code> represents one or more
@@ -49,7 +46,7 @@
// list of all either explicitly (through aggregation) or implicitly
// (through inheritance) included node types.
private final TreeSet allNodeTypes;
- // map of named item definitions
+ // map of named item definitions (maps name to list of definitions)
private final HashMap namedItemDefs;
// list of unnamed item definitions (i.e. residual definitions)
private final ArrayList unnamedItemDefs;
@@ -111,7 +108,27 @@
} else {
// named node definition
QName name = cnda[i].getName();
- ent.namedItemDefs.put(name, cnda[i]);
+ List defs = (List) ent.namedItemDefs.get(name);
+ if (defs == null) {
+ defs = new ArrayList();
+ ent.namedItemDefs.put(name, defs);
+ }
+ if (defs.size() > 0) {
+ /**
+ * there already exists at least one definition with that
+ * name; make sure none of them is auto-create
+ */
+ for (int j = 0; j < defs.size(); j++) {
+ ChildItemDef def = (ChildItemDef) defs.get(j);
+ if (cnda[i].isAutoCreate() || def.isAutoCreate()) {
+ // conflict
+ String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
+ log.error(msg);
+ throw new NodeTypeConflictException(msg);
+ }
+ }
+ }
+ defs.add(cnda[i]);
}
}
PropDef[] pda = ntd.getPropertyDefs();
@@ -122,7 +139,27 @@
} else {
// named property definition
QName name = pda[i].getName();
- ent.namedItemDefs.put(name, pda[i]);
+ List defs = (List) ent.namedItemDefs.get(name);
+ if (defs == null) {
+ defs = new ArrayList();
+ ent.namedItemDefs.put(name, defs);
+ }
+ if (defs.size() > 0) {
+ /**
+ * there already exists at least one definition with that
+ * name; make sure none of them is auto-create
+ */
+ for (int j = 0; j < defs.size(); j++) {
+ ChildItemDef def = (ChildItemDef) defs.get(j);
+ if (pda[i].isAutoCreate() || def.isAutoCreate()) {
+ // conflict
+ String msg = "There are more than one 'auto-create' item definitions for '" + name + "' in node type '" + ntName + "'";
+ log.error(msg);
+ throw new NodeTypeConflictException(msg);
+ }
+ }
+ }
+ defs.add(pda[i]);
}
}
@@ -159,13 +196,21 @@
public ChildItemDef[] getAllItemDefs() {
ArrayList defs = new ArrayList(namedItemDefs.size() + unnamedItemDefs.size());
- defs.addAll(namedItemDefs.values());
+ Iterator iter = namedItemDefs.values().iterator();
+ while (iter.hasNext()) {
+ defs.addAll((List) iter.next());
+ }
defs.addAll(unnamedItemDefs);
return (ChildItemDef[]) defs.toArray(new ChildItemDef[defs.size()]);
}
public ChildItemDef[] getNamedItemDefs() {
- return (ChildItemDef[]) namedItemDefs.values().toArray(new ChildItemDef[namedItemDefs.size()]);
+ ArrayList defs = new ArrayList(namedItemDefs.size());
+ Iterator iter = namedItemDefs.values().iterator();
+ while (iter.hasNext()) {
+ defs.addAll((List) iter.next());
+ }
+ return (ChildItemDef[]) defs.toArray(new ChildItemDef[defs.size()]);
}
public ChildItemDef[] getUnnamedItemDefs() {
@@ -176,8 +221,12 @@
return namedItemDefs.containsKey(name);
}
- public ChildItemDef getNamedItemDef(QName name) {
- return (ChildItemDef) namedItemDefs.get(name);
+ public ChildItemDef[] getNamedItemDefs(QName name) {
+ List defs = (List) namedItemDefs.get(name);
+ if (defs == null) {
+ return null;
+ }
+ return (ChildItemDef[]) defs.toArray(new ChildItemDef[defs.size()]);
}
public ChildNodeDef[] getAllNodeDefs() {
@@ -191,9 +240,13 @@
}
iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (def.definesNode()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (def.definesNode()) {
+ defs.add(def);
+ }
}
}
return (ChildNodeDef[]) defs.toArray(new ChildNodeDef[defs.size()]);
@@ -203,9 +256,13 @@
ArrayList defs = new ArrayList(namedItemDefs.size());
Iterator iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (def.definesNode()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (def.definesNode()) {
+ defs.add(def);
+ }
}
}
return (ChildNodeDef[]) defs.toArray(new ChildNodeDef[defs.size()]);
@@ -229,9 +286,13 @@
ArrayList defs = new ArrayList(namedItemDefs.size());
Iterator iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (def.definesNode() && def.isAutoCreate()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (def.definesNode() && def.isAutoCreate()) {
+ defs.add(def);
+ }
}
}
return (ChildNodeDef[]) defs.toArray(new ChildNodeDef[defs.size()]);
@@ -248,9 +309,13 @@
}
iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (!def.definesNode()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (!def.definesNode()) {
+ defs.add(def);
+ }
}
}
return (PropDef[]) defs.toArray(new PropDef[defs.size()]);
@@ -260,9 +325,13 @@
ArrayList defs = new ArrayList(namedItemDefs.size());
Iterator iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (!def.definesNode()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (!def.definesNode()) {
+ defs.add(def);
+ }
}
}
return (PropDef[]) defs.toArray(new PropDef[defs.size()]);
@@ -286,9 +355,13 @@
ArrayList defs = new ArrayList(namedItemDefs.size());
Iterator iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (!def.definesNode() && def.isAutoCreate()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (!def.definesNode() && def.isAutoCreate()) {
+ defs.add(def);
+ }
}
}
return (PropDef[]) defs.toArray(new PropDef[defs.size()]);
@@ -300,9 +373,13 @@
ArrayList defs = new ArrayList(namedItemDefs.size());
Iterator iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (!def.definesNode() && def.isMandatory()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (!def.definesNode() && def.isMandatory()) {
+ defs.add(def);
+ }
}
}
return (PropDef[]) defs.toArray(new PropDef[defs.size()]);
@@ -314,9 +391,13 @@
ArrayList defs = new ArrayList(namedItemDefs.size());
Iterator iter = namedItemDefs.values().iterator();
while (iter.hasNext()) {
- ChildItemDef def = (ChildItemDef) iter.next();
- if (def.definesNode() && def.isMandatory()) {
- defs.add(def);
+ List list = (List) iter.next();
+ Iterator iter1 = list.iterator();
+ while (iter1.hasNext()) {
+ ChildItemDef def = (ChildItemDef) iter1.next();
+ if (def.definesNode() && def.isMandatory()) {
+ defs.add(def);
+ }
}
}
return (ChildNodeDef[]) defs.toArray(new ChildNodeDef[defs.size()]);
@@ -404,47 +485,53 @@
*/
public ChildNodeDef getApplicableChildNodeDef(QName name, QName nodeTypeName)
throws NoSuchNodeTypeException, ConstraintViolationException {
- ChildItemDef def = (ChildItemDef) namedItemDefs.get(name);
- if (def == null) {
- // no item with that name defined;
- // try residual node definitions
- ChildNodeDef[] nda = getUnnamedNodeDefs();
- for (int i = 0; i < nda.length; i++) {
- ChildNodeDef nd = nda[i];
- if (nodeTypeName != null) {
- try {
- // check node type constraint
+ // try named node definitions first
+ ChildItemDef[] defs = getNamedItemDefs(name);
+ if (defs != null) {
+ for (int i = 0; i < defs.length; i++) {
+ ChildItemDef def = defs[i];
+ if (def.definesNode()) {
+ ChildNodeDef nd = (ChildNodeDef) def;
+ // node definition with that name exists
+ if (nodeTypeName != null) {
+ // check node type constraints
checkRequiredPrimaryType(nodeTypeName, nd.getRequiredPrimaryTypes());
- } catch (ConstraintViolationException e) {
- // ignore and try next
- continue;
- }
- return nd;
- } else {
- // since no node type has been specified for the new node,
- // it must be determined from the default node type;
- if (nd.getDefaultPrimaryType() != null) {
- // found residual node definition with default node type
return nd;
+ } else {
+ if (nd.getDefaultPrimaryType() == null) {
+ // no default node type defined
+ throw new ConstraintViolationException("node type for " + name + " can not be determined");
+ }
}
}
}
- } else {
- if (def.definesNode()) {
- ChildNodeDef nd = (ChildNodeDef) def;
- // node definition with that name exists
- if (nodeTypeName != null) {
- // check node type constraints
+ }
+
+ // no item with that name defined;
+ // try residual node definitions
+ ChildNodeDef[] nda = getUnnamedNodeDefs();
+ for (int i = 0; i < nda.length; i++) {
+ ChildNodeDef nd = nda[i];
+ if (nodeTypeName != null) {
+ try {
+ // check node type constraint
checkRequiredPrimaryType(nodeTypeName, nd.getRequiredPrimaryTypes());
+ } catch (ConstraintViolationException e) {
+ // ignore and try next
+ continue;
+ }
+ return nd;
+ } else {
+ // since no node type has been specified for the new node,
+ // it must be determined from the default node type;
+ if (nd.getDefaultPrimaryType() != null) {
+ // found residual node definition with default node type
return nd;
- } else {
- if (nd.getDefaultPrimaryType() == null) {
- // no default node type defined
- throw new ConstraintViolationException("node type for " + name + " can not be determined");
- }
}
}
}
+
+ // no applicable definition found
throw new ConstraintViolationException("no matching child node definition found for " + name);
}
@@ -461,42 +548,48 @@
*/
public PropDef getApplicablePropertyDef(QName name, int type, boolean multiValued)
throws ConstraintViolationException {
- ChildItemDef def = (ChildItemDef) namedItemDefs.get(name);
- if (def == null) {
- // no item with that name defined;
- // try residual property definitions
- PropDef[] pda = getUnnamedPropDefs();
- for (int i = 0; i < pda.length; i++) {
- PropDef pd = pda[i];
- int reqType = pd.getRequiredType();
- // match type
- if (reqType == PropertyType.UNDEFINED
- || type == PropertyType.UNDEFINED
- || reqType == type) {
- // match multiValued flag
- if (multiValued == pd.isMultiple()) {
- // found match
- return pd;
+ // try named property definitions first
+ ChildItemDef[] defs = getNamedItemDefs(name);
+ if (defs != null) {
+ for (int i = 0; i < defs.length; i++) {
+ ChildItemDef def = defs[i];
+ if (!def.definesNode()) {
+ PropDef pd = (PropDef) def;
+ int reqType = pd.getRequiredType();
+ // property definition with that name exists
+ // match type
+ if (reqType == PropertyType.UNDEFINED
+ || type == PropertyType.UNDEFINED
+ || reqType == type) {
+ // match multiValued flag
+ if (multiValued == pd.isMultiple()) {
+ // found match
+ return pd;
+ }
}
}
}
- } else {
- if (!def.definesNode()) {
- PropDef pd = (PropDef) def;
- int reqType = pd.getRequiredType();
- // property definition with that name exists
- // match type
- if (reqType == PropertyType.UNDEFINED
- || type == PropertyType.UNDEFINED
- || reqType == type) {
- // match multiValued flag
- if (multiValued == pd.isMultiple()) {
- // found match
- return pd;
- }
+ }
+
+ // no item with that name defined;
+ // try residual property definitions
+ PropDef[] pda = getUnnamedPropDefs();
+ for (int i = 0; i < pda.length; i++) {
+ PropDef pd = pda[i];
+ int reqType = pd.getRequiredType();
+ // match type
+ if (reqType == PropertyType.UNDEFINED
+ || type == PropertyType.UNDEFINED
+ || reqType == type) {
+ // match multiValued flag
+ if (multiValued == pd.isMultiple()) {
+ // found match
+ return pd;
}
}
}
+
+ // no applicable definition found
throw new ConstraintViolationException("no matching property definition found for " + name);
}
@@ -505,13 +598,19 @@
* @throws ConstraintViolationException
*/
public void checkRemoveItemConstraints(QName name) throws ConstraintViolationException {
- ChildItemDef def = getNamedItemDef(name);
- if (def != null) {
- if (def.isMandatory()) {
- throw new ConstraintViolationException("can't remove mandatory item");
- }
- if (def.isProtected()) {
- throw new ConstraintViolationException("can't remove protected item");
+ /**
+ * as there might be multiple definitions with the same name and we
+ * don't know which one is applicable, we check all of them
+ */
+ ChildItemDef[] defs = getNamedItemDefs(name);
+ if (defs != null) {
+ for (int i = 0; i < defs.length; i++) {
+ if (defs[i].isMandatory()) {
+ throw new ConstraintViolationException("can't remove mandatory item");
+ }
+ if (defs[i].isProtected()) {
+ throw new ConstraintViolationException("can't remove protected item");
+ }
}
}
}
@@ -600,14 +699,28 @@
continue;
}
QName name = def.getName();
- ChildItemDef existing = getNamedItemDef(name);
- if (existing != null) {
- // conflict
- String msg = "The item definition for '" + name + "' in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existing.getDeclaringNodeType() + "': name collision";
- log.error(msg);
- throw new NodeTypeConflictException(msg);
+ List existingDefs = (List) namedItemDefs.get(name);
+ if (existingDefs != null) {
+ if (existingDefs.size() > 0) {
+ /**
+ * there already exists at least one definition with that
+ * name; make sure none of them is auto-create
+ */
+ for (int j = 0; j < existingDefs.size(); j++) {
+ ChildItemDef existingDef = (ChildItemDef) existingDefs.get(j);
+ if (def.isAutoCreate() || existingDef.isAutoCreate()) {
+ // conflict
+ String msg = "The item definition for '" + name + "' in node type '" + def.getDeclaringNodeType() + "' conflicts with node type '" + existingDef.getDeclaringNodeType() + "': name collision with auto-create definition";
+ log.error(msg);
+ throw new NodeTypeConflictException(msg);
+ }
+ }
+ }
+ } else {
+ existingDefs = new ArrayList();
+ namedItemDefs.put(name, existingDefs);
}
- namedItemDefs.put(name, def);
+ existingDefs.add(def);
}
// residual item definitions
@@ -688,7 +801,12 @@
clone.mergedNodeTypes.addAll(mergedNodeTypes);
clone.inheritedNodeTypes.addAll(inheritedNodeTypes);
clone.allNodeTypes.addAll(allNodeTypes);
- clone.namedItemDefs.putAll(namedItemDefs);
+ Iterator iter = namedItemDefs.keySet().iterator();
+ while (iter.hasNext()) {
+ Object key = iter.next();
+ List list = (List) namedItemDefs.get(key);
+ clone.namedItemDefs.put(key, new ArrayList(list));
+ }
clone.unnamedItemDefs.addAll(unnamedItemDefs);
return clone;