Provides an API for managing nodes, such as folders and files. Nodes are the fundamental data structure in Content Services. All content that is stored is represented by a node data structure, which contains content metadata that is persisted in a database (such as PostgreSQL). The content referenced by the node is stored as a *.bin file in a content store (such as the file system, S3, encrypted or other content store).
Every node in the system is referenced by a NodeRef, which is made up of the content store protocol, the content store name, and the Universal Unique Identifier (UUID) of the content, for example: workspace://SpacesStore/ccb906ba-a768-4ccb-8b26-515119e1efdc. Generally nodes are of two main types, a file node (cm:content), or a folder node (cm:folder). Folders can contain child nodes. Note that each content store will have a root node, and all other nodes in the store will be children of the root node.
The NodeService provides an extensive API for managing nodes. Functionality includes:
- Adding aspects, children, properties, associations
- Getting aspects, children, properties, associations
- Removing aspects, children, properties, associations
- Creating and deleting stores
- Creating and deleting nodes
- Checking for existence of a node
- Get available content stores
- Moving nodes
The NodeService makes extensive use of NodeRefs to reference the node of interest.
Note that for creating folders and files you should also have a look at FileFolderService as it is an abstraction of the NodeService service that makes it a bit easier to work with folders and files with the cost of being less flexible.
Creating a file node:
NodeRef parentFolderNodeRef = serviceRegistry.getNodeLocatorService().getNode(CompanyHomeNodeLocator.NAME, null, null); // Create file node metadata QName associationType = ContentModel.ASSOC_CONTAINS; QName associationQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(filename)); Map<QName, Serializable> nodeProperties = new HashMap<QName, Serializable>(); nodeProperties.put(ContentModel.PROP_NAME, filename); ChildAssociationRef parentChildAssocRef = serviceRegistry.getNodeService().createNode( parentFolderNodeRef, associationType, associationQName, ContractType.QNAME, nodeProperties); NodeRef newFileNodeRef = parentChildAssocRef.getChildRef(); // Set text content for file node boolean updateContentPropertyAutomatically = true; ContentWriter writer = serviceRegistry.getContentService().getWriter( newFileNodeRef, ContentModel.PROP_CONTENT, updateContentPropertyAutomatically); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); writer.putContent(someText);
Creating a folder node:
privatevoidcreateFolder(NodeRef rootRef){ String folderName = "SampleFolder"; NodeRef parentFolderNodeRef = rootRef; // Create folder node QName associationType = ContentModel.ASSOC_CONTAINS; QName associationQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(folderName)); QName nodeType = ContentModel.TYPE_FOLDER; Map<QName, Serializable> nodeProperties = new HashMap<QName, Serializable>(); nodeProperties.put(ContentModel.PROP_NAME, folderName); ChildAssociationRef parentChildAssocRef = serviceRegistry.getNodeService().createNode( parentFolderNodeRef, associationType, associationQName, nodeType, nodeProperties); NodeRef newFolderNodeRef = parentChildAssocRef.getChildRef(); }
Add an aspect to a node:
NodeRef someNodeRef = ... Map<QName, Serializable> aspectProperties = new HashMap<QName, Serializable>(); aspectProperties.put(ContentModel.PROP_TITLE, "A title"); aspectProperties.put(ContentModel.PROP_DESCRIPTION, "A description"); serviceRegistry.getNodeService().addAspect(someNodeRef, ContentModel.ASPECT_TITLED, aspectProperties);
Getting a NodeRef from the node path:
StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); ResultSet rs = serviceRegistry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, "PATH:\"/app:company_home/app:user_homes/sys:boris/cm:mypics\""); NodeRef companyHomeNodeRef = null; try { if (rs.length() == 0) { thrownew AlfrescoRuntimeException("Didn't find Company Home"); } companyHomeNodeRef = rs.getNodeRef(0); } finally { rs.close(); }
Getting a file name from a NodeRef:
String fileName = (String) serviceRegistry.getNodeService().getProperty(nodeRef, ContentModel.PROP_NAME);
Reading a node property. The property may come from an aspect or not. You will probably want to cast to the appropriate type:
QName PROP_QNAME_MY_PROPERTY = QName.createQName("custom.model", "myProperty"); Object value = serviceRegistry.getNodeService().getProperty(nodeRef, PROP_QNAME_MY_PROPERTY);
Updating a node property. The property may come from an aspect or not:
QName PROP_QNAME_MY_PROPERTY = QName.createQName("custom.model", "myProperty"); serviceRegistry.getNodeService().setProperty(nodeRef, PROP_QNAME_MY_PROPERTY, value);
Getting the parent of a NodeRef:
ChildAssociationRef childAssociationRef = serviceRegistry.getNodeService().getPrimaryParent(nodeRef); NodeRef parentFolderNodeRef = childAssociationRef.getParentRef();
Adding an aspect to a node. Supposing the “MyAspect” aspect defines a “myProperty” property in the “custom.model” namespace:
QName CUSTOM_ASPECT_QNAME = QName.createQName("custom.model", "MyAspect"); QName PROP_QNAME_MY_PROPERTY = QName.createQName("custom.model", "myProperty"); Map<QName,Serializable> aspectValues = new HashMap<QName,Serializable>(); aspectValues.put(PROP_QNAME_MY_PROPERTY, value); serviceRegistry.getNodeService().addAspect(nodeRef, CUSTOM_ASPECT_QNAME, aspectValues);
Checking whether a node has a given aspect:
QName CUSTOM_ASPECT_QNAME = QName.createQName("custom.model", "MyAspect"); boolean hasAspect = serviceRegistry.getNodeService().hasAspect(node, CUSTOM_ASPECT_QNAME);
Looping through children of a NodeRef:
List<ChildAssociationRef> children = serviceRegistry.getNodeService().getChildAssocs(companyHome); for (ChildAssociationRef childAssoc : children) { NodeRef childNodeRef = childAssoc.getChildRef(); // Use childNodeRef here. }
Creating a parent-child association between two existing NodeRef:
QName PROP_QNAME_MY_CHILD_ASSOCIATION = QName.createQName("custom.model", "myChildAssociation"); serviceRegistry.getNodeService().addChild(parentNodeRef, childNodeRef, PROP_QNAME_MY_CHILD_ASSOCIATION, PROP_QNAME_MY_CHILD_ASSOCIATION);
Creating a peer-2-peer association between two existing NodeRef:
QName PROP_QNAME_MY_ASSOCIATION = QName.createQName("custom.model", "myAssociation"); serviceRegistry.getNodeService().createAssociation(sourceNodeRef, targetNodeRef, PROP_QNAME_MY_ASSOCIATION);
Setting the content type of a node:
QName PROP_QNAME_MY_TYPE = QName.createQName("custom.model", "myType"); serviceRegistry.getNodeService().setType(finalOriginal, MY_TYPE);
Getting the MIME type of a node:
ContentData contentData = (ContentData) serviceRegistry.getNodeService().getProperty(nodeRef, ContentModel.PROP_CONTENT); String originalMimeType = contentData.getMimetype();
Adding a category to a node:
ArrayList<NodeRef> categories = new ArrayList<NodeRef>(1); categories.add(categoryNode); if (!serviceRegistry.getNodeService().hasAspect(targetNode, ContentModel.ASPECT_GEN_CLASSIFIABLE) { HashMap<QName, Serializable> props = new HashMap<QName, Serializable>(); props.put(ContentModel.PROP_CATEGORIES, categories); serviceRegistry.getNodeService().addAspect(targetNode, ContentModel.ASPECT_GEN_CLASSIFIABLE, props); } else { serviceRegistry.getNodeService().setProperty(targetNode, ContentModel.PROP_CATEGORIES, categories); }
Getting the categories of a node:
List<NodeRef> categories = (List<NodeRef>) serviceRegistry.getNodeService().getProperty(nodeRef, ContentModel.PROP_CATEGORIES);
Deleting a node for real (not recycle bin):
serviceRegistry.getNodeService().addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY, null); serviceRegistry.getNodeService().deleteNode(nodeRef);
See also Content Stores.