You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by st...@apache.org on 2004/09/09 17:45:46 UTC
cvs commit: jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype NodeDefId.java
stefan 2004/09/09 08:45:46
Modified: proposals/jcrri/src/org/apache/slide/jcr/core ItemImpl.java
NodeImpl.java PropertyImpl.java RepositoryImpl.java
SessionImpl.java
proposals/jcrri/src/org/apache/slide/jcr/core/nodetype
NodeDefId.java
Log:
jcrri: fixing bug when adding/removing mixin's
Revision Changes Path
1.24 +3 -2 jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemImpl.java
Index: ItemImpl.java
===================================================================
RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ItemImpl.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- ItemImpl.java 6 Sep 2004 17:10:43 -0000 1.23
+++ ItemImpl.java 9 Sep 2004 15:45:45 -0000 1.24
@@ -149,7 +149,7 @@
case STATUS_DESTROYED:
case STATUS_INVALIDATED:
- throw new InvalidItemStateException("the item " + safeGetJCRPath() + " (" + id + ") " + " does not exist anymore.");
+ throw new InvalidItemStateException(id + ": the item does not exist anymore");
}
}
@@ -641,6 +641,7 @@
* @throws RepositoryException
*/
private void initVersionHistories(Iterator iter) throws RepositoryException {
+ // todo centralize version history creation code (currently in NodeImpl.addMixin & ItemImpl.initVersionHistories
// walk through list of transient items and
// search for new versionable nodes
while (iter.hasNext()) {
1.38 +108 -43 jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeImpl.java
Index: NodeImpl.java
===================================================================
RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeImpl.java,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- NodeImpl.java 6 Sep 2004 17:10:43 -0000 1.37
+++ NodeImpl.java 9 Sep 2004 15:45:45 -0000 1.38
@@ -1,6 +1,6 @@
/*
* Copyright 2002-2004 The Apache Software Foundation.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -96,10 +96,15 @@
return state;
}
- protected InternalValue[] computeSystemGeneratedPropertyValues(QName name, PropertyDefImpl def) {
+ protected InternalValue[] computeSystemGeneratedPropertyValues(QName name,
+ PropertyDefImpl def)
+ throws RepositoryException {
InternalValue[] genValues = null;
- // @todo need a more flexible generic way (callback?) of applying system generated values
+ /**
+ * todo: need to come up with some callback mechanism for applying system generated values
+ * (e.g. using a NodeTypeInstanceHandler interface)
+ */
NodeState thisState = (NodeState) state;
@@ -111,6 +116,25 @@
// jcr:uuid property
genValues = new InternalValue[]{InternalValue.create(((NodeState) state).getUUID())};
}
+/*
+ todo centralize version history creation code (currently in NodeImpl.addMixin & ItemImpl.initVersionHistories
+ } else if (nt.getQName().equals(NodeTypeRegistry.MIX_VERSIONABLE)) {
+ // mix:versionable node type
+ VersionHistory hist = rep.getVersionManager().getOrCreateVersionHistory(this);
+ if (name.equals(VersionImpl.PROPNAME_VERSION_HISTORY)) {
+ // jcr:versionHistory property
+ genValues = new InternalValue[]{InternalValue.create(new UUID(hist.getUUID()))};
+ } else if (name.equals(VersionImpl.PROPNAME_BASE_VERSION)) {
+ // jcr:baseVersion property
+ genValues = new InternalValue[]{InternalValue.create(new UUID(hist.getRootVersion().getUUID()))};
+ } else if (name.equals(VersionImpl.PROPNAME_IS_CHECKED_OUT)) {
+ // jcr:isCheckedOut property
+ genValues = new InternalValue[]{InternalValue.create(true)};
+ } else if (name.equals(VersionImpl.PROPNAME_PREDECESSORS)) {
+ // jcr:predecessors property
+ genValues = new InternalValue[]{InternalValue.create(new UUID(hist.getRootVersion().getUUID()))};
+ }
+*/
} else if (nt.getQName().equals(NodeTypeRegistry.NT_HIERARCHYNODE)) {
// nt:hierarchyNode node type
if (name.equals(PROPNAME_CREATED)) {
@@ -512,6 +536,13 @@
PropertyDefImpl def = getApplicablePropertyDef(PROPNAME_MIXINTYPES, PropertyType.NAME);
prop = createChildProperty(PROPNAME_MIXINTYPES, PropertyType.NAME, def);
}
+
+ if (mixinNames.isEmpty()) {
+ // purge empty jcr:mixinTypes property
+ removeChildProperty(PROPNAME_MIXINTYPES);
+ return;
+ }
+
// call internalSetValue for setting the jcr:mixinTypes property
// to avoid checking of the 'protected' flag
InternalValue[] vals = new InternalValue[mixinNames.size()];
@@ -724,7 +755,7 @@
* Returns the child node of <code>this</code> node with the specified
* <code>name</code>.
*
- * @param name The qualified name of the child node to retrieve.
+ * @param name The qualified name of the child node to retrieve.
* @param index The index of the child node to retrieve (in the case of same-name siblings).
* @return The child node with the specified <code>name</code>.
* @throws ItemNotFoundException If no child node exists with the
@@ -783,7 +814,7 @@
* Returns <code>true</code> if the child node exists and <code>false</code>
* otherwise.
*
- * @param name The qualified name of the child node.
+ * @param name The qualified name of the child node.
* @param index The index of the child node (in the case of same-name siblings).
* @return <code>true</code> if the child node exists; <code>false</code> otherwise.
* @throws RepositoryException If an unspecified error occurs.
@@ -1644,16 +1675,22 @@
throw new RepositoryException(mixinName + ": already contained in primary node type");
}
- // build effective node type of mixins & primary type in order to detect conflicts
+ // build effective node type of mixin's & primary type in order to detect conflicts
NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
- // existing mixin's
- HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
- // new mixin
- set.add(ntName);
- // primary type
- set.add(nodeType.getQName());
+ EffectiveNodeType entExisting;
try {
- // try to build effective node type (will throw in case of conflicts)
+ // existing mixin's
+ HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
+ // primary type
+ set.add(nodeType.getQName());
+ // build effective node type representing primary type including existing mixin's
+ entExisting = ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+ if (entExisting.includesNodeType(ntName)) {
+ throw new RepositoryException(mixinName + ": already contained in mixin types");
+ }
+ // add new mixin
+ set.add(ntName);
+ // try to build new effective node type (will throw in case of conflicts)
ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
} catch (NodeTypeConflictException ntce) {
throw new ConstraintViolationException(ntce.getMessage());
@@ -1673,18 +1710,28 @@
PropertyDef[] pda = mixin.getAutoCreatePropertyDefs();
for (int i = 0; i < pda.length; i++) {
PropertyDefImpl pd = (PropertyDefImpl) pda[i];
- createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
+ // make sure that the property is not already defined by primary type
+ // or existing mixin's
+ NodeTypeImpl declaringNT = (NodeTypeImpl) pd.getDeclaringNodeType();
+ if (!entExisting.includesNodeType(declaringNT.getQName())) {
+ createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
+ }
}
// recursively add 'auto-create' child nodes defined in mixin type
NodeDef[] nda = mixin.getAutoCreateNodeDefs();
for (int i = 0; i < nda.length; i++) {
NodeDefImpl nd = (NodeDefImpl) nda[i];
- createChildNode(nd.getQName(), nd, (NodeTypeImpl) nd.getDefaultPrimaryType(), null);
+ // make sure that the child node is not already defined by primary type
+ // or existing mixin's
+ NodeTypeImpl declaringNT = (NodeTypeImpl) nd.getDeclaringNodeType();
+ if (!entExisting.includesNodeType(declaringNT.getQName())) {
+ createChildNode(nd.getQName(), nd, (NodeTypeImpl) nd.getDefaultPrimaryType(), null);
+ }
}
- // check for special node-types
- // todo: invent some callback mechanism
+ // check for special node types
+ // todo centralize version history creation code (currently in NodeImpl.addMixin & ItemImpl.initVersionHistories
if (ntName.equals(NodeTypeRegistry.MIX_VERSIONABLE)) {
VersionHistory hist = rep.getVersionManager().createVersionHistory(this);
internalSetProperty(VersionImpl.PROPNAME_VERSION_HISTORY, InternalValue.create(new UUID(hist.getUUID())));
@@ -1737,7 +1784,7 @@
* special semantics:
* it can only be removed if there no more references to this node
*/
- PropertyIterator iter = getReferences();
+ PropertyIterator iter = getReferences();
if (iter.hasNext()) {
throw new ConstraintViolationException(mixinName + " can not be removed: the node is being referenced through at least one property of type REFERENCE");
}
@@ -1753,11 +1800,26 @@
// set jcr:mixinTypes property
setMixinTypesProperty(mixins);
+ // build effective node type of remaining mixin's & primary type
+ NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
+ NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
+ EffectiveNodeType entRemaining;
+ try {
+ // remaining mixin's
+ HashSet set = new HashSet(mixins);
+ // primary type
+ set.add(nodeType.getQName());
+ // build effective node type representing primary type including remaining mixin's
+ entRemaining = ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+ } catch (NodeTypeConflictException ntce) {
+ throw new ConstraintViolationException(ntce.getMessage());
+ }
+
NodeTypeImpl mixin = session.getNodeTypeManager().getNodeType(ntName);
// shortcut
- if (mixin.getDeclaredChildNodeDefs().length == 0 &&
- mixin.getDeclaredPropertyDefs().length == 0) {
+ if (mixin.getChildNodeDefs().length == 0 &&
+ mixin.getPropertyDefs().length == 0) {
// the node type has neither property nor child node definitions,
// i.e. we're done
return;
@@ -1774,13 +1836,11 @@
PropertyImpl prop = (PropertyImpl) itemMgr.getItem(new PropertyId(thisState.getUUID(), entry.getName()));
// check if property has been defined by mixin type (or one of its supertypes)
NodeTypeImpl declaringNT = (NodeTypeImpl) prop.getDefinition().getDeclaringNodeType();
- if (mixin.getQName().equals(declaringNT.getQName())
- || mixin.isDerivedFrom(declaringNT.getQName())) {
- // make sure declaring type is not included in primary type
- if (!nodeType.isDerivedFrom(declaringNT.getQName())) {
- // remove property
- removeChildProperty(entry.getName());
- }
+ if (!entRemaining.includesNodeType(declaringNT.getQName())) {
+ // the remaining effective node type doesn't include the
+ // node type that declared this property, it is thus safe
+ // to remove it
+ removeChildProperty(entry.getName());
}
}
// use temp array to avoid ConcurrentModificationException
@@ -1791,13 +1851,11 @@
NodeImpl node = (NodeImpl) itemMgr.getItem(new NodeId(entry.getUUID()));
// check if node has been defined by mixin type (or one of its supertypes)
NodeTypeImpl declaringNT = (NodeTypeImpl) node.getDefinition().getDeclaringNodeType();
- if (mixin.getQName().equals(declaringNT.getQName())
- || mixin.isDerivedFrom(declaringNT.getQName())) {
- // make sure declaring type is not included in primary type
- if (!nodeType.isDerivedFrom(declaringNT.getQName())) {
- // remove node
- removeChildNode(entry.getName(), entry.getIndex());
- }
+ if (!entRemaining.includesNodeType(declaringNT.getQName())) {
+ // the remaining effective node type doesn't include the
+ // node type that declared this child node, it is thus safe
+ // to remove it
+ removeChildNode(entry.getName(), entry.getIndex());
}
}
}
@@ -1839,13 +1897,20 @@
// build effective node type of mixins & primary type in order to detect conflicts
NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
- // existing mixin's
- HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
- // new mixin
- set.add(ntName);
- // primary type
- set.add(nodeType.getQName());
+ EffectiveNodeType entExisting;
try {
+ // existing mixin's
+ HashSet set = new HashSet(((NodeState) state).getMixinTypeNames());
+ // primary type
+ set.add(nodeType.getQName());
+ // build effective node type representing primary type including existing mixin's
+ entExisting = ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+ if (entExisting.includesNodeType(ntName)) {
+ return false;
+ }
+ // add new mixin
+ set.add(ntName);
+ // try to build new effective node type (will throw in case of conflicts)
ntReg.buildEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
} catch (NodeTypeConflictException ntce) {
return false;
@@ -1871,7 +1936,7 @@
public PropertyIterator getReferences() throws RepositoryException {
WorkspaceImpl wsp = (WorkspaceImpl) session.getWorkspace();
ReferenceManager refMgr = wsp.getReferenceManager();
- synchronized(refMgr) {
+ synchronized (refMgr) {
NodeReferences refs = refMgr.get((NodeId) id);
Iterator iter = refs.getReferences().iterator();
ArrayList list = new ArrayList();
@@ -2488,7 +2553,7 @@
String name = values[i].getString();
boolean found = false;
for (int j = 0; j < mixins.length; j++) {
- if (name.equals(mixins[j])) {
+ if (name.equals(mixins[j].getName())) {
// clear
mixins[j] = null;
found = true;
1.29 +3 -2 jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/PropertyImpl.java
Index: PropertyImpl.java
===================================================================
RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/PropertyImpl.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- PropertyImpl.java 6 Sep 2004 17:10:43 -0000 1.28
+++ PropertyImpl.java 9 Sep 2004 15:45:45 -0000 1.29
@@ -143,7 +143,8 @@
}
if (list.isEmpty()) {
// setting a property to null removes it automatically
- getParent().remove(getName());
+ // Protected/Lock etc. is already checked before
+ ((NodeImpl) getParent()).removeChildProperty(((PropertyId) id).getName());
return;
}
values = (InternalValue[]) list.toArray(new InternalValue[list.size()]);
1.26 +6 -2 jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryImpl.java
Index: RepositoryImpl.java
===================================================================
RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryImpl.java,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- RepositoryImpl.java 6 Sep 2004 17:10:43 -0000 1.25
+++ RepositoryImpl.java 9 Sep 2004 15:45:45 -0000 1.26
@@ -60,6 +60,10 @@
private static final String PROPERTIES_RESOURCE = "rep.properties";
private final Properties repProps;
+ // names of well known repository properties
+ public static final String STATS_NODE_COUNT_PROPERTY = "jcr.repository.stats.nodes.count";
+ public static final String STATS_PROP_COUNT_PROPERTY = "jcr.repository.stats.properties.count";
+
// pre-defined values of well known repository properties
private static final String SPEC_VERSION = "0.14";
private static final String SPEC_NAME = "Content Repository API for Java(TM) Technology Specification";
@@ -520,7 +524,7 @@
* @throws RepositoryException
*/
public NodeImpl getSystemRootNode(SessionImpl session) throws RepositoryException {
- return ((NodeImpl)session.getRootNode()).getNode(SYSTEM_ROOT_NAME);
+ return ((NodeImpl) session.getRootNode()).getNode(SYSTEM_ROOT_NAME);
}
//-----------------------------------------------------------< Repository >
1.3 +3 -3 jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/SessionImpl.java
Index: SessionImpl.java
===================================================================
RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/SessionImpl.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SessionImpl.java 6 Sep 2004 17:10:43 -0000 1.2
+++ SessionImpl.java 9 Sep 2004 15:45:45 -0000 1.3
@@ -614,7 +614,7 @@
class TransientNamespaceMappings implements NamespaceResolver {
// the global persistent namespace registry
- private NamespaceRegistry nsReg;
+ private NamespaceRegistryImpl nsReg;
// local prefix/namespace mappings
private HashMap prefixToURI = new HashMap();
@@ -623,7 +623,7 @@
// prefixes in global namespace registry hidden by local mappings
private Set hiddenPrefixes = new HashSet();
- TransientNamespaceMappings(NamespaceRegistry nsReg) {
+ TransientNamespaceMappings(NamespaceRegistryImpl nsReg) {
this.nsReg = nsReg;
}
1.7 +1 -2 jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype/NodeDefId.java
Index: NodeDefId.java
===================================================================
RCS file: /home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/nodetype/NodeDefId.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- NodeDefId.java 2 Aug 2004 16:21:50 -0000 1.6
+++ NodeDefId.java 9 Sep 2004 15:45:46 -0000 1.7
@@ -37,7 +37,6 @@
if (def == null) {
throw new IllegalArgumentException("ChildNodeDef argument can not be null");
}
- // build key (format: <declaring node type>/<name>/<default node type>/<required node types>)
StringBuffer sb = new StringBuffer();
sb.append(def.getDeclaringNodeType().toString());
---------------------------------------------------------------------
To unsubscribe, e-mail: slide-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: slide-dev-help@jakarta.apache.org