@SuppressWarnings("unchecked")
  @Test
  public void shouldAllowUnregisteringUnusedTypesWithMutualDependencies() throws Exception {
    ntTemplate.setName(TEST_TYPE_NAME);

    JcrNodeDefinitionTemplate childNode = new JcrNodeDefinitionTemplate(this.context);
    childNode.setDefaultPrimaryTypeName(TEST_TYPE_NAME2);
    ntTemplate.getNodeDefinitionTemplates().add(childNode);

    NodeTypeTemplate ntTemplate2 = new JcrNodeTypeTemplate(this.context);
    ntTemplate2.setName(TEST_TYPE_NAME2);

    JcrNodeDefinitionTemplate childNode2 = new JcrNodeDefinitionTemplate(this.context);
    childNode2.setDefaultPrimaryTypeName(TEST_TYPE_NAME);
    ntTemplate2.getNodeDefinitionTemplates().add(childNode2);

    try {
      repoTypeManager.registerNodeTypes(
          Arrays.asList(new NodeTypeDefinition[] {ntTemplate, ntTemplate2}));
    } catch (Exception ex) {
      fail(ex.getMessage());
    }

    Name typeNameAsName = nameFactory.create(TEST_TYPE_NAME);
    Name type2NameAsName = nameFactory.create(TEST_TYPE_NAME2);
    int nodeTypeCount = nodeTypes().getAllNodeTypes().size();
    repoTypeManager.unregisterNodeType(
        Arrays.asList(new Name[] {typeNameAsName, type2NameAsName}), true);
    assertThat(nodeTypes().getAllNodeTypes().size(), is(nodeTypeCount - 2));
    assertThat(nodeTypes().getNodeType(typeNameAsName), is(nullValue()));
    assertThat(nodeTypes().getNodeType(type2NameAsName), is(nullValue()));
  }
  /**
   * Returns a {@code NodeTypeTemplate} based on the definition given in {@code ntd}. This template
   * can then be used to define a node type and passed to {@link
   * JcrNodeTypeManager#registerNodeType(NodeTypeDefinition, boolean)}
   *
   * @param ntd an existing node type definition; null values will be ignored
   * @return an empty {@code NodeTypeTemplate} which can then be used to define a node type and
   *     passed to {@link JcrNodeTypeManager#registerNodeType(NodeTypeDefinition, boolean)}.
   * @throws RepositoryException if another error occurs
   */
  @Override
  @SuppressWarnings("unchecked")
  public NodeTypeTemplate createNodeTypeTemplate(NodeTypeDefinition ntd)
      throws RepositoryException {
    NodeTypeTemplate ntt = new JcrNodeTypeTemplate(context(), true);

    if (ntd != null) {
      ntt.setName(ntd.getName());
      ntt.setAbstract(ntd.isAbstract());
      ntt.setDeclaredSuperTypeNames(ntd.getDeclaredSupertypeNames());
      ntt.setMixin(ntd.isMixin());
      ntt.setOrderableChildNodes(ntd.hasOrderableChildNodes());
      ntt.setPrimaryItemName(ntd.getPrimaryItemName());
      ntt.setQueryable(ntd.isQueryable());

      // copy child nodes and props
      for (NodeDefinition nodeDefinition : ntd.getDeclaredChildNodeDefinitions()) {
        JcrNodeDefinitionTemplate ndt = new JcrNodeDefinitionTemplate(context());

        ndt.setAutoCreated(nodeDefinition.isAutoCreated());
        ndt.setDefaultPrimaryTypeName(nodeDefinition.getDefaultPrimaryTypeName());
        ndt.setMandatory(nodeDefinition.isMandatory());
        if (nodeDefinition.getName() != null) {
          ndt.setName(nodeDefinition.getName());
        }
        ndt.setOnParentVersion(nodeDefinition.getOnParentVersion());
        ndt.setProtected(nodeDefinition.isProtected());
        ndt.setRequiredPrimaryTypeNames(nodeDefinition.getRequiredPrimaryTypeNames());
        ndt.setSameNameSiblings(nodeDefinition.allowsSameNameSiblings());

        ntt.getNodeDefinitionTemplates().add(ndt);
      }

      for (PropertyDefinition propertyDefinition : ntd.getDeclaredPropertyDefinitions()) {
        JcrPropertyDefinitionTemplate pdt = new JcrPropertyDefinitionTemplate(context());

        pdt.setAutoCreated(propertyDefinition.isAutoCreated());
        pdt.setAvailableQueryOperators(propertyDefinition.getAvailableQueryOperators());
        pdt.setDefaultValues(propertyDefinition.getDefaultValues());
        pdt.setFullTextSearchable(propertyDefinition.isFullTextSearchable());
        pdt.setMandatory(propertyDefinition.isMandatory());
        pdt.setMultiple(propertyDefinition.isMultiple());
        if (propertyDefinition.getName() != null) {
          pdt.setName(propertyDefinition.getName());
        }
        pdt.setOnParentVersion(propertyDefinition.getOnParentVersion());
        pdt.setProtected(propertyDefinition.isProtected());
        pdt.setQueryOrderable(propertyDefinition.isQueryOrderable());
        pdt.setRequiredType(propertyDefinition.getRequiredType());
        pdt.setValueConstraints(propertyDefinition.getValueConstraints());

        ntt.getPropertyDefinitionTemplates().add(pdt);
      }
    }

    return ntt;
  }
 /**
  * Create a new JCR node type definition from the given <code>QNodeTypeDefinition</code>.
  *
  * @param qNtd A SPI node type definition.
  * @return the corresponding JCR node type definition.
  * @throws RepositoryException if an error occurs.
  */
 @SuppressWarnings("unchecked")
 public NodeTypeDefinition create(QNodeTypeDefinition qNtd) throws RepositoryException {
   NodeTypeTemplate nt = ntMgr.createNodeTypeTemplate();
   nt.setName(getJCRName(qNtd.getName()));
   nt.setDeclaredSuperTypeNames(getJCRNames(qNtd.getSupertypes()));
   nt.setAbstract(qNtd.isAbstract());
   nt.setMixin(qNtd.isMixin());
   nt.setOrderableChildNodes(qNtd.hasOrderableChildNodes());
   nt.setPrimaryItemName(getJCRName(qNtd.getPrimaryItemName()));
   nt.setQueryable(qNtd.isQueryable());
   List nodeDefs = nt.getNodeDefinitionTemplates();
   for (QNodeDefinition qNd : qNtd.getChildNodeDefs()) {
     nodeDefs.add(create(qNd));
   }
   List propDefs = nt.getPropertyDefinitionTemplates();
   for (QPropertyDefinition qPd : qNtd.getPropertyDefs()) {
     propDefs.add(create(qPd));
   }
   return nt;
 }
  @SuppressWarnings("unchecked")
  protected NodeTypeDefinition[] getTestTypes()
      throws ConstraintViolationException, RepositoryException {
    ExecutionContext context = session.context();
    session
        .getWorkspace()
        .getNamespaceRegistry()
        .registerNamespace("modetest", "http://www.modeshape.org/test/1.0");
    NodeTypeTemplate nodeA = new JcrNodeTypeTemplate(context);
    nodeA.setName("modetest:nodeA");

    JcrPropertyDefinitionTemplate nodeASingleProp1 = new JcrPropertyDefinitionTemplate(context);
    nodeASingleProp1.setName("modetest:singleProp1");
    nodeASingleProp1.setRequiredType(PropertyType.STRING);
    nodeA.getPropertyDefinitionTemplates().add(nodeASingleProp1);

    NodeTypeTemplate nodeB = new JcrNodeTypeTemplate(context);
    nodeB.setName("modetest:nodeB");

    JcrPropertyDefinitionTemplate nodeBSingleProp1 = new JcrPropertyDefinitionTemplate(context);
    nodeBSingleProp1.setName("modetest:singleProp1");
    nodeBSingleProp1.setRequiredType(PropertyType.DOUBLE);
    nodeB.getPropertyDefinitionTemplates().add(nodeBSingleProp1);

    JcrPropertyDefinitionTemplate nodeBSingleProp2 = new JcrPropertyDefinitionTemplate(context);
    nodeBSingleProp2.setName("modetest:singleProp2");
    nodeBSingleProp2.setRequiredType(PropertyType.UNDEFINED);
    nodeB.getPropertyDefinitionTemplates().add(nodeBSingleProp2);

    NodeTypeTemplate nodeC = new JcrNodeTypeTemplate(context);
    nodeC.setName("modetest:nodeC");
    nodeC.setDeclaredSuperTypeNames(new String[] {"modetest:nodeB"});

    JcrPropertyDefinitionTemplate nodeCSingleProp1 = new JcrPropertyDefinitionTemplate(context);
    nodeCSingleProp1.setName("modetest:singleProp1");
    nodeCSingleProp1.setRequiredType(PropertyType.LONG);
    nodeC.getPropertyDefinitionTemplates().add(nodeCSingleProp1);

    JcrPropertyDefinitionTemplate nodeCSingleProp2Double =
        new JcrPropertyDefinitionTemplate(context);
    nodeCSingleProp2Double.setName("modetest:singleProp2");
    nodeCSingleProp2Double.setRequiredType(PropertyType.DOUBLE);
    nodeC.getPropertyDefinitionTemplates().add(nodeCSingleProp2Double);

    JcrPropertyDefinitionTemplate nodeCSingleProp2Long = new JcrPropertyDefinitionTemplate(context);
    nodeCSingleProp2Long.setName("modetest:singleProp2");
    nodeCSingleProp2Long.setRequiredType(PropertyType.LONG);
    nodeC.getPropertyDefinitionTemplates().add(nodeCSingleProp2Long);

    return new NodeTypeDefinition[] {nodeA, nodeB, nodeC};
  }
  @Test
  public void testAggregateIndex()
      throws IOException, RepositoryException, InterruptedException, ClientPoolException,
          StorageClientException, AccessDeniedException, ClassNotFoundException {
    RepositoryBase repositoryBase = RepositoryBaseTest.getRepositoryBase();
    Repository repository = repositoryBase.getRepository();
    Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
    NodeTypeManager ntm = session.getWorkspace().getNodeTypeManager();

    NodeTypeTemplate ntt = ntm.createNodeTypeTemplate();
    ntt.setDeclaredSuperTypeNames(new String[] {"nt:unstructured"});
    ntt.setName("sakai:user-home");

    ntm.registerNodeType(ntt, true);

    Node rootNode = session.getRootNode();
    Node homeNode = rootNode.addNode("iebhome", "sakai:user-home");
    homeNode.setProperty("sling:resourceType", "sakai/user-home");
    Node publicNode = homeNode.addNode("public", "nt:unstructured");
    Node publicSub = publicNode.addNode("sub", "nt:unstructured");
    publicSub.setProperty("test", "The brown fox");
    Node publicSub2 = publicNode.addNode("sub2", "nt:unstructured");
    publicSub2.setProperty("test", "The brown fox");
    Node childFileNode = publicSub.addNode("childNode", "nt:file");
    Node resourceNode = childFileNode.addNode("jcr:content", "nt:resource");
    ValueFactory valueFactory = session.getValueFactory();
    InputStream fileStream = new ByteArrayInputStream(FILE_CONTENT.getBytes("UTF-8"));
    Binary binary = valueFactory.createBinary(fileStream);
    resourceNode.setProperty("jcr:data", binary);
    session.save();
    session.logout();

    Thread.sleep(100);

    session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
    Node n = session.getNode("/iebhome/public/sub");
    Assert.assertEquals("The brown fox", n.getProperty("test").getString());

    QueryManager qm = session.getWorkspace().getQueryManager();
    {
      Query q =
          qm.createQuery(
              "//*[@sling:resourceType = 'sakai/user-home' and jcr:contains(.,'brown')]",
              Query.XPATH);
      QueryResult qr = q.execute();
      NodeIterator nodeIterator = qr.getNodes();
      Assert.assertTrue(nodeIterator.hasNext());
      Assert.assertEquals("/iebhome", nodeIterator.nextNode().getPath());
      Assert.assertFalse(nodeIterator.hasNext());
    }
    {
      Query q = qm.createQuery("//*[@sling:resourceType = 'sakai/user-home']", Query.XPATH);
      QueryResult qr = q.execute();
      NodeIterator nodeIterator = qr.getNodes();
      Assert.assertTrue(nodeIterator.hasNext());
      Assert.assertEquals("/iebhome", nodeIterator.nextNode().getPath());
      Assert.assertFalse(nodeIterator.hasNext());
    }
    {
      Query q = qm.createQuery("//*[jcr:contains(.,'brown')]", Query.XPATH);
      QueryResult qr = q.execute();
      NodeIterator nodeIterator = qr.getNodes();
      List<String> paths = new ArrayList<String>();
      while (nodeIterator.hasNext()) {
        paths.add(nodeIterator.nextNode().getPath());
      }

      Assert.assertTrue(paths.contains("/iebhome"));
      Assert.assertTrue(paths.contains("/iebhome/public/sub"));
      Assert.assertTrue(paths.contains("/iebhome/public/sub2"));
    }
    session.logout();
  }