/** * Register a set of namespaces. * * @param namespaceUrisByPrefix the map of new namespace URIs by their prefix */ public void register(Map<String, String> namespaceUrisByPrefix) { if (namespaceUrisByPrefix == null || namespaceUrisByPrefix.isEmpty()) return; final Lock lock = this.namespacesLock.writeLock(); try { lock.lock(); SystemContent systemContent = systemContent(false); systemContent.registerNamespaces(namespaceUrisByPrefix); systemContent.save(); for (Map.Entry<String, String> entry : namespaceUrisByPrefix.entrySet()) { String prefix = entry.getKey().trim(); String uri = entry.getValue().trim(); if (prefix.length() == 0) continue; this.cache.register(prefix, uri); } } finally { lock.unlock(); } }
@Override public boolean unregister(String namespaceUri) { CheckArg.isNotNull(namespaceUri, "namespaceUri"); namespaceUri = namespaceUri.trim(); final Lock lock = this.namespacesLock.writeLock(); try { lock.lock(); // Remove it from the cache ... boolean found = this.cache.unregister(namespaceUri); // Then from the source ... SystemContent systemContent = systemContent(false); boolean foundPersistent = systemContent.unregisterNamespace(namespaceUri); systemContent.save(); return foundPersistent || found; } finally { lock.unlock(); } }
@Override public String register(String prefix, String namespaceUri) { CheckArg.isNotNull(namespaceUri, "namespaceUri"); namespaceUri = namespaceUri.trim(); final Lock lock = this.namespacesLock.writeLock(); try { lock.lock(); // Register it in the cache first ... String previousCachedUriForPrefix = this.cache.register(prefix, namespaceUri); if (!namespaceUri.equals(previousCachedUriForPrefix)) { // And register it in the source ... SystemContent systemContent = systemContent(false); systemContent.registerNamespaces(Collections.singletonMap(prefix, namespaceUri)); systemContent.save(); } return previousCachedUriForPrefix; } finally { lock.unlock(); } }
@Override public String getPrefixForNamespaceUri(String namespaceUri, boolean generateIfMissing) { CheckArg.isNotNull(namespaceUri, "namespaceUri"); Lock lock = this.namespacesLock.readLock(); try { lock.lock(); // Try the cache first ... String prefix = cache.getPrefixForNamespaceUri(namespaceUri, false); if (prefix == null && generateIfMissing) { SystemContent systemContent = systemContent(!generateIfMissing); prefix = systemContent.readNamespacePrefix(namespaceUri, generateIfMissing); if (prefix != null) { systemContent.save(); cache.register(prefix, namespaceUri); } } return prefix; } finally { lock.unlock(); } }
@Override public void unregisterIndexes(String... indexNames) throws NoSuchIndexException, RepositoryException { if (indexNames == null || indexNames.length == 0) return; // Remove the definition from the system area ... SessionCache systemCache = repository.createSystemSession(context, false); SystemContent system = new SystemContent(systemCache); for (String indexName : indexNames) { IndexDefinition defn = indexes.getIndexDefinitions().get(indexName); if (defn == null) { throw new NoSuchIndexException( JcrI18n.indexDoesNotExist.text(indexName, repository.name())); } system.remove(defn); } system.save(); // Refresh the immutable snapshot ... this.indexes = readIndexDefinitions(); }
List<JcrNodeType> registerNodeTypes( Iterable<NodeTypeDefinition> nodeTypeDefns, boolean failIfNodeTypeDefinitionsExist, boolean skipIfNodeTypeDefinitionExists, boolean persist) throws InvalidNodeTypeDefinitionException, NodeTypeExistsException, RepositoryException { if (nodeTypeDefns == null) { return Collections.emptyList(); } List<JcrNodeType> typesPendingRegistration = new ArrayList<JcrNodeType>(); try { nodeTypesLock.writeLock().lock(); final NodeTypes nodeTypes = this.nodeTypesCache; for (NodeTypeDefinition nodeTypeDefn : nodeTypeDefns) { if (nodeTypeDefn instanceof JcrNodeTypeTemplate) { // Switch to use this context, so names are properly prefixed ... nodeTypeDefn = ((JcrNodeTypeTemplate) nodeTypeDefn).with(context); } Name internalName = nodeTypes.nameFactory().create(nodeTypeDefn.getName()); if (internalName == null || internalName.getLocalName().length() == 0) { throw new InvalidNodeTypeDefinitionException(JcrI18n.invalidNodeTypeName.text()); } boolean found = nodeTypes.hasNodeType(internalName); if (found && failIfNodeTypeDefinitionsExist) { String name = nodeTypeDefn.getName(); throw new NodeTypeExistsException(internalName, JcrI18n.nodeTypeAlreadyExists.text(name)); } if (found && skipIfNodeTypeDefinitionExists) continue; List<JcrNodeType> supertypes = nodeTypes.supertypesFor(nodeTypeDefn, typesPendingRegistration); JcrNodeType nodeType = nodeTypeFrom(nodeTypeDefn, supertypes); typesPendingRegistration.add(nodeType); } if (!typesPendingRegistration.isEmpty()) { // Make sure the nodes have primary types that are either already registered, or pending // registration ... validateTypes(typesPendingRegistration); // Validate each of types that should be registered for (JcrNodeType typePendingRegistration : typesPendingRegistration) { nodeTypes.validate( typePendingRegistration, Arrays.asList(typePendingRegistration.getDeclaredSupertypes()), typesPendingRegistration); } SystemContent system = null; if (persist) { SessionCache systemCache = repository.createSystemSession(context, false); system = new SystemContent(systemCache); } for (JcrNodeType nodeType : typesPendingRegistration) { if (system != null) system.store(nodeType, true); } // Create the new cache ... NodeTypes newNodeTypes = nodeTypes.with(typesPendingRegistration); // Save the changes ... if (system != null) system.save(); // And finally update the capabilities cache ... this.nodeTypesCache = newNodeTypes; this.schemata = null; } } finally { nodeTypesLock.writeLock().unlock(); } return typesPendingRegistration; }
/** * 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 */ 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, supertype.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; } finally { nodeTypesLock.writeLock().unlock(); } }