jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r376692 - in /incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype: EffectiveNodeTypeCache.java NodeTypeDef.java NodeTypeImpl.java NodeTypeRegistry.java
Date Fri, 10 Feb 2006 14:05:33 GMT
Author: stefan
Date: Fri Feb 10 06:05:31 2006
New Revision: 376692

URL: http://svn.apache.org/viewcvs?rev=376692&view=rev
Log:
JCR-275: added NodeTypeRegistry.unregisterNodeTypes(Collection)
- some additional cleaning up of implementation

Modified:
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeTypeCache.java
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java
    incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeTypeCache.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeTypeCache.java?rev=376692&r1=376691&r2=376692&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeTypeCache.java
(original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/EffectiveNodeTypeCache.java
Fri Feb 10 06:05:31 2006
@@ -107,8 +107,17 @@
      *
      * @see WeightedKey#compareTo
      */
-    Iterator keys() {
+    Iterator keyIterator() {
         return sortedKeys.iterator();
+    }
+
+    /**
+     * Returns the set of keys.
+     *
+     * @return the set of keys.
+     */
+    Set keySet() {
+        return Collections.unmodifiableSet(sortedKeys);
     }
 
     //-------------------------------------------------------------< Dumpable >

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java?rev=376692&r1=376691&r2=376692&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java
(original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeDef.java
Fri Feb 10 06:05:31 2006
@@ -44,6 +44,7 @@
     public NodeTypeDef() {
         dependencies = null;
         name = null;
+        primaryItemName = null;
         nodeDefs = NodeDef.EMPTY_ARRAY;
         propDefs = PropDef.EMPTY_ARRAY;
         supertypes = QName.EMPTY_ARRAY;
@@ -51,42 +52,6 @@
         orderableChildNodes = false;
     }
 
-    public Object clone() throws CloneNotSupportedException {
-        // create a shallow copy
-        NodeTypeDef clone = (NodeTypeDef) super.clone();
-        // clear dependencies (will be lazily built)
-        clone.resetDependencies();
-        return clone;
-    }
-
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof NodeTypeDef) {
-            NodeTypeDef other = (NodeTypeDef) obj;
-            return (name == null ? other.name == null : name.equals(other.name))
-                    && (primaryItemName == null ? other.primaryItemName == null :
primaryItemName.equals(other.primaryItemName))
-                    && Arrays.equals(supertypes, other.supertypes)
-                    && mixin == other.mixin
-                    && orderableChildNodes == other.orderableChildNodes
-                    && Arrays.equals(propDefs, other.propDefs)
-                    && Arrays.equals(nodeDefs, other.nodeDefs);
-        }
-        return false;
-    }
-
-    /**
-     * Returns zero to satisfy the Object equals/hashCode contract.
-     * This class is mutable and not meant to be used as a hash key.
-     *
-     * @return always zero
-     * @see Object#hashCode()
-     */
-    public int hashCode() {
-        return 0;
-    }
-
     /**
      * Returns a collection of node type <code>QName</code>s that are being
      * referenced by <i>this</i> node type definition (e.g. as supertypes, as
@@ -144,6 +109,7 @@
         dependencies = null;
     }
 
+    //----------------------------------------------------< setters & getters >
     /**
      * Sets the name of the node type being defined.
      *
@@ -197,6 +163,7 @@
      * @param defs An array of <code>PropertyDef</code> objects.
      */
     public void setPropertyDefs(PropDef[] defs) {
+        resetDependencies();
         propDefs = defs;
     }
 
@@ -279,5 +246,46 @@
      */
     public NodeDef[] getChildNodeDefs() {
         return nodeDefs;
+    }
+
+    //-------------------------------------------< java.lang.Object overrides >
+    public Object clone() {
+        NodeTypeDef clone = new NodeTypeDef();
+        clone.name = name;
+        clone.primaryItemName = primaryItemName;
+        clone.supertypes = (QName[]) supertypes.clone();
+        clone.mixin = mixin;
+        clone.orderableChildNodes = orderableChildNodes;
+        clone.nodeDefs = (NodeDef[]) nodeDefs.clone();
+        clone.propDefs = (PropDef[]) propDefs.clone();
+        return clone;
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NodeTypeDef) {
+            NodeTypeDef other = (NodeTypeDef) obj;
+            return (name == null ? other.name == null : name.equals(other.name))
+                    && (primaryItemName == null ? other.primaryItemName == null :
primaryItemName.equals(other.primaryItemName))
+                    && Arrays.equals(supertypes, other.supertypes)
+                    && mixin == other.mixin
+                    && orderableChildNodes == other.orderableChildNodes
+                    && Arrays.equals(propDefs, other.propDefs)
+                    && Arrays.equals(nodeDefs, other.nodeDefs);
+        }
+        return false;
+    }
+
+    /**
+     * Returns zero to satisfy the Object equals/hashCode contract.
+     * This class is mutable and not meant to be used as a hash key.
+     *
+     * @return always zero
+     * @see Object#hashCode()
+     */
+    public int hashCode() {
+        return 0;
     }
 }

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java?rev=376692&r1=376691&r2=376692&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java
(original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeImpl.java
Fri Feb 10 06:05:31 2006
@@ -66,14 +66,7 @@
         this.ent = ent;
         this.ntMgr = ntMgr;
         this.nsResolver = nsResolver;
-        try {
-            // store a clone of the definition
-            this.ntd = (NodeTypeDef) ntd.clone();
-        } catch (CloneNotSupportedException e) {
-            // should never get here
-            log.fatal("internal error", e);
-            throw new InternalError(e.getMessage());
-        }
+        this.ntd = ntd;
     }
 
     /**
@@ -94,14 +87,8 @@
      * @return the definition of this node type
      */
     public NodeTypeDef getDefinition() {
-        try {
-            // return a clone of the definition
-            return (NodeTypeDef) ntd.clone();
-        } catch (CloneNotSupportedException e) {
-            // should never get here
-            log.fatal("internal error", e);
-            throw new InternalError(e.getMessage());
-        }
+        // return clone to make sure nobody messes around with the 'live' definition
+        return (NodeTypeDef) ntd.clone();
     }
 
     /**

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java?rev=376692&r1=376691&r2=376692&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java
(original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeRegistry.java
Fri Feb 10 06:05:31 2006
@@ -230,13 +230,7 @@
         entCache.put(ent);
 
         // register clone of node type definition
-        try {
-            ntd = (NodeTypeDef) ntd.clone();
-        } catch (CloneNotSupportedException e) {
-            // should never get here
-            log.fatal("internal error", e);
-            throw new InternalError(e.getMessage());
-        }
+        ntd = (NodeTypeDef) ntd.clone();
         registeredNTDefs.put(name, ntd);
 
         // store property & child node definitions of new node type by id
@@ -252,31 +246,86 @@
         return ent;
     }
 
-    private void internalUnregister(QName name)
-            throws NoSuchNodeTypeException, RepositoryException {
-        if (!registeredNTDefs.containsKey(name)) {
-            throw new NoSuchNodeTypeException(name.toString());
+    /**
+     * Validates and registers the specified collection of <code>NodeTypeDef</code>
+     * objects. An <code>InvalidNodeTypeDefException</code> is thrown if the
+     * validation of any of the contained <code>NodeTypeDef</code> objects fails.
+     * <p/>
+     * Note that in the case an exception is thrown no node type will be
+     * eventually registered.
+     *
+     * @param ntDefs collection of <code>NodeTypeDef</code> objects
+     * @throws InvalidNodeTypeDefException
+     * @throws RepositoryException
+     * @see #registerNodeType
+     */
+    private synchronized void internalRegister(Collection ntDefs)
+            throws InvalidNodeTypeDefException, RepositoryException {
+
+        // @todo review
+
+        // cache of pre-built aggregations of node types
+        EffectiveNodeTypeCache anEntCache = new EffectiveNodeTypeCache(entCache);
+
+        // map of node type names and node type definitions
+        Map aRegisteredNTDefCache = new HashMap(registeredNTDefs);
+
+        // temporarily register the node type definition
+        // and do some preliminary checks
+        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
+            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+            QName name = ntd.getName();
+            if (name != null && registeredNTDefs.containsKey(name)) {
+                String msg = name + " already exists";
+                log.debug(msg);
+                throw new InvalidNodeTypeDefException(msg);
+            }
+            // add definition to temporary cache
+            aRegisteredNTDefCache.put(ntd.getName(), ntd);
         }
