Alfresco WCM Forms: Unique Identifier

From time to time I’ve seen the need to provide a unique identifier in content created through the Alfresco WCM Forms Service.  The reason why has varied from needing an unique identifier across renditions to needing a way to tie the content to User Generated Content (UGC) or some other database managed application. A simple solution is to leverage Java generated [Universally Unique Identifiers][1] (UUID) imported into the [Schema Definition of your form][2] via a [Java Backed Web Script][3]. **Note: **These are not the UUIDs used by Alfresco DM.  UUIDs are not available/part of the AVM/WCM model used by Alfresco.

Java Backed Web Scripts provide a powerful way to include complex business process logic, enabling integrations through the [Alfresco Web Script framework][4] using a simple HTTP based API.  In this case, we are using a simple Java class to generate a UUID and then returning that UUID wrapped in a XML Scheme Definition imported through a into a Schema Definition used to generate a form used to capture content in Alfresco’s WCM service.

First let’s tackle the Java portion.  This is a simple Java class that extends the Alfresco [DeclarativeWebScript][5] class. A Declarative Web Script allows you to mix Java classes, Freemarker templates (FTL) and Javascript.  In this case we a want to leverage a FTL, which generates the XSD for the return.  Here is the meat of our class:

public class UUIDWebScript extends DeclarativeWebScript<br /> {

@Override<br /> protected Map executeImpl(WebScriptRequest req,<br /> Status status, Cache cache)<br /> {

Map model = new HashMap();

`</p>

UUID uuid = UUID.randomUUID();

model.put("uuid", uuid.toString());

return model;

}

`

}

Basically, * Create a `map` of properties you want to return (by coding conventions this is called a model). * Perform your business logic, in our case generate a UUID. * Add the values you want to return to the template with a unique name to identify it in the template * Return the map of properties Next we want to format our return.  This is done using a Freemarker Template . ([Freemarker][6] is a Java Based markup language.) Here is ours:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"<br /> xmlns:alfresco="http://www.alfresco.org/alfresco"<br /> elementFormDefault="qualified">

<xs:complexType name="uuid">

<xs:sequence>

<xs:element name="uuid" fixed="${uuid}" type="xs:normalizedString"/>

</xs:sequence>

</xs:complexType>

</xs:schema><br />

The FTL, as you can see , is a simple XSD.  The value returned from our Java class, in the model, named uuid, is declared as ${uuid}. Now let’s declare the web script so that it can be registered in Alfresco:

<webscript>

<shortname>Generate UUID</shortname><br /> <description>Returns a UUID</description><br /> <url>/util/uuid</url><br /> <authentication>none</authentication><br /> <format default="xml">argument</format>

</webscript>

And since we are using a Java class in our Web Script, we also need to declare it so that the Web Script framework can use it:

<?xml version="1.0" encoding="UTF-8"?><br /> <beans xmlns="http://www.springframework.org/schema/beans"<br /> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br /> xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

`

<bean id="webscript.org.alfresco.extension.uuid.uuid.get"
class="org.alfresco.extension.uuid.UUIDWebScript"
parent="webscript">
</bean>

`

</beans>

It is important to note here that the bean id for a Java backed Web Script requires a very specific format: * Start by declaring this bean a webscript with: webscript. * Next add the full Java package declaration: org.alfresco.extension.uuid * Followed by the name used in your FTL and XML declaration with the method used to access the web script: uuid.get * When packaged, the FTL and XML declaration must be in a folder structure that matches the Java package declaration. This puts together all of the pieces on the Web Script side.  It is easiest to manage this through an [AMP file][7], which we won’t discuss here how to create or install, but [code][8] and [amp file][9] are available at the project page: <http://code.google.com/p/alfresco-uuid-webscript/> Once installed we can verify that it works by going to http://localhost:8080/alfresco/service/util/uuid in your browser (replace localhost and port as needed for your install).  What you should see returned is an XSD that looks something like this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"<br /> xmlns:alfresco="http://www.alfresco.org/alfresco"<br /> elementFormDefault="qualified">

`

</p>

</p>

</xs:sequence>

</xs:complexType>

`

</xs:schema>

It is our template but with are declaration of ${uuid} replaced with aUUID: 9c2fce39-3351-47c9-bb05-4b002967a00d.  With each call to this  Web Script you will see a uniquely generated ID. Now let’s integrate this with a simple XSD:

<?xml version="1.0" encoding="UTF-8"?><br /> <xs:schema<br /> xmlns:alf="http://www.alfresco.org"<br /> xmlns:xs="http://www.w3.org/2001/XMLSchema"<br /> xmlns:sample="http://www.alfresco.org/alfresco/sample"<br /> elementFormDefault="qualified"<br /> targetNamespace="http://www.alfresco.org/alfresco/sample">

<xs:include schemaLocation="webscript://util/uuid" />

<xs:element name="sample">

</p> <p style="padding-left: 30px"><xs:complexType></p> <p style="padding-left: 60px"><xs:sequence></p> <p style="padding-left: 90px"><xs:element name="sample" type="xs:normalizedString" minOccurs="1" maxOccurs="1"/><br /> <xs:element name="key" type="sample:uuid"/></p> <p style="padding-left: 60px"></xs:sequence></p> <p style="padding-left: 30px"></xs:complexType></p> <p style="padding-left: 30px"></xs:element></p> <p>

</xs:schema>

The important thing here is how we reference the Web Script, and you can do this with any custom Web Script designed to render XML Schema to be included in a form,  by referencing the call with the declaration of webscript:

<xs:include schemaLocation="webscript://util/uuid" />

Add this XSD to your Web Project and give it a run! In the form you will see the UUID, as a read-only field.

UUID in Web Form

Now in your XML output you will have a unique key that you can reference in your templates.

[1]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier [2]: http://wiki.alfresco.com/wiki/Forms_Authoring_Guide [3]: http://wiki.alfresco.com/wiki/Web_Scripts#Java-Backed_Implementations [4]: http://wiki.alfresco.com/wiki/Web_Scripts [5]: http://dev.alfresco.com/resource/docs/java/web-client/org/alfresco/web/scripts/DeclarativeWebScript.html [6]: http://freemarker.org/ [7]: http://wiki.alfresco.com/wiki/AMP_Files [8]: http://code.google.com/p/alfresco-uuid-webscript/source/checkout [9]: http://alfresco-uuid-webscript.googlecode.com/files/alfresco-uuid-webscript.amp