private String getAclTenant(long aclId) {
    List<Long> nodeIds = aclDAO.getADMNodesByAcl(aclId, 1);
    if (nodeIds.size() == 0) {
      return null;
    }

    nodeDAO.setCheckNodeConsistency();
    Pair<Long, NodeRef> nodePair = nodeDAO.getNodePair(nodeIds.get(0));
    if (nodePair == null) {
      return null;
    }

    return tenantService.getDomain(nodePair.getSecond().getStoreRef().getIdentifier());
  }
  protected Map<QName, Serializable> getProperties(Long nodeId) {
    Map<QName, Serializable> props = null;

    // ALF-10641
    // Residual properties are un-indexed -> break serlialisation
    nodeDAO.setCheckNodeConsistency();
    Map<QName, Serializable> sourceProps = nodeDAO.getNodeProperties(nodeId);
    props = new HashMap<QName, Serializable>((int) (sourceProps.size() * 1.3));
    for (QName propertyQName : sourceProps.keySet()) {
      PropertyDefinition propDef = dictionaryService.getProperty(propertyQName);
      if (propDef != null) {
        props.put(propertyQName, sourceProps.get(propertyQName));
      }
    }

    return props;
  }
  private List<Long> preCacheNodes(NodeMetaDataParameters nodeMetaDataParameters) {
    int maxResults = nodeMetaDataParameters.getMaxResults();
    boolean isLimitSet = (maxResults != 0 && maxResults != Integer.MAX_VALUE);

    List<Long> nodeIds = null;
    Iterable<Long> iterable = null;
    List<Long> allNodeIds = nodeMetaDataParameters.getNodeIds();
    if (allNodeIds != null) {
      int toIndex = (maxResults > allNodeIds.size() ? allNodeIds.size() : maxResults);
      nodeIds = isLimitSet ? allNodeIds.subList(0, toIndex) : nodeMetaDataParameters.getNodeIds();
      iterable = nodeMetaDataParameters.getNodeIds();
    } else {
      Long fromNodeId = nodeMetaDataParameters.getFromNodeId();
      Long toNodeId = nodeMetaDataParameters.getToNodeId();
      nodeIds = new ArrayList<Long>(isLimitSet ? maxResults : 100); // TODO better default here?
      iterable = new SequenceIterator(fromNodeId, toNodeId, maxResults);
      int counter = 1;
      for (Long nodeId : iterable) {
        if (isLimitSet && counter++ > maxResults) {
          break;
        }
        nodeIds.add(nodeId);
      }
    }

    // Pre-evaluate ancestors so we can bulk load them
    List<Long> ancestors;
    if (cacheAncestors) {
      ancestors = cacheAncestors(nodeIds);
    } else {
      ancestors = nodeIds;
    }
    // Ensure that we get fresh node references
    nodeDAO.setCheckNodeConsistency();
    // bulk load nodes and their ancestors
    nodeDAO.cacheNodesById(ancestors);

    return nodeIds;
  }
  private CategoryPaths getCategoryPaths(
      NodeRef nodeRef, Set<QName> aspects, Map<QName, Serializable> properties) {
    ArrayList<Pair<Path, QName>> categoryPaths = new ArrayList<Pair<Path, QName>>();
    ArrayList<ChildAssociationRef> categoryParents = new ArrayList<ChildAssociationRef>();

    nodeDAO.setCheckNodeConsistency();
    for (QName classRef : aspects) {
      AspectDefinition aspDef = dictionaryService.getAspect(classRef);
      if (!isCategorised(aspDef)) {
        continue;
      }
      LinkedList<Pair<Path, QName>> aspectPaths = new LinkedList<Pair<Path, QName>>();
      for (PropertyDefinition propDef : aspDef.getProperties().values()) {
        if (!propDef.getDataType().getName().equals(DataTypeDefinition.CATEGORY)) {
          // The property is not a category
          continue;
        }
        // Don't try to iterate if the property is null
        Serializable propVal = properties.get(propDef.getName());
        if (propVal == null) {
          continue;
        }
        for (NodeRef catRef : DefaultTypeConverter.INSTANCE.getCollection(NodeRef.class, propVal)) {
          if (catRef == null) {
            continue;
          }
          // can be running in context of System user, hence use input nodeRef
          catRef = tenantService.getName(nodeRef, catRef);

          try {
            Pair<Long, NodeRef> pair = nodeDAO.getNodePair(catRef);
            if (pair != null) {
              for (Path path : nodeDAO.getPaths(pair, false)) {
                aspectPaths.add(new Pair<Path, QName>(path, aspDef.getName()));
              }
            }
          } catch (InvalidNodeRefException e) {
            // If the category does not exists we move on the next
          }
        }
      }
      categoryPaths.addAll(aspectPaths);
    }
    // Add member final element
    for (Pair<Path, QName> pair : categoryPaths) {
      if (pair.getFirst().last() instanceof Path.ChildAssocElement) {
        Path.ChildAssocElement cae = (Path.ChildAssocElement) pair.getFirst().last();
        ChildAssociationRef assocRef = cae.getRef();
        ChildAssociationRef categoryParentRef =
            new ChildAssociationRef(
                assocRef.getTypeQName(),
                assocRef.getChildRef(),
                QName.createQName("member"),
                nodeRef);
        pair.getFirst().append(new Path.ChildAssocElement(categoryParentRef));
        categoryParents.add(categoryParentRef);
      }
    }

    return new CategoryPaths(categoryPaths, categoryParents);
  }
 @Override
 public Long getMaxTxnId() {
   long maxCommitTime = System.currentTimeMillis() + 1L;
   nodeDAO.setCheckNodeConsistency();
   return nodeDAO.getMaxTxnIdByCommitTime(maxCommitTime);
 }
 @Override
 public Long getMaxTxnCommitTime() {
   nodeDAO.setCheckNodeConsistency();
   return nodeDAO.getMaxTxnCommitTime();
 }