Alfresco document management system

Alfresco ECM is a system for the organization of the company’s internal portal. Alfresco ensures joint work of employees by providing the following main features:

  • Joint work with documents.
  • Joint work with articles on the internal portal using Wiki approach.
  • Discussions. Discussions are a kind of forum where any employee can create a new discussion and other employees can participate in it by posting their messages.
  • Blogging.
  • Document management. By default, the system has only one “Workflow” for the workflow system – the process of document acceptance (approval). Example: CEO shall approve a document. So, when the document is completed, it is necessary to start the “Workflow” of document acceptance and specify persons who shall approve it (in this case it is CEO). After that, the CEO’s list of tasks will include a new task – document acceptance. CEO will have two options, “Accept” and “Reject”. It is also possible to create your own “Workflow”.

Activity: setting a workflow for submitting documents for review

The process of setting your own “Workflow” in Alfresco is described below by steps. This Workflow was created following the manual, implements the functionality of sending documents for review, and is described by the following diagram:

Workflow in Alfresco
  1. Create a model directory in directory ALFRESCO_HOME/tomcat/shared/classes/alfresco/extension/ and add workflow model file ReviewWorkflowModel.xml into it.
  2. Create a workflows directory in directory ALFRESCO_HOME/tomcat/shared/classes/alfresco/extension/ and add process description file ReviewProcess.xml there.
  3. Create a messages directory in directory ALFRESCO_HOME/tomcat/shared/classes/alfresco/extension/ and add workflow localization file jazzWorkflow_ru_RU.properties to it.
  4. Add files web-client-config-custom.xml and dir-workflow-context.xml in directory ALFRESCO_HOME/tomcat/shared/classes/alfresco/extension.
  5. Add files share-config-custom.xml and custom-slingshot-application-context to ALFRESCO_HOME/tomcat/shared/classes/alfresco/web-extension.
  6. Create a messages directory in ALFRESCO_HOME/tomcat/shared/classes/alfresco/web-extension/ and add file jazz_ru_RU.properties to it. It describes share interface localization.

Business workflow creation and execution

After that start Alfresco. Go to the directory ALFRESCO_HOME/tomcat/bin and run file startup.bat.

Go to http://localhost:8080/share, log in to your account and select More -> My business workflows.

Click Start a business workflow

Then click Start a business workflow.

Send a document for review

Select Send a document for review in the list of available business workflows.

Start a business workflow

Then specify the description of the task, what should be reviewed, assign the task to a certain person in the system, add the document that should be reviewed, and then click on the Start a business workflow button.

The list of tasks

After that the status of the business workflow will change to actual, and the list of tasks of Alexander Ivanov user, who was assigned the review task, will include the corresponding task.

Document review

He will be able to open the task, view the attached files, review them and write the Review result.

Review result task

After that he should click on the Submit button to submit the Document review result task. After submitting the Review result task, the user who sent the document for review will see the Review result task.

Document review result

The task describes the Document review result.

Task completed
After that the task can be closed by clicking on the Task completed button. The status of the business workflow will change to Completed.

Alfresco Web Scripts technology

Alfresco web scripts provide tremendous opportunities to expand system functionality.

A web script in Alfresco terms is a RESTful service that is connected with a specific URI. A web script can process different types of HTTP requests: GET, PUT, POST, DELETE. Usually the type of request is selected depending on the functions performed (GET – data output, PUT – data loading, etc.).

The process of executing a web script is presented below:

Process of executing a web script

Let’s write a web script that will allow creating new folders using POST (HTTP) method.

Web script structure:

  • folder.post.desc.xml – script description;
  • folder.post.js – js controller;
  • folder.post.json.ftl – template for json output;
  • folder.post.xml.ftl – template for xml output.

folder.post.desc.xml

<!--Start of the script description-->
<webscript>
<!--Short name-->
<shortname>Create New Folder</shortname>
<!—Description-->
<description>Create new folder</description>
<!--Script URI, the script takes two parameters: name and
parentNodeRef-->

<url>/jazzteam/folder?name={name}&parentNodeRef=
{parentNodeRef}
</url>
<!--Method of specifying the output and default formats-->
<format default="json">any</format>
<!--Authentication. This script will be available to all
system users (login and password are required)-->

<authentication>user</authentication>
<!--Enable transactions to access the storage-->
<transaction>required</transaction>
<lifecycle>sample</lifecycle>
</webscript>

Now let’s describe the controller of script operation. The controller contains all the business logic of the script.

folder.post.js

// Get the parentNodeRef parameter from the URL. For this purpose, use
// a standard alfresco object - args
var parentFolderNodeRef = args["parentNodeRef"];
// Get the name parameter
var newFolderName = args["name"];
if (parentFolderNodeRef && newFolderName) {
// Get the parent folder object. Do this
// using another standard object - search. Call the
// findNode method and transfer the nodeRef of the node that
// should be found
var parentFolder = search.findNode(parentFolderNodeRef);
// If the node is found and it is a container
if (parentFolder && parentFolder.isContainer) {
// Make sure that no folder with this title has been yet
if (!parentFolder.childByNamePath("/" + newFolderName)) {
// Create a new folder in parentFolder directory by
// calling the createFolder method, which takes
// the name of the new folder as a parameter.
var createdFolder = parentFolder.createFolder
(newFolderName);
// Use the standard model object to save the data,
// which will be needed to create a response
model
.data = {
"name": createdFolder.name,
"nodeRef": createdFolder.nodeRef.toString(),
"path": createdFolder.displayPath.toString()
};
}
// In case we try to duplicate the folder name,
// it is necessary to create a response stating about an exceptional
// situation. It is done using the status object,
// Enter HTTP status code 403 in the code field. It
// shows that there is an error. Enter the description in the message field
else {
status
.code = 403;
status
.message = "Folder " + newFolderName + " already
exists."
;
status
.redirect = true;
}
}
else {
status
.code = 400;
status
.message = "Folder with nodeRef " +
parentFolderNodeRef
+ " not found.";
status
.redirect = true;
}
}
else {
status
.code = 403;
status
.message = "Invalid arguments.";
status
.redirect = true;
}

