/**
   * Tests if <code>NodeType.canAddChildNode(String childNodeName, String nodeTypeName)</code>
   * returns false if <code>nodeTypeName</code> represents an abstract node type.
   */
  public void testCanAddAbstractType() throws NotExecutableException, RepositoryException {

    NodeDefinition nodeDef = NodeTypeUtil.locateChildNodeDef(session, false, false, false);

    if (nodeDef == null) {
      throw new NotExecutableException("No testable node type found.");
    }

    NodeType nodeType = nodeDef.getDeclaringNodeType();
    String childNodeName = nodeDef.getName();
    String abstractName = null;
    NodeTypeIterator it = manager.getPrimaryNodeTypes();
    while (it.hasNext() && abstractName == null) {
      NodeType nt = it.nextNodeType();
      if (nt.isAbstract()) {
        abstractName = nt.getName();
      }
    }
    if (abstractName == null) {
      throw new NotExecutableException("No abstract type found.");
    }

    assertFalse(
        "NodeType.canAddChildNode(String childNodeName, String nodeTypeName) "
            + "must return false if nodeTypeName represents an abstract node type.",
        nodeType.canAddChildNode(childNodeName, abstractName));
  }
 /**
  * Map query types.
  *
  * @param queryCriteria the query criteria
  * @param queryBuilder the query builder
  * @throws Exception the exception
  */
 private void mapQueryTypes(final QueryCriteria queryCriteria, final SQLQueryBuilder queryBuilder)
     throws Exception {
   queryBuilder.selectTypes(null);
   // Searh on nt:base
   queryBuilder.fromNodeTypes(queryCriteria.getNodeTypes());
   ManageableRepository currentRepository = repositoryService.getCurrentRepository();
   NodeTypeManager manager = currentRepository.getNodeTypeManager();
   // Query all documents for specific content types
   String[] contentTypes = queryCriteria.getContentTypes();
   if ((contentTypes != null && contentTypes.length > 0 && queryCriteria.getKeyword() == null)
       || queryCriteria.isSearchWebpage()) {
     mapQuerySpecificNodeTypes(queryCriteria, queryBuilder, manager);
     return;
   }
   List<String> selectedNodeTypes = templateService.getDocumentTemplates();
   queryBuilder.openGroup(LOGICAL.AND);
   queryBuilder.equal("jcr:primaryType", "nt:resource", LOGICAL.NULL);
   // query on exo:rss-enable nodetypes for title, summary field
   queryBuilder.equal("jcr:mixinTypes", "exo:rss-enable", LOGICAL.OR);
   // query on metadata nodetype
   List<String> publicatioTypes = new ArrayList<String>(4);
   for (NodeTypeIterator iterator = manager.getAllNodeTypes(); iterator.hasNext(); ) {
     NodeType nodeType = iterator.nextNodeType();
     if (nodeType.isNodeType("publication:webpagesPublication")) {
       publicatioTypes.add(nodeType.getName());
       continue;
     }
     if (!nodeType.isNodeType("exo:metadata")) continue;
     if (nodeType.isMixin()) {
       queryBuilder.equal("jcr:mixinTypes", nodeType.getName(), LOGICAL.OR);
     } else {
       queryBuilder.equal("jcr:primaryType", nodeType.getName(), LOGICAL.OR);
     }
   }
   for (String type : selectedNodeTypes) {
     NodeType nodetype = manager.getNodeType(type);
     if (nodetype.isMixin()) {
       queryBuilder.like("jcr:mixinTypes", type, LOGICAL.OR);
     } else {
       queryBuilder.equal("jcr:primaryType", type, LOGICAL.OR);
     }
   }
   queryBuilder.closeGroup();
   // unwanted document types: exo:cssFile, exo:jsFile
   if (excludeMimeTypes.size() < 1) return;
   queryBuilder.openGroup(LOGICAL.AND_NOT);
   String[] mimetypes = excludeMimeTypes.toArray(new String[] {});
   queryBuilder.equal("jcr:mimeType", mimetypes[0], LOGICAL.NULL);
   for (int i = 1; i < mimetypes.length; i++) {
     queryBuilder.equal("jcr:mimeType", mimetypes[i], LOGICAL.OR);
   }
   queryBuilder.closeGroup();
   // Unwanted document by mixin nodetypes
   queryBuilder.openGroup(LOGICAL.AND_NOT);
   queryBuilder.like("jcr:mixinTypes", "exo:cssFile", LOGICAL.NULL);
   queryBuilder.like("jcr:mixinTypes", "exo:jsFile", LOGICAL.OR);
   queryBuilder.closeGroup();
 }
 @Override
 public String[] getMixinTypes(boolean allowAbstract) throws RemoteException {
   ArrayList<String> list = new ArrayList();
   try {
     NodeTypeManager mgr = session().getWorkspace().getNodeTypeManager();
     NodeTypeIterator it = mgr.getMixinNodeTypes();
     while (it.hasNext()) {
       NodeType nodeType = it.nextNodeType();
       if (!nodeType.isAbstract() || allowAbstract) {
         list.add(nodeType.getName());
       }
     }
     String[] res = new String[list.size()];
     list.toArray(res);
     return res;
   } catch (RepositoryException e) {
     throw new RemoteException(e.getMessage());
   }
 }
  @Override
  public Collection<JcrNodeType> nodeTypes() throws RemoteException {
    ArrayList<JcrNodeType> list = new ArrayList();
    try {
      NodeTypeManager mgr = session().getWorkspace().getNodeTypeManager();

      NodeTypeIterator it = mgr.getAllNodeTypes();
      while (it.hasNext()) {
        NodeType type = it.nextNodeType();
        JcrNodeType jcrType = new JcrNodeType();
        jcrType.setName(type.getName());
        jcrType.setAbstract(type.isAbstract());
        jcrType.setPrimary(!type.isMixin());
        jcrType.setMixin(type.isMixin());
        list.add(jcrType);
      }
    } catch (Exception e) {
      throw new RemoteException(e.getMessage());
    }
    return list;
  }
  /**
   * Tests if <code>NodeType.canAddChildNode(String childNodeName, String nodeTypeName)</code>
   * returns false if <code>nodeTypeName</code> represents a mixin.
   */
  public void testCanAddMixinType() throws NotExecutableException, RepositoryException {

    NodeDefinition nodeDef = NodeTypeUtil.locateChildNodeDef(session, false, false, false);

    if (nodeDef == null) {
      throw new NotExecutableException("No testable node type found.");
    }

    NodeType nodeType = nodeDef.getDeclaringNodeType();
    String childNodeName = nodeDef.getName();
    String mixinName;
    NodeTypeIterator it = manager.getMixinNodeTypes();
    if (it.hasNext()) {
      mixinName = it.nextNodeType().getName();
    } else {
      throw new NotExecutableException("No mixin type found.");
    }

    assertFalse(
        "NodeType.canAddChildNode(String childNodeName, String nodeTypeName) "
            + "must return false if nodeTypeName represents a mixin type.",
        nodeType.canAddChildNode(childNodeName, mixinName));
  }