Creating a custom metadata action

Once the development setup is done, we can start building custom metadata actions for Alfred Inflow.

Example scenario

For demo purposes, we introduce an example scenario. This scenario will make it easier to understand some Inflow principles and how they are coupled with Alfresco.

Alfresco document model

First we will create a document model for Alfresco. In this model we will define one document type. The document type is called inflow:inflowTestDocument. It has one text property (type d:text) called inflow:documentCode.

Purpose of the demo metadata action

The purpose of all metadata actions is uploading files with custom metadata to Alfresco. In this guide, we’ll create a metadata action that extracts the custom inflow:documentCode property out of the file name. Furthermore, the uploaded files will be uploaded to a folder with the name also extracted from the file name.

Implementing the Java class

Create a new class called InflowTutorialAction in package tutorial. As superclass choose eu.xenit.move2alf.core.action.Move2AlfReceivingAction with generic parameter <FileInfo>{=html}. Annotate your class with eu.xenit.move2alf.core.action.ClassInfo and provide the parameters classId, category and description.

@ClassInfo( classId = "InflowTutorialAction",
            category = ConfigurableObject.CAT_METADATA,
            description = "Tutorial metadata action")
public class InflowTutorialAction extends Move2AlfReceivingAction<FileInfo>{

Now we will implement the executeImpl method. This method is called once for every file that is processed by Alfred Inflow. It takes one parameter, a FileInfo. The FileInfo is a wrapper of the map object that is used as input for the action. To get data from the FileInfo object, you can use a key (like a normal map), or use the functions to fetch the property directly. The keys you can use are defined as constants in the Parameters class. Here is an overview:

  • Input:
Parameter Type Function Description
PARAM_FILE File getFile() The file that is currently being processed
  • Output:
Parameter Type Description
PARAM_NAMESPACE String The full namespace of the content type, enclosed by {}.
PARAM_CONTENTTYPE String The name of the content type, without prefix
PARAM_METADATA Map<Object, Object> A map containing the metadata, the key contains the name of the field without prefix
PARAM_RELATIVE_PATH String The subfolder where the file should be placed.

All output parameters are optional. If nothing is provided a cm:content file is created without custom metadata in a folder structure that mirrors the input folder.
More advanced parameters are not covered by this example. (ACLs, reporting, …)

First we will fetch the current file from the parameter map so we can get the filename:

File file = incoming.getFile();
String filename = file.getName();

Then we will set the content type to the new type we defined in the content model above:

 FileInfo outgoing = new FileInfo();
 outgoing.put(Parameters.PARAM_FILE, file);
 outgoing.put(Parameters.PARAM_NAMESPACE, "{http://www.xenit.eu/model/inflow/test/1.0}");
 outgoing.put(Parameters.PARAM_CONTENTTYPE, "inflowTestDocument");

Next we write the document code to the DocumentCode metadata field:

Map<String, String> metadata = new HashMap<>();
metadata.put("documentCode", filename.substring(5, 9));
outgoing.put(Parameters.PARAM_METADATA, metadata);

It is also possible to add metadata with multiple values. Therefor you can use a value of the java.util.Collection type, like a java.util.List:

metadata.put("someMultiValueProperty", Arrays.asList("value1", "value2"));

Lastly we will group the files in subfolders based on the first letter of the filename and send the new message to the next step in the pipeline:

outgoing.put(Parameters.PARAM_RELATIVE_PATH, filename.substring(0, 1));<br />sendMessage(outgoing);

The full code for “InflowTutorialAction” class is included with this tutorial.

Handling errors

There are 2 ways to handle errors. If your executeImpl method throws an exception, Alfred Inflow will catch it and generate an error message in the reporting. Throwing exceptions does stop execution of the executeImpl method right away. When you are developing an action that reads lines from a file and you encounter an exception in one of the lines, you might not want to stop execution. You probably want to report the error on that line and continue execution. This is possible in Alfred Inflow:

handleError(message, e) 
//The message is the argument of your executeImpl method and e is of type Exception
handleError(message, "This is what went wrong") 
//Instead of passing the exception, you can specify you own explanation

Calling these methods will put an extra line in the reporting.

Test

Create a job using your new action. Use the “input” folder that’s part of this tutorial as input folder. Run the job and verify if the files are loaded into Alfresco. Make sure the correct subfolders are created as expected and you can use the Node Browser to check if the document code is set in the metadata field.