/* (non-Javadoc) * @see org.alfresco.service.cmr.view.Exporter#startNode(org.alfresco.service.cmr.repository.NodeRef) */ public void startNode(NodeRef nodeRef) { try { AttributesImpl attrs = new AttributesImpl(); Path path = nodeService.getPath(nodeRef); if (path.size() > 1) { // a child name does not exist for root Path.ChildAssocElement pathElement = (Path.ChildAssocElement) path.last(); QName childQName = pathElement.getRef().getQName(); attrs.addAttribute( NamespaceService.REPOSITORY_VIEW_1_0_URI, CHILDNAME_LOCALNAME, CHILDNAME_QNAME.toPrefixString(), null, toPrefixString(childQName)); } QName type = nodeService.getType(nodeRef); contentHandler.startElement( type.getNamespaceURI(), type.getLocalName(), toPrefixString(type), attrs); } catch (SAXException e) { throw new ExporterException( "Failed to process start node event - node ref " + nodeRef.toString(), e); } }
/** * Helper to convert a path into an indexed path which uniquely identifies a node * * @param nodeRef * @param path * @return */ private Path createIndexedPath(NodeRef nodeRef, Path path) { // Add indexes for same name siblings // TODO: Look at more efficient approach for (int i = path.size() - 1; i >= 0; i--) { Path.Element pathElement = path.get(i); if (i > 0 && pathElement instanceof Path.ChildAssocElement) { int index = 1; // for xpath index compatibility String searchPath = path.subPath(i).toPrefixString(namespaceService); List<NodeRef> siblings = searchService.selectNodes(nodeRef, searchPath, null, namespaceService, false); if (siblings.size() > 1) { ChildAssociationRef childAssoc = ((Path.ChildAssocElement) pathElement).getRef(); NodeRef childRef = childAssoc.getChildRef(); for (NodeRef sibling : siblings) { if (sibling.equals(childRef)) { childAssoc.setNthSibling(index); break; } index++; } } } } return path; }
/** * Returns human readable path for node. To improve performance may return simple toString() * method of the path. * * @param nodeRef * @return Human readable path for node */ private String getNodePath(NodeRef nodeRef) { String result = null; if (nodeService.exists(nodeRef)) { Path path = nodeService.getPath(nodeRef); return path.toPrefixString(namespacePrefixResolver); } return result; }
/** * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) */ public boolean evaluate(Node node) { final FacesContext fc = FacesContext.getCurrentInstance(); final ServiceRegistry services = Repository.getServiceRegistry(fc); final NavigationBean navigator = (NavigationBean) FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME); // get the path to the current name - compare last element with the Forms folder name final Path path = navigator.getCurrentNode().getNodePath(); final Path.Element element = path.get(path.size() - 1); final String endPath = element.getPrefixedString(services.getNamespaceService()); // check we have the permission to create nodes in that Forma folder return (Application.getContentFormsFolderName(fc).equals(endPath) && navigator.getCurrentNode().hasPermission(PermissionService.ADD_CHILDREN)); }
/** * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) */ public boolean evaluate(final Node node) { // is the authenticated user permitted to execute the regenerate renditions action // against at least one web project boolean isUserAllowed = false; final FacesContext fc = FacesContext.getCurrentInstance(); final ServiceRegistry services = Repository.getServiceRegistry(fc); final PermissionService permissionService = services.getPermissionService(); final WebProjectService webProjectService = services.getWebProjectService(); final NavigationBean navigator = (NavigationBean) FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME); // check that the authenticated user has CONTENT MANAGER permissions for at least one web // project // this will ensure that the action appears only if the user is able to regenerate renditions // for at least one web project List<WebProjectInfo> wpInfos = webProjectService.listWebProjects(); for (WebProjectInfo wpInfo : wpInfos) { if (permissionService.hasPermission( wpInfo.getNodeRef(), PermissionService.WCM_CONTENT_MANAGER) == AccessStatus.ALLOWED) { isUserAllowed = true; break; } } // TODO improve how we determine whether the form supports the ability to regenerate renditions // or not // get the path to the current name - compare each path element with the Web Forms folder name final Path path = navigator.getCurrentNode().getNodePath(); boolean isWebFormsPath = false; Iterator<Path.Element> itr = path.iterator(); while (itr.hasNext()) { Path.Element element = (Path.Element) itr.next(); String pathElement = element.getPrefixedString(services.getNamespaceService()); if (Application.getWebContentFormsFolderName(fc).equals(pathElement)) { isWebFormsPath = true; break; } } return (node.hasAspect(WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE) || isWebFormsPath) && isUserAllowed; }
/* (non-Javadoc) * @see org.alfresco.service.cmr.view.Exporter#startReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) */ public void startReference(NodeRef nodeRef, QName childName) { try { // determine format of reference e.g. node or path based ReferenceType referenceFormat = referenceType; if (nodeRef.equals(nodeService.getRootNode(nodeRef.getStoreRef()))) { referenceFormat = ReferenceType.PATHREF; } // output reference AttributesImpl attrs = new AttributesImpl(); if (referenceFormat.equals(ReferenceType.PATHREF)) { Path path = createPath(context.getExportParent(), context.getExportParent(), nodeRef); attrs.addAttribute( NamespaceService.REPOSITORY_VIEW_1_0_URI, PATHREF_LOCALNAME, PATHREF_QNAME.toPrefixString(), null, path.toPrefixString(namespaceService)); } else { attrs.addAttribute( NamespaceService.REPOSITORY_VIEW_1_0_URI, NODEREF_LOCALNAME, NODEREF_QNAME.toPrefixString(), null, nodeRef.toString()); } if (childName != null) { attrs.addAttribute( NamespaceService.REPOSITORY_VIEW_1_0_URI, CHILDNAME_LOCALNAME, CHILDNAME_QNAME.toPrefixString(), null, childName.toPrefixString(namespaceService)); } contentHandler.startElement( REFERENCE_QNAME.getNamespaceURI(), REFERENCE_LOCALNAME, toPrefixString(REFERENCE_QNAME), attrs); } catch (SAXException e) { throw new ExporterException("Failed to process start reference", e); } }
/** * Return relative path between from and to references within export root * * @param fromRef from reference * @param toRef to reference * @return path */ private Path createPath(NodeRef rootRef, NodeRef fromRef, NodeRef toRef) { // Check that item exists first if (!nodeService.exists(toRef)) { // return null path return null; } // Check whether item is the root node of the store // If so, always return absolute path if (toRef.equals(nodeService.getRootNode(toRef.getStoreRef()))) { return nodeService.getPath(toRef); } // construct relative path Path rootPath = createIndexedPath(rootRef, nodeService.getPath(rootRef)); Path fromPath = createIndexedPath(fromRef, nodeService.getPath(fromRef)); Path toPath = createIndexedPath(toRef, nodeService.getPath(toRef)); Path relativePath = null; try { // Determine if 'to path' is a category // TODO: This needs to be resolved in a more appropriate manner - special support is // required for categories. for (int i = 0; i < toPath.size(); i++) { Path.Element pathElement = toPath.get(i); if (pathElement.getPrefixedString(namespaceService).equals("cm:categoryRoot")) { Path.ChildAssocElement childPath = (Path.ChildAssocElement) pathElement; relativePath = new Path(); relativePath.append( new Path.ChildAssocElement( new ChildAssociationRef(null, null, null, childPath.getRef().getParentRef()))); relativePath.append(toPath.subPath(i + 1, toPath.size() - 1)); break; } } if (relativePath == null) { // Determine if from node is relative to export tree int i = 0; while (i < rootPath.size() && i < fromPath.size() && rootPath.get(i).equals(fromPath.get(i))) { i++; } if (i == rootPath.size()) { // Determine if to node is relative to export tree i = 0; while (i < rootPath.size() && i < toPath.size() && rootPath.get(i).equals(toPath.get(i))) { i++; } if (i == rootPath.size()) { // build relative path between from and to relativePath = new Path(); for (int p = 0; p < fromPath.size() - i; p++) { relativePath.append(new Path.ParentElement()); } if (i < toPath.size()) { relativePath.append(toPath.subPath(i, toPath.size() - 1)); } } } } if (relativePath == null) { // default to absolute path relativePath = toPath; } } catch (Throwable e) { String msg = "Failed to determine relative path: root path=" + rootPath + "; from path=" + fromPath + "; to path=" + toPath; throw new ExporterException(msg, e); } return relativePath; }
/* (non-Javadoc) * @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable) */ public void value(NodeRef nodeRef, QName property, Object value, int index) { try { // determine data type of value QName valueDataType = null; PropertyDefinition propDef = dictionaryService.getProperty(property); DataTypeDefinition dataTypeDef = (propDef == null) ? null : propDef.getDataType(); if (dataTypeDef == null || dataTypeDef.getName().equals(DataTypeDefinition.ANY)) { dataTypeDef = (value == null) ? null : dictionaryService.getDataType(value.getClass()); if (dataTypeDef != null) { valueDataType = dataTypeDef.getName(); } } // convert node references to paths if (value instanceof NodeRef && referenceType.equals(ReferenceType.PATHREF)) { NodeRef valueNodeRef = (NodeRef) value; if (nodeRef.getStoreRef().equals(valueNodeRef.getStoreRef())) { Path nodeRefPath = createPath(context.getExportOf(), nodeRef, valueNodeRef); value = (nodeRefPath == null) ? null : nodeRefPath.toPrefixString(namespaceService); } } // output value wrapper if value is null or property data type is ANY or value is part of // collection if (value == null || valueDataType != null || index != -1) { AttributesImpl attrs = new AttributesImpl(); if (value == null) { attrs.addAttribute( NamespaceService.REPOSITORY_VIEW_PREFIX, ISNULL_LOCALNAME, ISNULL_QNAME.toPrefixString(), null, "true"); } if (valueDataType != null) { attrs.addAttribute( NamespaceService.REPOSITORY_VIEW_PREFIX, DATATYPE_LOCALNAME, DATATYPE_QNAME.toPrefixString(), null, toPrefixString(valueDataType)); } contentHandler.startElement( NamespaceService.REPOSITORY_VIEW_PREFIX, VALUE_LOCALNAME, toPrefixString(VALUE_QNAME), attrs); } // output value String strValue = (String) DefaultTypeConverter.INSTANCE.convert(String.class, value); if (strValue != null) { for (int i = 0; i < strValue.length(); i++) { char[] temp = new char[] {strValue.charAt(i)}; contentHandler.characters(temp, 0, 1); } } // output value wrapper if property data type is any if (value == null || valueDataType != null || index != -1) { contentHandler.endElement( NamespaceService.REPOSITORY_VIEW_PREFIX, VALUE_LOCALNAME, toPrefixString(VALUE_QNAME)); } } catch (SAXException e) { throw new ExporterException( "Failed to process value event - nodeRef " + nodeRef + "; property " + toPrefixString(property) + "; value " + value, e); } }
protected Set<String> getPaths(boolean primaryOnly) throws AfException { if (isNew()) { throw new AfException("this object is new, you can not get any paths"); } if (!nodeRef.getStoreRef().equals(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)) { throw new AfException("you cannot query the object's paths that is not in workspace"); } NodeService nodeService = ServiceHelper.getNodeService(afSession); List<Path> ps = nodeService.getPaths(nodeRef, primaryOnly); Set<String> paths = new HashSet<String>(); // NodeRef parent = AFCHelper.getNodeRefByPath(afSession, "/"); for (Path p : ps) { StringBuffer realPath = new StringBuffer(); int length = p.size(); for (int i = 0; i < length; i++) { QName qname = QName.createQName(p.get(i).getElementString()); String fname = qname.getLocalName(); if (fname.equals("/") || fname.equals("company_home")) { continue; } else if ("system".equals(fname) && i == 1) { break; } realPath.append('/'); if (i == length - 1) { realPath.append(getObjectName()); } else { realPath.append(ISO9075.decode(fname)); } } if (realPath.length() != 0) { paths.add(realPath.toString()); } } // for (Path p : ps) { // // NodeRef tmpParent = parent; // // String realPath = ""; // for (int i = 0; i < p.size(); i++) { // QName qname = QName.createQName(p.get(i).getElementString()); // String fname = qname.getLocalName(); // // if (fname.equals("/") || fname.equals("company_home")) { // continue; // } // // String name = ISO9075.decode(fname); // // tmpParent = getChildByAssName(nodeService, tmpParent, name); // // if (tmpParent == null) { // break; // } // // realPath += "/" + getNodeName(nodeService, tmpParent); // // } // // if (!realPath.equals("")) { // paths.add(realPath); // } // // } return paths; }
/** * Returns a list of NodeRefs representing the deployment servers configured for the given web * project. * * @param webProject Web project to get test servers for * @param live * @param availableOnly if true only returns those servers still available for deployment * @return List of test servers */ private static List<NodeRef> findServers( NodeRef webProject, boolean live, boolean availableOnly) { FacesContext context = FacesContext.getCurrentInstance(); NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); SearchService searchService = Repository.getServiceRegistry(context).getSearchService(); NamespacePrefixResolver namespacePrefixResolver = Repository.getServiceRegistry(context).getNamespaceService(); Path projectPath = nodeService.getPath(webProject); String stringPath = projectPath.toPrefixString(namespacePrefixResolver); StringBuilder query = new StringBuilder("PATH:\""); query.append(stringPath); query.append("/*\" "); query.append(" AND @"); query.append(NamespaceService.WCMAPP_MODEL_PREFIX); query.append("\\:"); query.append(WCMAppModel.PROP_DEPLOYSERVERTYPE.getLocalName()); query.append(":\""); if (live) { query.append(WCMAppModel.CONSTRAINT_LIVESERVER); } else { query.append(WCMAppModel.CONSTRAINT_TESTSERVER); } query.append("\""); // if required filter the test servers if (live == false && availableOnly) { query.append(" AND ISNULL:\""); query.append(WCMAppModel.PROP_DEPLOYSERVERALLOCATEDTO.toString()); query.append("\""); } if (logger.isDebugEnabled()) logger.debug("Finding deployment servers using query: " + query.toString()); // execute the query ResultSet results = null; List<NodeRef> servers = new ArrayList<NodeRef>(); try { results = searchService.query( Repository.getStoreRef(), SearchService.LANGUAGE_LUCENE, query.toString()); if (logger.isDebugEnabled()) logger.debug("Found " + results.length() + " deployment servers"); for (NodeRef server : results.getNodeRefs()) { servers.add(server); } } finally { if (results != null) { results.close(); } } return servers; }
/** {@inheritDoc} */ public void getNodesMetadata( NodeMetaDataParameters nodeMetaDataParameters, MetaDataResultsFilter resultFilter, NodeMetaDataQueryCallback callback) { if (false == enabled) { return; } NodeMetaDataQueryRowHandler rowHandler = new NodeMetaDataQueryRowHandler(callback); boolean includeType = (resultFilter == null ? true : resultFilter.getIncludeType()); boolean includeProperties = (resultFilter == null ? true : resultFilter.getIncludeProperties()); boolean includeAspects = (resultFilter == null ? true : resultFilter.getIncludeAspects()); boolean includePaths = (resultFilter == null ? true : resultFilter.getIncludePaths()); boolean includeNodeRef = (resultFilter == null ? true : resultFilter.getIncludeNodeRef()); boolean includeParentAssociations = (resultFilter == null ? true : resultFilter.getIncludeParentAssociations()); boolean includeChildAssociations = (resultFilter == null ? true : resultFilter.getIncludeChildAssociations()); boolean includeOwner = (resultFilter == null ? true : resultFilter.getIncludeOwner()); boolean includeChildIds = (resultFilter == null ? true : resultFilter.getIncludeChildIds()); boolean includeTxnId = (resultFilter == null ? true : resultFilter.getIncludeTxnId()); List<Long> nodeIds = preCacheNodes(nodeMetaDataParameters); for (Long nodeId : nodeIds) { Status status = nodeDAO.getNodeIdStatus(nodeId); if (status == null) { // We've been called with the ID of a purged node, probably due to processing a transaction // with a // cascading delete. Fine to skip and assume it will be processed in a transaction. // See org.alfresco.solr.tracker.CoreTracker.updateDescendantAuxDocs(NodeMetaData, boolean, // SolrIndexSearcher) continue; } NodeRef nodeRef = status.getNodeRef(); NodeMetaData nodeMetaData = new NodeMetaData(); nodeMetaData.setNodeId(nodeId); if (includeNodeRef) { nodeMetaData.setNodeRef(tenantService.getBaseName(nodeRef, true)); } if (includeTxnId) { nodeMetaData.setTxnId(status.getDbTxnId()); } if (status.isDeleted()) { rowHandler.processResult(nodeMetaData); continue; } Map<QName, Serializable> props = null; Set<QName> aspects = null; nodeMetaData.setAclId(nodeDAO.getNodeAclId(nodeId)); if (includeType) { QName nodeType = getNodeType(nodeId); if (nodeType != null) { nodeMetaData.setNodeType(nodeType); } else { throw new AlfrescoRuntimeException("Nodes with no type are ignored by SOLR"); } } if (includeProperties) { if (props == null) { props = getProperties(nodeId); } nodeMetaData.setProperties(props); } else { nodeMetaData.setProperties(Collections.<QName, Serializable>emptyMap()); } if (includeAspects || includePaths || includeParentAssociations) { aspects = getNodeAspects(nodeId); } nodeMetaData.setAspects(aspects); boolean ignoreLargeMetadata = (typeIndexFilter.shouldBeIgnored(getNodeType(nodeId)) || aspectIndexFilter.shouldBeIgnored(getNodeAspects(nodeId))); if (!ignoreLargeMetadata && (typeIndexFilter.isIgnorePathsForSpecificTypes() || aspectIndexFilter.isIgnorePathsForSpecificAspects())) { // check if parent should be ignored final List<Long> parentIds = new LinkedList<Long>(); nodeDAO.getParentAssocs( nodeId, null, null, true, new ChildAssocRefQueryCallback() { @Override public boolean preLoadNodes() { return false; } @Override public boolean orderResults() { return false; } @Override public boolean handle( Pair<Long, ChildAssociationRef> childAssocPair, Pair<Long, NodeRef> parentNodePair, Pair<Long, NodeRef> childNodePair) { parentIds.add(parentNodePair.getFirst()); return false; } @Override public void done() {} }); if (!parentIds.isEmpty()) { Long parentId = parentIds.iterator().next(); if (typeIndexFilter.isIgnorePathsForSpecificTypes()) { QName parentType = getNodeType(parentId); ignoreLargeMetadata = typeIndexFilter.shouldBeIgnored(parentType); } if (!ignoreLargeMetadata && aspectIndexFilter.isIgnorePathsForSpecificAspects()) { ignoreLargeMetadata = aspectIndexFilter.shouldBeIgnored(getNodeAspects(parentId)); } } } CategoryPaths categoryPaths = new CategoryPaths( new ArrayList<Pair<Path, QName>>(), new ArrayList<ChildAssociationRef>()); if (!ignoreLargeMetadata && (includePaths || includeParentAssociations)) { if (props == null) { props = getProperties(nodeId); } categoryPaths = getCategoryPaths(status.getNodeRef(), aspects, props); } if (includePaths && !ignoreLargeMetadata) { if (props == null) { props = getProperties(nodeId); } List<Path> directPaths = nodeDAO.getPaths(new Pair<Long, NodeRef>(nodeId, status.getNodeRef()), false); Collection<Pair<Path, QName>> paths = new ArrayList<Pair<Path, QName>>(directPaths.size() + categoryPaths.getPaths().size()); for (Path path : directPaths) { paths.add(new Pair<Path, QName>(path.getBaseNamePath(tenantService), null)); } for (Pair<Path, QName> catPair : categoryPaths.getPaths()) { paths.add( new Pair<Path, QName>( catPair.getFirst().getBaseNamePath(tenantService), catPair.getSecond())); } nodeMetaData.setPaths(paths); // Calculate name path Collection<Collection<String>> namePaths = new ArrayList<Collection<String>>(2); nodeMetaData.setNamePaths(namePaths); for (Pair<Path, QName> catPair : paths) { Path path = catPair.getFirst(); boolean added = false; List<String> namePath = new ArrayList<String>(path.size()); NEXT_ELEMENT: for (Path.Element pathElement : path) { if (!(pathElement instanceof ChildAssocElement)) { // This is some path element that is terminal to a cm:name path break; } ChildAssocElement pathChildAssocElement = (ChildAssocElement) pathElement; NodeRef childNodeRef = pathChildAssocElement.getRef().getChildRef(); Pair<Long, NodeRef> childNodePair = nodeDAO.getNodePair(childNodeRef); if (childNodePair == null) { // Gone break; } Long childNodeId = childNodePair.getFirst(); String childNodeName = (String) nodeDAO.getNodeProperty(childNodeId, ContentModel.PROP_NAME); if (childNodeName == null) { // We have hit a non-name node, which acts as a root for cm:name // DH: There is no particular constraint here. This is just a decision made. namePath.clear(); // We have to continue down the path as there could be a name path lower down continue NEXT_ELEMENT; } // We can finally add the name to the path namePath.add(childNodeName); // Add the path if this is the first entry in the name path if (!added) { namePaths.add(namePath); added = true; } } } } nodeMetaData.setTenantDomain(tenantService.getDomain(nodeRef.getStoreRef().getIdentifier())); if (includeChildAssociations) { final List<ChildAssociationRef> childAssocs = new ArrayList<ChildAssociationRef>(100); nodeDAO.getChildAssocs( nodeId, null, null, null, null, null, new ChildAssocRefQueryCallback() { @Override public boolean preLoadNodes() { return false; } @Override public boolean orderResults() { return false; } @Override public boolean handle( Pair<Long, ChildAssociationRef> childAssocPair, Pair<Long, NodeRef> parentNodePair, Pair<Long, NodeRef> childNodePair) { boolean addCurrentChildAssoc = true; if (typeIndexFilter.isIgnorePathsForSpecificTypes()) { QName nodeType = nodeDAO.getNodeType(childNodePair.getFirst()); addCurrentChildAssoc = !typeIndexFilter.shouldBeIgnored(nodeType); } if (!addCurrentChildAssoc && aspectIndexFilter.isIgnorePathsForSpecificAspects()) { addCurrentChildAssoc = !aspectIndexFilter.shouldBeIgnored(getNodeAspects(childNodePair.getFirst())); } if (addCurrentChildAssoc) { childAssocs.add(tenantService.getBaseName(childAssocPair.getSecond(), true)); } return true; } @Override public void done() {} }); nodeMetaData.setChildAssocs(childAssocs); } if (includeChildIds) { final List<Long> childIds = new ArrayList<Long>(100); nodeDAO.getChildAssocs( nodeId, null, null, null, null, null, new ChildAssocRefQueryCallback() { @Override public boolean preLoadNodes() { return false; } @Override public boolean orderResults() { return false; } @Override public boolean handle( Pair<Long, ChildAssociationRef> childAssocPair, Pair<Long, NodeRef> parentNodePair, Pair<Long, NodeRef> childNodePair) { boolean addCurrentId = true; if (typeIndexFilter.isIgnorePathsForSpecificTypes()) { QName nodeType = nodeDAO.getNodeType(childNodePair.getFirst()); addCurrentId = !typeIndexFilter.shouldBeIgnored(nodeType); } if (!addCurrentId) { addCurrentId = !aspectIndexFilter.shouldBeIgnored(getNodeAspects(childNodePair.getFirst())); } if (addCurrentId) { childIds.add(childNodePair.getFirst()); } return true; } @Override public void done() {} }); nodeMetaData.setChildIds(childIds); } if (includeParentAssociations && !ignoreLargeMetadata) { final List<ChildAssociationRef> parentAssocs = new ArrayList<ChildAssociationRef>(100); nodeDAO.getParentAssocs( nodeId, null, null, null, new ChildAssocRefQueryCallback() { @Override public boolean preLoadNodes() { return false; } @Override public boolean orderResults() { return false; } @Override public boolean handle( Pair<Long, ChildAssociationRef> childAssocPair, Pair<Long, NodeRef> parentNodePair, Pair<Long, NodeRef> childNodePair) { parentAssocs.add(tenantService.getBaseName(childAssocPair.getSecond(), true)); return true; } @Override public void done() {} }); for (ChildAssociationRef ref : categoryPaths.getCategoryParents()) { parentAssocs.add(tenantService.getBaseName(ref, true)); } CRC32 crc = new CRC32(); for (ChildAssociationRef car : parentAssocs) { try { crc.update(car.toString().getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException("UTF-8 encoding is not supported"); } } nodeMetaData.setParentAssocs(parentAssocs, crc.getValue()); // TODO non-child associations // Collection<Pair<Long, AssociationRef>> sourceAssocs = // nodeDAO.getSourceNodeAssocs(nodeId); // Collection<Pair<Long, AssociationRef>> targetAssocs = // nodeDAO.getTargetNodeAssocs(nodeId); // // nodeMetaData.setAssocs(); } if (includeOwner) { // cached in OwnableService nodeMetaData.setOwner(ownableService.getOwner(status.getNodeRef())); } rowHandler.processResult(nodeMetaData); } }