Example #1
0
 @Test
 public void shouldStoreNodeTypeDefinitionsInSystemCatalog() {
   Collection<JcrNodeType> nodeTypes =
       repository.nodeTypeManager().getNodeTypes().getAllNodeTypes();
   for (int i = 0; i != 3; ++i) {
     system.store(nodeTypes, true);
     assertThat(repository.nodeTypeManager().refreshFromSystem(), is(true));
   }
 }
  @Override
  public void registerIndexes(IndexDefinition[] indexDefinitions, boolean allowUpdate)
      throws InvalidIndexDefinitionException, IndexExistsException {
    CheckArg.isNotNull(indexDefinitions, "indexDefinitions");

    // Before we do anything, validate each of the index definitions and throw an exception ...
    RepositoryNodeTypeManager nodeTypeManager = repository.nodeTypeManager();
    List<IndexDefinition> validated = new ArrayList<>(indexDefinitions.length);
    Problems problems = new SimpleProblems();
    for (IndexDefinition defn : indexDefinitions) {
      String name = defn.getName();
      String providerName = defn.getProviderName();

      if (name == null) {
        problems.addError(JcrI18n.indexMustHaveName, defn, repository.name());
        continue;
      }
      if (indexes.getIndexDefinitions().containsKey(name) && !allowUpdate) {
        // Throw this one immediately ...
        String msg = JcrI18n.indexAlreadyExists.text(defn.getName(), repository.name());
        throw new IndexExistsException(msg);
      }
      if (providerName == null) {
        problems.addError(JcrI18n.indexMustHaveProviderName, defn.getName(), repository.name());
        continue;
      }
      if (defn.hasSingleColumn()) {
        IndexColumnDefinition columnDefn = defn.getColumnDefinition(0);
        Name propName =
            context.getValueFactories().getNameFactory().create(columnDefn.getPropertyName());
        switch (defn.getKind()) {
          case UNIQUE_VALUE:
            if (NON_UNIQUE_PROPERTY_NAMES.contains(propName)) {
              problems.addError(
                  JcrI18n.unableToCreateUniqueIndexForColumn,
                  defn.getName(),
                  columnDefn.getPropertyName());
            }
            break;
          case ENUMERATED_VALUE:
            if (NON_ENUMERATED_PROPERTY_NAMES.contains(propName)) {
              problems.addError(
                  JcrI18n.unableToCreateEnumeratedIndexForColumn,
                  defn.getName(),
                  columnDefn.getPropertyName());
            }
            break;
          case VALUE:
          case NODE_TYPE:
          case TEXT:
            break;
        }
      } else {
        // Mulitple columns ...
        if (defn.getKind() == IndexKind.NODE_TYPE) {
          // must be single-column indexes
          problems.addError(JcrI18n.nodeTypeIndexMustHaveOneColumn, defn.getName());
        }
      }
      IndexProvider provider = providers.get(providerName);
      if (provider == null) {
        problems.addError(JcrI18n.indexProviderDoesNotExist, defn.getName(), repository.name());
      } else {
        // Perform some default validations that should be applied to all providers...
        provider.validateDefaultColumnTypes(context, defn, problems);

        // Then have the provider perform any custom validations
        provider.validateProposedIndex(context, defn, nodeTypeManager, problems);

        // Create an instance of our own definition implementation ...
        defn = RepositoryIndexDefinition.createFrom(defn, true);

        validated.add(defn);
      }
    }
    if (problems.hasErrors()) {
      String msg = JcrI18n.invalidIndexDefinitions.text(repository.name(), problems);
      throw new InvalidIndexDefinitionException(new JcrProblems(problems), msg);
    }

    SessionCache systemCache = repository.createSystemSession(context, false);
    SystemContent system = new SystemContent(systemCache);
    for (IndexDefinition defn : validated) {
      String providerName = defn.getProviderName();

      // Determine if the index should be enabled ...
      defn = RepositoryIndexDefinition.createFrom(defn, providers.containsKey(providerName));

      // Write the definition to the system area ...
      system.store(defn, allowUpdate);
    }
    // Save the changes ...
    systemCache.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;
  }