April 20, 2024

Alfresco Data Model the project ADAMO

Often, I have to face problems related to Alfresco document management solutions. One in particular concerns the metadata management functionality implemented by Alfresco. In order to better explain this context, we take a look at the following use case.

1. Open the browser, login to Alfresco Explorer and insert a document.
2. The wizard will show a form where I can submit the name of the document and some other additional properties such as a description, title and the author’s name.
3. At the end of the wizard, Alfresco stored my document and all its meta-information.

Alfresco Add Content form

Alfresco Content Properties

The default Alfresco document properties (title, description, author, etc. . ) are very useful and allow the user to perform advanced filtered searches into the repository (for example you can search the author or the title of a novel). But what happens if the user stores documents related to the company business like invoices or medical records rather then books or novels ?
A invoice does not have an “author” property but rather an identification number, a registry reference , a rateable number, and many other meta-data.
A very interesting aspect of Alfresco is precisely the possibility of extending its model of data using the “Custom Content Model ” concept.
A Content Model is a collection of types and aspects that define a custom template of data into the Alfresco Repository Data Dictionary .
Uploading  a well-formed xml file in the Data Dictionary, it is possible to extend the “Base Model” properties of Alfresco adding custom data . Here’s an example.

<?xml version="1.0" encoding="UTF-8"?> 
<model name="inv:invoiceModel" xmlns="http://www.alfresco.org/model/dictionary/1.0"> 
<description>Custom Content Model INVOICE</description> 
<author>FooSoft.com </author> 
<version>1.0</version> 
<imports> 
    <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" /> 
    <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" /> 
</imports> 
<namespaces> 
    <namespace uri="http://www.foosoft.com/model/content/1.0" prefix="inv" /> 
</namespaces> 
<types> 
    <type name="inv:invoice"> 
        <title>Invoice</title> 
        <parent>cm:content</parent> 
        <properties> 
               <property name="inv:number"> 
                <title>Number</title> 
                  <type>d:text</type> 
                  <mandatory>true</mandatory> 
            </property> 
            <property name="inv:date"> 
                <title>Date/title> 
                <type>d:date</type> 
                <mandatory>true</mandatory> 
            </property> 
            <property name="inv:shipTo"> 
                <title>Ship to</title> 
                <type>d:text</type> 
                <mandatory>true</mandatory> 
            </property> 
            <property name="inv:totalPrice"> 
                <title>Total price</title> 
                <type>d:text</type> 
                <mandatory>true</mandatory> 
            </property> 
           </properties> 
    </type/ 
</types>

I will not provide a deep explanation of the Content Model, further details and information can be found here.

ADAMO Project

The Adamo project borns as a extension tool for Alfresco custom model management. Adamo stands for Alfresco DAta MOdel, a open source project written in java that allows a user­ friendly creation of custom model data in Alfresco. Integrating Java, the WebScript Restful API provided by Alfresco and the Spring Surf technology, Adamo exposes a web front-end allowing an easier and more intuitive management of custom model in Alfresco. Rather than manually create the xml data model file related to the company business model (a file that is being uploaded to Alfresco and configured to be displayed on the Web Explorer), you can enter and edit your data types and properties directly using the Adamo web interface. The Adamo project consists of  two components:
Adamo-core
Adamo-surf

Adamo-Core

Adamo-core implements the service layer required to produce the interface with Alfresco Repository Data Dictionary. A set of webscripts java-backed allow you to manage the CRUD of the Custom Model. The object com.adamo.service.DataModelService provides access to the content meta-data into the Alfresco Data Dictionary. Follows an extract of its implementation for the creation of a Custom Type.

public class DataModelServiceImpl implements DataModelService {

private static final String MODEL_FILE_NAME= "InvoiceModel.xml";

public void createType(String name, String description, String parentName, String title){
M2Model m2mod=getRepoM2Model(MODEL_FILE_NAME);
if (m2mod==null) {
//create M2Model instance
m2mod= M2Model.createModel("inv:invoiceModel");
m2mod.setDescription("My Custom Model");
m2mod.setAuthor("foo");
m2mod.setVersion("1.0");
m2mod.createNamespace("http://www.foosoft.com/model/content/1.0", "foo");
m2mod.createImport(NamespaceService.DICTIONARY_MODEL_1_0_URI, NamespaceService.DICTIONARY_MODEL_PREFIX);
m2mod.createImport(NamespaceService.SYSTEM_MODEL_1_0_URI, NamespaceService.SYSTEM_MODEL_PREFIX);
m2mod.createImport(NamespaceService.CONTENT_MODEL_1_0_URI, NamespaceService.CONTENT_MODEL_PREFIX);
}
M2Type m2type=m2mod.createType(name);
m2type.setParentName(parentName);
m2type.setDescription(description);
m2type.setTitle(title);

registerM2Model(m2mod);
}      }