-        if (builtInNTDefs.contains(name)) {
-            throw new RepositoryException(name.toString()
-                    + ": can't unregister built-in node type.");
+
+        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
+            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+
+            EffectiveNodeType ent = validateNodeTypeDef(ntd, anEntCache, aRegisteredNTDefCache);
+
+            // store new effective node type instance
+            anEntCache.put(ent);
         }
 
+        // since no exception was thrown so far the definitions are assumed to be valid
+        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
+            NodeTypeDef ntd = (NodeTypeDef) iter.next();
+
+            // register clone of node type definition
+            ntd = (NodeTypeDef) ntd.clone();
+            registeredNTDefs.put(ntd.getName(), ntd);
+            // store property & child node definitions of new node type by id
+            PropDef[] pda = ntd.getPropertyDefs();
+            for (int i = 0; i < pda.length; i++) {
+                propDefs.put(pda[i].getId(), pda[i]);
+            }
+            NodeDef[] nda = ntd.getChildNodeDefs();
+            for (int i = 0; i < nda.length; i++) {
+                nodeDefs.put(nda[i].getId(), nda[i]);
+            }
+        }
+    }
+
+    private void internalUnregister(QName name) throws NoSuchNodeTypeException {
         NodeTypeDef ntd = (NodeTypeDef) registeredNTDefs.get(name);
+        if (ntd == null) {
+            throw new NoSuchNodeTypeException(name.toString());
+        }
         registeredNTDefs.remove(name);
         /**
          * remove all affected effective node types from aggregates cache
-         * (collect keys first to prevent ConcurrentModificationException)
+         * (copy keys first to prevent ConcurrentModificationException)
          */
-        Iterator iter = entCache.keys();
-        ArrayList keys = new ArrayList();
-        while (iter.hasNext()) {
-            keys.add(iter.next());
-        }
-        iter = keys.iterator();
-        while (iter.hasNext()) {
+        ArrayList keys = new ArrayList(entCache.keySet());
+        for (Iterator keysIter = keys.iterator(); keysIter.hasNext();) {
             EffectiveNodeTypeCache.WeightedKey k =
-                    (EffectiveNodeTypeCache.WeightedKey) iter.next();
+                    (EffectiveNodeTypeCache.WeightedKey) keysIter.next();
             EffectiveNodeType ent = entCache.get(k);
             if (ent.includesNodeType(name)) {
                 entCache.remove(k);
@@ -294,6 +343,14 @@
         }
     }
 
+    private void internalUnregister(Collection ntNames)
+            throws NoSuchNodeTypeException {
+        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
+            QName name = (QName) iter.next();
+            internalUnregister(name);
+        }
+    }
+
     /**
      * Add a <code>NodeTypeRegistryListener</code>
      *
@@ -398,7 +455,9 @@
      * @throws InvalidNodeTypeDefException
      * @throws RepositoryException
      */
-    private EffectiveNodeType validateNodeTypeDef(NodeTypeDef ntd, EffectiveNodeTypeCache
anEntCache, Map aRegisteredNTDefCache)
+    private EffectiveNodeType validateNodeTypeDef(NodeTypeDef ntd,
+                                                  EffectiveNodeTypeCache anEntCache,
+                                                  Map aRegisteredNTDefCache)
             throws InvalidNodeTypeDefException, RepositoryException {
 
         /**
@@ -791,7 +850,9 @@
      * @return
      * @throws NoSuchNodeTypeException
      */
-    public synchronized EffectiveNodeType getEffectiveNodeType(QName ntName, EffectiveNodeTypeCache
anEntCache, Map aRegisteredNTDefCache)
+    public synchronized EffectiveNodeType getEffectiveNodeType(QName ntName,
+                                                               EffectiveNodeTypeCache anEntCache,
+                                                               Map aRegisteredNTDefCache)
             throws NoSuchNodeTypeException {
         // 1. make sure that the specified node type exists
         if (!aRegisteredNTDefCache.containsKey(ntName)) {
@@ -806,17 +867,8 @@
 
         // 3. build effective node type
         try {
-            NodeTypeDef def = (NodeTypeDef) aRegisteredNTDefCache.get(ntName);
-            NodeTypeDef ntDef4ENT;
-            // return clone to make sure nobody messes around with the 'live' definition
-            try {
-                ntDef4ENT = (NodeTypeDef) def.clone();
-            } catch (CloneNotSupportedException e) {
-                // should never get here
-                log.fatal("internal error", e);
-                throw new InternalError(e.getMessage());
-            }
-            ent = EffectiveNodeType.create(this, ntDef4ENT, anEntCache, aRegisteredNTDefCache);
+            NodeTypeDef ntd = (NodeTypeDef) aRegisteredNTDefCache.get(ntName);
+            ent = EffectiveNodeType.create(this, ntd, anEntCache, aRegisteredNTDefCache);
             // store new effective node type
             anEntCache.put(ent);
             return ent;
@@ -836,7 +888,9 @@
      * @throws NodeTypeConflictException
      * @throws NoSuchNodeTypeException
      */
-    public synchronized EffectiveNodeType getEffectiveNodeType(QName[] ntNames, EffectiveNodeTypeCache
anEntCache, Map aRegisteredNTDefCache)
+    public synchronized EffectiveNodeType getEffectiveNodeType(QName[] ntNames,
+                                                               EffectiveNodeTypeCache anEntCache,
+                                                               Map aRegisteredNTDefCache)
             throws NodeTypeConflictException, NoSuchNodeTypeException {
         // 1. make sure every single node type exists
         for (int i = 0; i < ntNames.length; i++) {
@@ -872,7 +926,7 @@
              * aggregate (i.e. the cost of building it)
              */
             boolean foundSubResult = false;
-            Iterator iter = anEntCache.keys();
+            Iterator iter = anEntCache.keyIterator();
             while (iter.hasNext()) {
                 EffectiveNodeTypeCache.WeightedKey k =
                         (EffectiveNodeTypeCache.WeightedKey) iter.next();
@@ -895,19 +949,9 @@
                  */
                 QName[] remainder = key.toArray();
                 for (int i = 0; i < remainder.length; i++) {
-                    NodeTypeDef def = (NodeTypeDef) aRegisteredNTDefCache.get(remainder[i]);
-                    NodeTypeDef clonedDef;
-                    // return clone to make sure nobody messes around with the 'live' definition
-                    try {
-                        clonedDef = (NodeTypeDef) def.clone();
-                    } catch (CloneNotSupportedException e) {
-                        // should never get here
-                        log.fatal("internal error", e);
-                        throw new InternalError(e.getMessage());
-                    }
-
+                    NodeTypeDef ntd = (NodeTypeDef) aRegisteredNTDefCache.get(remainder[i]);
                     EffectiveNodeType ent =
-                            EffectiveNodeType.create(this, clonedDef, anEntCache, aRegisteredNTDefCache);
+                            EffectiveNodeType.create(this, ntd, anEntCache, aRegisteredNTDefCache);
                     // store new effective node type
                     anEntCache.put(ent);
                     if (result == null) {
@@ -975,7 +1019,9 @@
         return getEffectiveNodeType(ntNames, entCache, registeredNTDefs);
     }
 
-    void checkForCircularInheritance(QName[] supertypes, Stack inheritanceChain, Map aRegisteredNTDefCache)
+    void checkForCircularInheritance(QName[] supertypes,
+                                     Stack inheritanceChain,
+                                     Map aRegisteredNTDefCache)
             throws InvalidNodeTypeDefException, RepositoryException {
         for (int i = 0; i < supertypes.length; i++) {
             QName nt = supertypes[i];
@@ -1062,7 +1108,8 @@
 
     /**
      * Validates the <code>NodeTypeDef</code> and returns
-     * a registered <code>EffectiveNodeType</code> instance.
+     * an  <code>EffectiveNodeType</code> object representing the newly
+     * registered node type.
      * <p/>
      * The validation includes the following checks:
      * <ul>
@@ -1118,176 +1165,110 @@
      * <p/>
      * This method can be used to register a set of node types that have
      * dependencies on each other.
-     * <p/>
-     * Note that in the case an exception is thrown, some node types might have
-     * been nevertheless successfully registered.
      *
-     * @param newNTDefs a collection of <code>NodeTypeDef<code>s
+     * @param ntDefs a collection of <code>NodeTypeDef<code> objects
      * @throws InvalidNodeTypeDefException
      * @throws RepositoryException
      */
-    public synchronized void registerNodeTypes(Collection newNTDefs)
+    public synchronized void registerNodeTypes(Collection ntDefs)
             throws InvalidNodeTypeDefException, RepositoryException {
-        // exceptions that might be thrown by internalRegister(Collection)
-        RepositoryException re = null;
-        InvalidNodeTypeDefException intde = null;
-
-        try {
-            internalRegister(newNTDefs);
-        } catch (RepositoryException e) {
-            // store exception so it can be re-thrown later on
-            re = e;
-        } catch (InvalidNodeTypeDefException e) {
-            // store exception so it can be re-thrown later on
-            intde = e;
-        }
-        boolean allNodeTypeDefsAreValid = re == null && intde == null;
-        if (allNodeTypeDefsAreValid) {
-            Iterator validNTDsIterator = newNTDefs.iterator();
-            while (validNTDsIterator.hasNext()) {
-                NodeTypeDef ntd = (NodeTypeDef) validNTDsIterator.next();
-                // store property & child node definitions of new node type by id
-                customNTDefs.add(ntd);
-            }
-            persistCustomNodeTypeDefs(customNTDefs);
-            // notify listeners
-            for (Iterator iter = newNTDefs.iterator(); iter.hasNext();) {
-                NodeTypeDef ntDef = (NodeTypeDef) iter.next();
-                notifyRegistered(ntDef.getName());
-            }
-        } else {
-            // re-throw the exception
-            if (re != null) {
-                throw re;
-            } else if (intde != null) {
-                throw intde;
-            }
+        // validate and register new node type definitions
+        internalRegister(ntDefs);
+        // persist new node type definitions
+        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
+            NodeTypeDef ntDef = (NodeTypeDef) iter.next();
+            customNTDefs.add(ntDef);
+        }
+        persistCustomNodeTypeDefs(customNTDefs);
+        // notify listeners
+        for (Iterator iter = ntDefs.iterator(); iter.hasNext();) {
+            NodeTypeDef ntDef = (NodeTypeDef) iter.next();
+            notifyRegistered(ntDef.getName());
         }
     }
 
     /**
-     * Validates and registers the specified collection of <code>NodeTypeDef</code>
-     * objects. An <code>InvalidNodeTypeDefException</code> is thrown if the
-     * validation of any of the contained <code>NodeTypeDef</code> objects fails.
+     * Same as <code>{@link #unregisterNodeType(QName)}</code> except
+     * that a set of node types is unregistered instead of just one.
      * <p/>
-     * Note that in the case an exception is thrown no node type will be
-     * registered.
+     * This method can be used to unregister a set of node types that depend on
+     * each other.
      *
-     * @param newNTDefs collection of <code>NodeTypeDef</code> objects
-     * @throws InvalidNodeTypeDefException
-     * @throws RepositoryException
-     * @see #registerNodeType
+     * @param ntNames a collection of <code>QName</code> objects denoting the
+     *                node types to be unregistered
+     * @throws NoSuchNodeTypeException if any of the specified names does not
+     *                                 denote a registered node type.
+     * @throws RepositoryException if another error occurs
+     * @see #unregisterNodeType(QName)
      */
-    private synchronized void internalRegister(Collection newNTDefs)
-            throws InvalidNodeTypeDefException, RepositoryException {
-
-        // cache of pre-built aggregations of node types
-        EffectiveNodeTypeCache anEntCache = new EffectiveNodeTypeCache(entCache);
-        
-        // map of node type names and node type definitions
-        Map aRegisteredNTDefCache = new HashMap(registeredNTDefs);
-        
-        // temporarily register a clone of the node type definition
-        // and do some checks by the way
-        Iterator ntdNameIterator = newNTDefs.iterator();
-        while (ntdNameIterator.hasNext()) {
-            Object ntdObject = ntdNameIterator.next();
-            // check if the right type is used
-            if (!(ntdObject instanceof NodeTypeDef)) {
-                String msg = "The specified object is not of type "
-                        + NodeTypeDef.class.getName();
-                log.debug(msg);
-                throw new InvalidNodeTypeDefException(msg);
-            } else {
-                // check if the ntd is new
-                NodeTypeDef ntd = (NodeTypeDef) ntdObject;
-                QName name = ntd.getName();
-                if (name != null && registeredNTDefs.containsKey(name)) {
-                    String msg = name + " already exists";
-                    log.debug(msg);
-                    throw new InvalidNodeTypeDefException(msg);
-                }
-                // clone the ntd and add it to the cache
-                NodeTypeDef clonedNTD;
-                try {
-                    clonedNTD = (NodeTypeDef) ntd.clone();
-                } catch (CloneNotSupportedException e) {
-                    // should never get here
-                    log.fatal("internal error", e);
-                    throw new InternalError(e.getMessage());
+    public synchronized void unregisterNodeTypes(Collection ntNames)
+            throws NoSuchNodeTypeException, RepositoryException {
+        // do some preliminary checks
+        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
+            QName ntName = (QName) iter.next();
+            if (!registeredNTDefs.containsKey(ntName)) {
+                throw new NoSuchNodeTypeException(ntName.toString());
+            }
+            if (builtInNTDefs.contains(ntName)) {
+                throw new RepositoryException(ntName.toString()
+                        + ": can't unregister built-in node type.");
+            }
+            // check for node types other than those to be unregistered
+            // that depend on the given node types
+            Set dependents = getDependentNodeTypes(ntName);
+            dependents.removeAll(ntNames);
+            if (dependents.size() > 0) {
+                StringBuffer msg = new StringBuffer();
+                msg.append(ntName
+                        + " can not be removed because the following node types depend on
it: ");
+                for (Iterator depIter = dependents.iterator(); depIter.hasNext();) {
+                    msg.append(depIter.next());
+                    msg.append(" ");
                 }
-                aRegisteredNTDefCache.put(clonedNTD.getName(), clonedNTD);
+                throw new RepositoryException(msg.toString());
             }
         }
-        Iterator ntdIterator = newNTDefs.iterator();
-        while (ntdIterator.hasNext()) {
-            NodeTypeDef ntd = (NodeTypeDef) ntdIterator.next();
-
-            EffectiveNodeType ent = validateNodeTypeDef(ntd, anEntCache, aRegisteredNTDefCache);
 
-            // store new effective node type instance
-            anEntCache.put(ent);
+        // make sure node types are not currently in use
+        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
+            QName ntName = (QName) iter.next();
+            checkForReferencesInContent(ntName);
         }
-        // as no exception occured at this point, the ntds are valid
-        Iterator validNTDsIterator = newNTDefs.iterator();
-        while (validNTDsIterator.hasNext()) {
-            NodeTypeDef ntd = (NodeTypeDef) validNTDsIterator.next();
-            registeredNTDefs.put(ntd.getName(), ntd);
-            // store property & child node definitions of new node type by id
-            PropDef[] pda = ntd.getPropertyDefs();
-            for (int i = 0; i < pda.length; i++) {
-                propDefs.put(pda[i].getId(), pda[i]);
-            }
-            NodeDef[] nda = ntd.getChildNodeDefs();
-            for (int i = 0; i < nda.length; i++) {
-                nodeDefs.put(nda[i].getId(), nda[i]);
-            }
+
+        // all preconditions are met, node types can now safely be unregistered
+        internalUnregister(ntNames);
+
+        // persist removal of node type definitions & notify listeners
+        for (Iterator iter = ntNames.iterator(); iter.hasNext();) {
+            QName ntName = (QName) iter.next();
+            customNTDefs.remove(ntName);
+            notifyUnregistered(ntName);
         }
+        persistCustomNodeTypeDefs(customNTDefs);
     }
 
     /**
-     * @param nodeTypeName
-     * @throws NoSuchNodeTypeException
-     * @throws RepositoryException
+     * Unregisters the specified node type. In order for a node type to be
+     * successfully unregistered it must meet the following conditions:
+     * <ol>
+     * <li>the node type must obviously be registered.</li>
+     * <li>a built-in node type can not be unregistered.</li>
+     * <li>the node type must not have dependents, i.e. other node types that
+     * are referencing it.</li>
+     * <li>the node type must not be currently used by any workspace.</li>
+     * </ol>
+     *
+     * @param ntName name of the node type to be unregistered
+     * @throws NoSuchNodeTypeException if <code>ntName</code> does not
+     *                                 denote a registered node type.
+     * @throws RepositoryException if another error occurs.
+     * @see #unregisterNodeTypes(Collection)
      */
-    public synchronized void unregisterNodeType(QName nodeTypeName)
+    public synchronized void unregisterNodeType(QName ntName)
             throws NoSuchNodeTypeException, RepositoryException {
-        if (!registeredNTDefs.containsKey(nodeTypeName)) {
-            throw new NoSuchNodeTypeException(nodeTypeName.toString());
-        }
-        if (builtInNTDefs.contains(nodeTypeName)) {
-            throw new RepositoryException(nodeTypeName.toString()
-                    + ": can't unregister built-in node type.");
-        }
-
-        /**
-         * check if there are node types that have dependencies on the given
-         * node type
-         */
-        Set dependentNTs = getDependentNodeTypes(nodeTypeName);
-        if (dependentNTs.size() > 0) {
-            StringBuffer msg = new StringBuffer();
-            msg.append(nodeTypeName
-                    + " could not be removed because the following node types are referencing
it: ");
-            Iterator iterator = dependentNTs.iterator();
-            while (iterator.hasNext()) {
-                msg.append(iterator.next());
-                msg.append(" ");
-            }
-            throw new RepositoryException(msg.toString());
-        }
-
-        // make sure node type is not currently in use
-        checkForReferencesInContent(nodeTypeName);
-
-        internalUnregister(nodeTypeName);
-
-        // persist removal of node type definition
-        customNTDefs.remove(nodeTypeName);
-        persistCustomNodeTypeDefs(customNTDefs);
-
-        // notify listeners
-        notifyUnregistered(nodeTypeName);
+        HashSet ntNames = new HashSet();
+        ntNames.add(ntName);
+        unregisterNodeTypes(ntNames);
     }
 
     /**
@@ -1370,7 +1351,7 @@
      * Returns the names of those registered node types that have
      * dependencies on the given node type.
      *
-     * @param nodeTypeName
+     * @param nodeTypeName node type name
      * @return a set of node type <code>QName</code>s
      * @throws NoSuchNodeTypeException
      */
@@ -1410,13 +1391,7 @@
         }
         NodeTypeDef def = (NodeTypeDef) registeredNTDefs.get(nodeTypeName);
         // return clone to make sure nobody messes around with the 'live' definition
-        try {
-            return (NodeTypeDef) def.clone();
-        } catch (CloneNotSupportedException e) {
-            // should never get here
-            log.fatal("internal error", e);
-            throw new InternalError(e.getMessage());
-        }
+        return (NodeTypeDef) def.clone();
     }
 
     /**



Mime
View raw message