Let’s describe a template for web script result output in json format.

folder.post.json.ftl

<#--Enable character escaping-->
<#escape x as jsonUtils.encodeJSONString(x)>
{
"data":{
<#--Get the name, nodeRef and path fields from the data object, which we saved in the controller in the model object-->
"name":"${data.name}",
"nodeRef":"${data.nodeRef}",
"path":"${data.path}"
}
}

Now we will describe a template for web script result output in xml format.

folder.post.xml.ftl

<!--?xml version="1.0" encoding="utf8"?-->
<#--Enable character escaping-->
<#escape x as x?xml>
<#--Root element-->
<data>
<#--We get the name, nodeRef and path fields from the data object, which we saved in the controller in the model object-->
${data.name}
${data.nodeRef}
${data.path}
</data>

After the script description you need to install it. So, copy all the script files to the following directory: ALFRESCO_HOME\tomcat\shared\classes\alfresco\templates\webscripts\.

Go to http://localhost:8080/alfresco/service/index and click on the Refresh Web Scripts button to refresh the web script index:

Refresh Web Scripts

Click on the Browse all Web Scripts link and find your script:

Browse all Web Scripts

Use of REST service

To use a previously written service, it should be called. You can do it by sending an HTTP request. To call the service, use POSTMAN – an extension for Google Chrome.

POSTMAN

The service can be called in several ways, depending on the format in which you want to receive the response. It is not obligatory to specify the format. If you do not specify the format, the service will return the response in the default format:

localhost:8080/alfresco/service/jazzteam/folder – response in json format;

localhost:8080/alfresco/service/jazzteam/folder.json – sends a response in json format;

localhost:8080/alfresco/service/jazzteam/folder.xml – response in xml format.

Also, the response format can be specified as the format parameter, which can take xml or json values added to the end of the parameter list.

Let’s enter the URL of our REST service in the field “Enter request URL here” and select the POST value from the drop-down list:

Enter request URL here

Add name – the name of the created folder and parentNodeRef – the identifier of the folder, in which you want to create a new folder, to the list of parameters:

Add name

When everything is filled in, send a request. So, click on the Send button:

Send a request

After that a new folder will be created, and the server will send back its nodeRef and the relative path to it in Alfresco.

In case of an error, the server will send the error description in reply:

Error description

If you specify localhost:8080/alfresco/service/jazzteam/folder.xml in the URL field, the response from the server will be in xml format:

The response from the server in xml format

Error description in xml format:

Error description in xml format

Alfresco Web Scripts: dashlets

Dashlets are essentially web scripts that send back the HTML code displayed on the page as a widget instead of json/xml.

Let’s write a dashlet that will display a list of system users. The dashlet receives data from the system’s web scripts.

To create a dashlet, you need to write the following files:

  • users.get.desc.xml – dashlet descriptor;
  • users.get.js – controller, main logic;
  • users.get.html.ftl – output template in HTML format;
  • users.get_ru.properties – localization file.

users.get.desc.xml

<webscript>
<shortname>List User Dashlet</shortname>
<description>Simple dashlet</description>
<family>dashlet</family>
<url>/components/dashlets/listuser</url>
</webscript>

users.get.js

//Create a connector object that will allow getting access to Alfresco
var connector = remote.connect('alfresco');
//Address the service located at /jazz/users,
//which will return the list of users in json format
var dataStr = connector.get('/jazz/users');
//Parse the resulting json string, change it to a js object
var data = eval('(' + dataStr + ')').data;
//Save the received data in the data field of the model object
//for the subsequent use in the output template
model
.data = data;

Let’s describe the template of the page that will be the dashlet presentation

users.get.html.ftl

<script type="text/javascript">
<#-- Let the panel be expandable, change its size-->
new Alfresco.widget.DashletResizer("${args.htmlid}",
"${instance.object.id}");
</script>
<div class="dashlet" style="height: 40%">
<#-- Set the title of the panel-->
<div class="title">${msg('label.title')}</div>
<div class="body scrollableList">
<#-- Let's make the output of records in the form of a list of tables-->
<#list data.users as user>
<div class="detail-list-item
<#if !user_has_next>last-item</#if>">
<table>
<tr>
<td>
<div class="yui-dt-liner">
<#--Set the icon for the user-->
<img src='/share/res/components/documentlibrary/images/
folder-32.png'
/>
</div>
</td>
<td>
<h4>
<a class="theme-color-1" href="#">${user.fullName}
(${user.nickName})
</a>
</h4>
</td>
</tr>
</table>
</div>
</#list>
</div>
</div>

users.get_ru.properties

label.title=Alfresco User List

Let’s copy the previously described files to ALFRESCO_HOME/tomcat/shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/dashlets/.

Now let’s go to http://localhost:8080/alfresco/service/index and click on the Refresh Web Scripts button to refresh the web script index.

After that go to http://localhost:8080/share, log in and click on the Customize home page button:

Customize home page

Then click on the Add dashlets button:

Add dashlets

And you will see your dashlet – List User Dashlet – in the list of available dashlets:

List User Dashlet - in the list of available dashlets

Add it by dragging to Column 1 or Column 2 and then click OK.

After that the dashlet will be displayed as a scrollable panel on the main page of Alfresco Share:

Dashlet as a scrollable panel on the main page of Alfresco Share

Useful information on Web Scripts creation