The default response format for the webscript is atom. Here the descriptor createtype.get.desc.xml for the creating of a Custom Type.

<webscript>
<shortname>Create Type webscript</shortname>
<description>Create type webscript</description>
<url>/adamo/createtype?name={name}&description={description?}&title={title?}</url>
<args>
<arg>
<shortname>name</shortname>
<description>The name of the type (prefix:name)</description>
</arg>
<arg>
<shortname>description</shortname>
<description>The description of the type</description>
</arg>
<arg>
<shortname>title</shortname>
<description>The title of the type</description>
</arg>
</args>
<authentication>user</authentication>
<format default="atom">argument</format>
</webscript>

The java-backed component of the webscript is instead the object org.alfresco.module.adamo.CreateTypeScript. In its implementation, the object CreateTypeScript extends the Alfresco DeclarativeWebScript class.. The serivce layer com.adamo.service.DataModelService stores the meta-data in the Repository Data Dictionary. Here is an excerpt of code.

public class CreateTypeScript extends DeclarativeWebScript
{
	private static final String PARENT_TYPE_NAME= "inv:invoiceModel";
	private static final String LAST_UPDATE_KEY= "lastUpdated";

	/** DataModel service */
	protected DataModelService dataModelService;
	HttpServletRequest httpReq = ((WebScriptServletRequest)req).getHttpServletRequest();
	String name = httpReq.getParameter("name");
	String description = httpReq.getParameter("description");
	String title = httpReq.getParameter("title");

	// Using DataModelService to create a custom type
	dataModelService.createType(name,description,PARENT_TYPE_NAME,title);
	return model;		 
	}
}

 

Adamo-Surf

Adamo-surf is the front-end, a web application developed using Spring Surf, the same technology used for Alfresco Share. Spring-Surf was originally developed by Alfresco and has now been offered as a contribution to the Spring open source community under the Apache License version 2.0. It is basically a framework for developing Java web application based on a componentized views. Spring Surf provides  developers with a set of useful libraries, including Web Scripts, that allow to create REST-based remote script. Here are some links where you can find more details and information:

Adamo-surf uses the mechanism of componentized views to define the page layout and makes it available dynamically through a series of webscripts REST calls. The layout of the web pages looks like this.
surf-01 adamo-layout

This development concept based on the componentization of the elements of a web page defines some prerogatives:
– Header, Footer, Side Horznav must have Global scope and generally represent the static part of all site web pages;
– The body section containing the list of data, has a scope of type Page and generally holds all web contents that dynamically change (forms, lists, etc).

Using the Spring-Surf technology, each view can be achieved through the definition of a XML file. Here are the ones that define the components of the web page shown above.

<!-- Component Header -->
<?xml version='1.0' encoding='UTF-8'?>
<component>
<scope>global</scope>
<region-id>header</region-id>
<url>/company/header</url>
</component>

<!-- Component Footer-->
<?xml version='1.0' encoding='UTF-8'?>
<component>
<scope>global</scope>
<region-id>footer</region-id>
<url>/company/footer</url>
</component>

<!-- Component Horznav -->
<?xml version='1.0' encoding='UTF-8'?>
<component>
<scope>global</scope>
<region-id>horznav</region-id>
<url>/navigation/horizontal</url>
</component>

<!-- Component Side -->
<?xml version='1.0' encoding='UTF-8'?>
<component>
<scope>global</scope>
<region-id>side</region-id>
<url>/navigation/side</url>
</component>

<!-- Component customModel -->
<?xml version='1.0' encoding='UTF-8'?>
<component>
<scope>page</scope>
<region-id>main</region-id>
<source-id>customModel</source-id>
<url>/customModel/main</url>
</component>

The tag <url> in the descriptor file defines the url to retrieve the view of the related component. The file system path is webscripts/com/adamo/customModel / and here the descriptor main.get.desc.xml

<webscript>
<shortname>Custom Model Main Section</shortname>
<description>Custom Model Page - Call Alfresco /adamo/types webscript to retrieve a custom model </description>
<url>/customModel/main?refreshTypesResponse={refreshTypesResponse}</url>
</webscript>

This is a ftl-view webscript and the controller is javascript based:
– main.get.head.ftl
– main.get.html.ftl
– main.get.js

Actually Sourceforge hosted the source code of the ADAMO project (GNU GPL 2.0 license). There is also an alpha version of pre-compilated files:
adamo.amp
admo-surf.war

Related posts

Leave a Reply

Your email address will not be published.