In the following example we will see how to implement a custom node locator, it will allow a named folder to be found. To define the example node locator the following Spring configuration is used (in a custom context file):
<beanid="namedFolderNodeLocator"class="com.example.NamedFolderNodeLocator"parent="baseNodeLocator"> <property name="NodeService" ref="NodeService" /> <property name="FileFolderService" ref="FileFolderService" /> </bean>
A node locator must implement the NodeLocator interface, whose definition is shown below:
publicinterfaceNodeLocator { NodeRef getNode(NodeRef source, Map<String, Serializable> params); public List<ParameterDefinition> getParameterDefinitions(); }
A NodeLocator in its simplest form takes a source node, some optional parameters and returns a node or null if a suitable node could not be found. If a node is not found the NodeLocatorService returns the NodeRef representing the /Company Home folder.
The source node is not mandatory, node locators can be used to return well known nodes, /Company Home, /User Home for example in which case a source node is not required.
If a NodeLocator has parameters they must be defined using the same definition classes (ParameterDefinition) used by the ActionService.
A base class AbstractNodeLocator is provided and it’s recommended that your NodeLocator extends this base class. It provides the functionality to register the NodeLocator with the NodeLocatorService registry. This class also defines an abstract method your implementation must override.
publicabstract String getName();
This is the unique name for your NodeLocator and will be used by the NodeLocatorService in the lookup process. It is also used in the startLocation configuration.
Our example locator, NamedFolderNodeLocator, will be named namedfolder and will expect a single parameter called name which will indicate what folder to locate. The full source for this example is shown below:
publicclassNamedFolderNodeLocatorextendsAbstractNodeLocator { publicstaticfinal String LOCATOR_NAME = "namedfolder"; publicstaticfinal String NAME_PARAM = "name"; private ServiceRegistry serviceRegistry; @Override public NodeRef getNode(NodeRef source, Map<String, Serializable> params) { NodeRef node = null; String folderName = (String)params.get(NAME_PARAM); if (source != null && folderName != null) { // Get the parent of the source node NodeRef parent = serviceRegistry.getNodeService().getPrimaryParent(source).getParentRef(); // Look for a child with the provided name NodeRef folder = serviceRegistry.getNodeService()NodeService().getChildByName( parent, ContentModel.ASSOC_CONTAINS, folderName); // Make sure it's a folder if (folder != null && serviceRegistry.getFileFolderService().getFileInfo(folder).isFolder()) { node = folder; } } return node; } public List<ParameterDefinition> getParameterDefinitions() { List<ParameterDefinition> paramDefs = new ArrayList<ParameterDefinition>(2); paramDefs.add(new ParameterDefinitionImpl(NAME_PARAM, DataTypeDefinition.TEXT, false, "Name")); return paramDefs; } public String getName() { return LOCATOR_NAME; } }
The "source" parameter in getNode() represents the starting point, in a form association control this will be the node being edited, for a create form it will be the destination node. Our example finds the primary parent of the source node and looks for a child folder with the given name. This is a fairly simple example but it is easy to see how this could be extended to allow for a named folder to be located up or down a folder hierarchy.
startLocation:
The main use of the NodeLocatorService is to determine where the forms association control should start when it is first displayed. In some scenarios the picker may need to start in the root of the document library of a Share site or start in the folder where the node being edited is located. See the next section for a list of NodeLocators provided out-of-the-box.
NodeLocators are configured using form control parameters. The name of the NodeLocator implementation is provided as the startLocation parameter and the parameters are provided by a startLocationParameters parameter. They should be provided in the form of query string parameters, for example name=value&name=value.
The configuration for our example node locator is shown below, it will look for a folder named “Example” in the same folder as the node being edited.
<fieldid="my:association"> <control> <control-param name="startLocation">{namedfolder}</control-param> <control-param name="startLocationParams">name=Example</control-param> </control> </field>