void unregisterNodeType( Collection<Name> nodeTypeNames,
                             boolean failIfNodeTypesAreUsed )
        throws NoSuchNodeTypeException, InvalidNodeTypeDefinitionException, RepositoryException {
        CheckArg.isNotNull(nodeTypeNames, "nodeTypeNames");
        if (nodeTypeNames.isEmpty()) return;

        if (failIfNodeTypesAreUsed) {
            long start = System.nanoTime();
            // Search the content graph to make sure that this type isn't being used
            for (Name nodeTypeName : nodeTypeNames) {
                if (isNodeTypeInUse(nodeTypeName)) {
                    String name = nodeTypeName.getString(context.getNamespaceRegistry());
                    throw new InvalidNodeTypeDefinitionException(JcrI18n.cannotUnregisterInUseType.text(name));
                }
            }
            long time = TimeUnit.MILLISECONDS.convert(Math.abs(System.nanoTime() - start), TimeUnit.NANOSECONDS);
            logger.debug("{0} milliseconds to check if any of these node types are unused before unregistering them: {1}", time,
                         nodeTypeNames);
        }

        try {
            /*
             * Grab an exclusive lock on this data to keep other nodes from being added/saved while the unregistration checks are occurring
             */
            List<JcrNodeType> removedNodeTypes = new ArrayList<JcrNodeType>(nodeTypeNames.size());
            nodeTypesLock.writeLock().lock();
            final NodeTypes nodeTypes = this.nodeTypesCache;

            for (Name nodeTypeName : nodeTypeNames) {
                /*
                 * Check that the type names are valid
                 */
                if (nodeTypeName == null) {
                    throw new NoSuchNodeTypeException(JcrI18n.invalidNodeTypeName.text());
                }
                String name = nodeTypeName.getString(context.getNamespaceRegistry());

                JcrNodeType foundNodeType = nodeTypes.getNodeType(nodeTypeName);
                if (foundNodeType == null) {
                    throw new NoSuchNodeTypeException(JcrI18n.noSuchNodeType.text(name));
                }
                removedNodeTypes.add(foundNodeType);

                /*
                 * Check that no other node definitions have dependencies on any of the named types
                 */
                for (JcrNodeType nodeType : nodeTypes.getAllNodeTypes()) {
                    // If this node is also being unregistered, don't run checks against it
                    if (nodeTypeNames.contains(nodeType.getInternalName())) {
                        continue;
                    }

                    for (JcrNodeType supertype : nodeType.supertypes()) {
                        if (nodeTypeName.equals(supertype.getInternalName())) {
                            throw new InvalidNodeTypeDefinitionException(JcrI18n.cannotUnregisterSupertype.text(name,
                                                                                                                nodeType.getName()));
                        }
                    }

                    for (JcrNodeDefinition childNode : nodeType.childNodeDefinitions()) {
                        NodeType defaultPrimaryType = childNode.getDefaultPrimaryType();
                        if (defaultPrimaryType != null && name.equals(defaultPrimaryType.getName())) {
                            throw new InvalidNodeTypeDefinitionException(
                                                                         JcrI18n.cannotUnregisterDefaultPrimaryType.text(name,
                                                                                                                         nodeType.getName(),
                                                                                                                         childNode.getName()));
                        }
                        if (childNode.requiredPrimaryTypeNameSet().contains(nodeTypeName)) {
                            throw new InvalidNodeTypeDefinitionException(
                                                                         JcrI18n.cannotUnregisterRequiredPrimaryType.text(name,
                                                                                                                          nodeType.getName(),
                                                                                                                          childNode.getName()));
                        }
                    }
                }
            }

            // Create the new cache ...
            NodeTypes newNodeTypes = nodeTypes.without(removedNodeTypes);

            // Remove the node types from persistent storage ...
            SessionCache system = repository.createSystemSession(context, false);
            SystemContent systemContent = new SystemContent(system);
            systemContent.unregisterNodeTypes(removedNodeTypes.toArray(new JcrNodeType[removedNodeTypes.size()]));
            systemContent.save();

            // Now change the cache ...
            this.nodeTypesCache = newNodeTypes;
            this.schemata = null;
            notifiyListeners();
        } finally {
            nodeTypesLock.writeLock().unlock();
        }
    }
