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