void unregisterNodeType ( Collection < Name > nodeTypeNames , boolean failIfNodeTypesAreUsed ) throws NoSuchNodeTypeException , InvalidNodeTypeDefinitionException , RepositoryException { CheckArg . isNotNull ( nodeTypeNames , "nodeTypeNames" ) ; if ( nodeTypeNames . isEmpty ( ) ) return ; if ( failIfNodeTypesAreUsed ) { long start = System . nanoTime ( ) ; for ( Name nodeTypeName : nodeTypeNames ) { if ( isNodeTypeInUse ( nodeTypeName ) ) { String name = nodeTypeName . getString ( context . getNamespaceRegistry ( ) ) ; throw new InvalidNodeTypeDefinitionException ( JcrI18n . cannotUnregisterInUseType . text ( name ) ) ; } } long time = TimeUnit . MILLISECONDS . convert ( Math . abs ( System . nanoTime ( ) - start ) , TimeUnit . NANOSECONDS ) ; logger . debug ( "{0} milliseconds to check if any of these node types are unused before unregistering them: {1}" , time , nodeTypeNames ) ; } try { List < JcrNodeType > removedNodeTypes = new ArrayList < JcrNodeType > ( nodeTypeNames . size ( ) ) ; nodeTypesLock . writeLock ( ) . lock ( ) ; final NodeTypes nodeTypes = this . nodeTypesCache ; for ( Name nodeTypeName : nodeTypeNames ) { if ( nodeTypeName == null ) { throw new NoSuchNodeTypeException ( JcrI18n . invalidNodeTypeName . text ( ) ) ; } String name = nodeTypeName . getString ( context . getNamespaceRegistry ( ) ) ; JcrNodeType foundNodeType = nodeTypes . getNodeType ( nodeTypeName ) ; if ( foundNodeType == null ) { throw new NoSuchNodeTypeException ( JcrI18n . noSuchNodeType . text ( name ) ) ; } removedNodeTypes . add ( foundNodeType ) ; for ( JcrNodeType nodeType : nodeTypes . getAllNodeTypes ( ) ) { if ( nodeTypeNames . contains ( nodeType . getInternalName ( ) ) ) { continue ; } for ( JcrNodeType supertype : nodeType . supertypes ( ) ) { if ( nodeTypeName . equals ( supertype . getInternalName ( ) ) ) { throw new InvalidNodeTypeDefinitionException ( JcrI18n . cannotUnregisterSupertype . text ( name , nodeType . getName ( ) ) ) ; } } for ( JcrNodeDefinition childNode : nodeType . childNodeDefinitions ( ) ) { NodeType defaultPrimaryType = childNode . getDefaultPrimaryType ( ) ; if ( defaultPrimaryType != null && name . equals ( defaultPrimaryType . getName ( ) ) ) { throw new InvalidNodeTypeDefinitionException ( JcrI18n . cannotUnregisterDefaultPrimaryType . text ( name , nodeType . getName ( ) , childNode . getName ( ) ) ) ; } if ( childNode . requiredPrimaryTypeNameSet ( ) . contains ( nodeTypeName ) ) { throw new InvalidNodeTypeDefinitionException ( JcrI18n . cannotUnregisterRequiredPrimaryType . text ( name , nodeType . getName ( ) , childNode . getName ( ) ) ) ; } } } } NodeTypes newNodeTypes = nodeTypes . without ( removedNodeTypes ) ; SessionCache system = repository . createSystemSession ( context , false ) ; SystemContent systemContent = new SystemContent ( system ) ; systemContent . unregisterNodeTypes ( removedNodeTypes . toArray ( new JcrNodeType [ removedNodeTypes . size ( ) ] ) ) ; systemContent . save ( ) ; this . nodeTypesCache = newNodeTypes ; this . schemata = null ; notifiyListeners ( ) ; } finally { nodeTypesLock . writeLock ( ) . unlock ( ) ; } }
Allows the collection of node types to be unregistered if they are not referenced by other node types as supertypes,
default primary types of child nodes, or required primary types of child nodes.

@param nodeTypeNames the names of the node types to be unregistered
@param failIfNodeTypesAreUsed true if this method should fail to unregister the named node types if any of the node types
are still in use by nodes, or false if this method should not perform such a check
@throws NoSuchNodeTypeException if any of the node type names do not correspond to a registered node type
@throws InvalidNodeTypeDefinitionException if any of the node types with the given names cannot be unregistered because
they are the supertype, one of the required primary types, or a default primary type of a node type that is not
being unregistered.
@throws RepositoryException if any other error occurs