Alfresco 3: Writing and Executing Scripts

Exclusive offer: get 50% off this eBook here
Alfresco 3 Cookbook

Alfresco 3 Cookbook — Save 50%

Over 70 recipes for implementing the most important functionalities of Alfresco

£22.99    £11.50
by Snig Bhaumik | July 2011 | Open Source

An API (Application Programming Interface) is an interface implemented and offered by a software program that enables other applications to interact with it, or enables developers to write other applications on top of it. An API can be exposed in several different forms, such as internal class model and implementation–using which you can write your program, or as different services, for example, web services. As a solution developer of an Enterprise framework, you need to be proficient on the APIs provided and exposed by the framework.

In this article by Snig Bhaumik, author of Alfresco 3 Cookbook, we will take a look at how to write and execute scripts.

 

Alfresco 3 Cookbook

Alfresco 3 Cookbook

Over 70 recipes for implementing the most important functionalities of Alfresco

        Read more about this book      

(For more resources on Alfresco, see here.)

The reader can benefit from the previous article on Implementing Alfresco JavaScript API Functionalities.

 

Introduction

Alfresco, like any other enterprise open source framework, exposes a number of APIs including Alfresco SDK (Software Development Kit) a set of development tools that allows the creation of an application for a certain software package or framework and JavaScript API.

Available JavaScript APIs

Alfresco JavaScript API exposes all important repository objects as JavaScript objects that can be used in a script file. The API follows the object-oriented programming model for well known Alfresco concepts such as Nodes, Properties, Associations, and Aspects.

The JavaScript API is capable of performing several essential functions for the script developer, such as:

  • Create Node, Update Node: You can create, upload, or update files using these.
  • Check In/Check Out: You can programmatically check-out and check-in your content.
  • Access Rights Management Permissioning: You can manage your content’s security aspects.
  • Transformation: You can transform your content using this. For example, you want to generate a PDF version of your MS-Office document.
  • Tagging: Tagging APIs will help you tag your contents.
  • Classifying: You can categorize or classify your contents using this.
  • People: Using these APIs, you can handle all user-and group-related operations in your script; such as creating a new user, changing the password of a user, and so on.
  • Searching: One of most important and powerful APIs exposed. You can search your contents using these APIs. You can perform Lucene-based search or XPath-based search operations using these APIs.
  • Workflow: You can manage the tasks and workflows in your system using these APIs and services.
  • Thumbnail: Exposes APIs to manage the thumbnail operations of various content items.
  • Node operations: You use these APIs to perform several node-related functions such as Manage Properties, Manage Aspects, copying, deleting, moving, and so on.

Thus, as you can see, pretty much most of the things can be done in a JavaScript file using these APIs.

However, one thing is important, that you should not mix the usual JavaScript code you write for your HTML or JSP web pages. Those scripts are executed by your browser (this means, at the client side). The scripts you write using Alfresco JavaScript API are not client-side JavaScript file – this means these do not get executed by your browser. Instead, they get executed in your server and the browser has nothing to do in these scripts.
It is called JavaScript API since the APIs are exposed using the ECMA script model and syntaxes. The programs you develop using these APIs are written in JavaScript language.

The JavaScript API model

Alfresco has provided a number of objects in the JavaScript API – these are more usually named as Root Scope Objects. These objects are your entry point into the repository. Each of the root level objects refers to a particular entity or functional point in the repository. For example, userhome object refers to the home space node of the current user. Each of these objects presents a number of properties and functionalities, thus enabling the script writer to implement several different requirements. For example, the userhome.name statement will return the name of the root folder of the current user.

Some important and most frequently used root scope objects are:

  • Companyhome: Returns the company home script node object
  • Userhome: Returns the home folder node of the current user
  • Person: Represents the current user person object
  • Space: Stands for the current space object
  • Document: Returns the currently selected document
  • Search: Offers fully functional search APIs
  • People: Encapsulates all functionalities related to user, groups, roles, permissions, and so on.
  • Sites: Exposes the site service functionalities
  • Actions: Provides invocation methods for registered actions
  • Workflow: Handles all functionalities related to workflow implementation within the repository

Among these, companyhome, userhome, person, space, and document objects represent Alfresco Node objects and allow access to the properties and aspects of the corresponding node object. Each of the node objects provides a number of APIs which are termed ScriptNode API.

The others – search, people, sites, workflow, and actions – expose several methods that would help you implement specific business requirements. For example, if you want to write a script that searches some documents and contents, you would use the search API. If you want to create a new user – the people API will help you.

 

Alfresco 3 Cookbook Over 70 recipes for implementing the most important functionalities of Alfresco
Published: July 2011
eBook Price: £22.99
Book Price: £36.99
See more
Select your format and quantity:

 

        Read more about this book      

(For more resources on Alfresco, see here.)

Writing and executing scripts

There are a few options and implementation models by which you can write your JavaScript files and execute them in Alfresco. A couple of the most usual models are:

  • Writing and storing scripts in the Data Dictionary
  • Using Web Scripts

In this recipe, we will see how to write and execute simple scripts from the Data Dictionary.

Getting ready

  1. Open the Alfresco explorer and navigate to the Company Home | Data Dictionary | Scripts folder.

    (Move the mouse over the image to enlarge.)

  2. This is the space where all the JavaScript files should be stored. Alfresco explorer looks for JS files by default from this location. Alfresco has provided some sample scripts to make the scripting methodology more understandable.
  3. We will try executing the backup.js script provided in this space. One way you can execute the script files is with the Run Action method.
  4. Let’s assume in a particular space we have a document. We will run the backup.js script against this document. Suppose these are the contents of a space we are working on. It has only one content item – My Movie.wmv.

    Alfresco 3 Cookbook

  5. Open the details screen of this content and click on Run Action. In the Run Action Wizard, select Execute script as the action to be performed and click on Set Values and Add.

    Alfresco 3 Cookbook

  6. In the next screen, the list of available scripts is presented. You can select one of them and the script will be executed.

    Alfresco 3 Cookbook

  7. As you can see, all the nine default scripts are available here – the same as the scripts present in the Company Home > Data Dictionary > Scripts space. However, since we are trying to execute the backup.js, we select the backup.js file and click OK . In the next screen, click Finish to complete the operation.
  8. Now if you navigate to the original space (where the My Movie.wmv file was located), you will see that a new folder named Backup is created there.

    Alfresco 3 Cookbook

  9. A backup of the file My Movie.wmv has been generated in the Backup folder.

  10. Thus the backup.js script has been executed and it has created a backup of the content item on which the script has been executed.

We now know how to execute a script file. We will now try to create a new script file and run it.

How to do it…

  1. Open the Alfresco explorer and navigate to the Company Home > Data Dictionary > Scripts folder. Create a content item. Let’s name it transform.js.

    Though the .js extension for the content name is optional here, it is a standard and good practice to name the JavaScript file .js

    Alfresco 3 Cookbook

  2. Let’s say, we are writing the script for creating an Adobe PDF version for an MS Word file. Here is the code:

    if (document.mimetype == "application/msword")
    {
    var pdfDoc = document.transformDocument("application/pdf");
    }

    Alfresco 3 Cookbook

  3. Click on Finish to complete the creation of your script.

  4. Now, as your script has been created, let’s execute it.
  5. Upload an MS Word document in a space. For example, we have uploaded a document named Infoxon.doc.

  6. Open the details view of the document. Click on Run Action and select action as Execute script. You can see our new script transform.js is available in the list. Select this script and click OK.

    Alfresco 3 Cookbook

  7. Click on Finish to execute the action. This will run the JavaScript we have written in the script file.
  8. When you reopen the space contents, you can see a new PDF file has been created here. Since the original document name was Infoaxon.doc, the PDF is automatically named Infoaxon.pdf.

  9. When you download the PDF file, you can see your Word file is transformed into a PDF document.

How it works...

There are a few interesting points to explore how this transformation happened.

There are simply two lines of code in your JS file.

if (document.mimetype == "application/msword")

The document object stands for the current document on which the script is being executed. In our case, it is the Infoaxon.doc document. Thus document.mimetype would return the mime type of the current document.

Since we want only to convert MS Word documents into PDF, we have added this condition. In case you run this script for a document which is not of type MS Word, the transformation won’t take place.

var pdfDoc = document.transformDocument("application/pdf");

Again, the document object represents the current document. The transformDocument method is an API provided in a ScriptNode object where you need to supply the mimetype of the target document – in our case, it is a PDF document, hence the application/pdf mimetype.

The transformDocument method has another overloaded signature, where you can supply a second parameter – destination folder. Right now, the new PDF file is being created in the current folder. In case you want your transformed file to be created in another space, you must provide this parameter.

In the background, Alfresco uses Open Office APIs to generate PDF documents from MS Office contents. For this, you must enable and establish Open Office in your Alfresco server.

Running scripts via Run Action is one way of executing this. However, what if you want to generate PDF files whenever a new MS Word document is uploaded in a certain folder? For this, you use the Rule mechanism. You simply create a rule that will fire the execution of the transform.js script whenever a new document is placed in this folder.

 

Alfresco 3 Cookbook Over 70 recipes for implementing the most important functionalities of Alfresco
Published: July 2011
eBook Price: £22.99
Book Price: £36.99
See more
Select your format and quantity:

 

        Read more about this book      

(For more resources on Alfresco, see here.)

There’s more...

Now that we know how to write and execute scripts in the Alfresco explorer, let’s dive deep into the important APIs supplied by Alfresco.

ScriptNode API

The following list is a subset of the available APIs and services of a ScriptNode object. More extensive properties, methods, and services are available in the JavaScript APIs.

  • properties: Presents an array of the available properties of the current node object. For example, var docname = document.properties["cm:name"];
    In case of our custom model – iabook:product, if we want to extract the color of the product node, we will write:
    var pcolor = document.properties["iabook:color"];
  • children: Supplies an array of ScriptNode objects of the child nodes of the current object.
  • isContainer: This will return a boolean value denoting whether the current node object is a space or a document. This will return true if the node is a folder.
  • isDocument: This will return a boolean value denoting whether the current node object is a space or a document. This will return true if the node is a content item.
  • downloadUrl: Returns the content stream of the node as an HTTP1.1 attachment object. You should use this property if you want to provide the download URL of your document in the repository.
  • size: Returns the size of the content item in bytes.
  • isLocked: When a document is checked out, it is locked for other users. This property returns true if it is locked.
  • nodeRef: Each object in the Alfresco repository has a unique ID – this is named as NodeRef. This property returns the NodeRef value as a string of the corresponding object.
  • childByNamePath: This method returns the particular node specified in XPath. For example, var mynode = companyhome.childByNamePath("InfoAxon/Chapter 8/Infoaxon.doc") would return the particular referenced node in the specified path.
  • childrenByXPath: This method searches for the matching nodes as per the specified XPath. Returns an array of nodes. For example, var mynodes = companyhome.childrenByXPath("*[@cm:name=’InfoAxon’]/*") returns all nodes with the name InfoAxon.
  • content: Returns the text content for the node. This is a read/write property – meaning you can set or change the content using this property. For example, mynode.content = "This is a sample content"
  • createNode: Method for creating a new node under a particular folder.
    For example, var newdoc = myspace.createNode("docname.txt"). The method returns the ScriptNode object of the new content node created. The new node created will be of type cm:content. If you want to create a content node of your own type, you can use var newdoc = myspace.createNode("docname.txt", "iabook:Product"). You then use that object to set other properties and so on.
  • createFolder: Method for creating a new space under a particular folder.
    For example, var newfolder = myspace.createFolder("foldername").

    You can see that the statement var newfolder = myspace.createFolder("foldername") and statement var newfolder = myspace.createNode("foldername", "cm:folder") will produce exactly the same result.

  • remove: Removes the current node from the repository.
    For example, var success = mynode.remove(). Upon successful operation, mynode will be deleted, and the variable success will have the value true or false, depending on the status of the operation.
  • copy: Use this method to create a copy of the current node into another folder. More powerfully, you can copy the entire subfolder tree as well.
    For example, var newnode = mynode.copy(destinationfolder, true). This will copy the mynode space and all other subfolders and content items into the destinationfolder node. However, the second parameter is optional, with the default value false.
  • addAspect: Adds a new aspect into the current node.
    For example, var success = mynode.addAspect("cm:versionable").
  • hasAspect: If you want to check whether your content node has a certain aspect associated with it or not, you need to use this method.
    For example, mynode.hasAspect("iabook: relatedProducts") would return true or false, depending on whether the relatedProducts aspect is associated with mynode.
  • write: Copies the contents of the specified node into the current node. For example, mynode.write(sourcenode) would copy the contents of sourcenode into mynode.

    There is a difference between the copy method defined above and the write method. The copy method copies the entire object and creates a new instance which is an exact replica of the source node; on the other hand, the write method only copies the contents of the node leaving the other properties unchanged.

  • hasPermission: Returns true if the current user has the specified permission on the node.
    For example, var permitted = mynode.hasPermission("Delete"). The permitted value will be true if the current user can Delete the node or the sub-nodes. The commonly used permission checks are Read, Write, Delete, and CreateChildren. CreateChildren permission is especially interesting, as having this permission means you can create sub-nodes under the current node.
  • setPermission: Applies the specified permission to the specified authority. An authority can be a user or a group.
    For example, mynode.setPermission("Write") would provide Write permission to all the users on mynode. The command mynode.setPermission("Write", "snig.bhaumik") would provide Write permission to the user snig.bhaumik.
  • removePermission: Use this method to revoke some permission from an authority.
    For example, mynode.removePermission("Write") would retract Write permission from all users. Similarly, mynode.removePermission("Write","snig.bhaumik") would retract Write permission from the user snig.bhaumik.
  • inheritsPermissions, setInheritsPermissions: Just like your Windows® file system, where by default a subfolder inherits all permissions from its parent folder (unless explicitly overridden), a folder in the Alfresco repository also inherits the permission settings from the parent node.
    These methods are used to control this permission inheritance behavior.

    For example, mynode.inheritsPermissions() would return a Boolean value mentioning whether the mynode object is inheriting the permission settings from the parent folder. You can change this by using the mynode.setInheritsPermissions(true) (or false) method syntax.

  • checkout: Method to checkout a node. After a successful execution of the statement, the corresponding node will be checked-out, it will be locked, and a new content item will be created and returned as the working copy of the content.
  • checkin: After alteration on the working copy node, you must check in the working copy. After this, the original node will be updated and unlocked.
  • cancelCheckout: Sometimes you may want to cancel the checkout operation. You do not want to continue the updating of the content. For that, you use this method mynode. cancelCheckout().
  • isTagScope: As part of the tagging API, this method returns whether the current node is the tag scope or not.

    A tag scope is a logical container for tagged content items. In the repository, you can have a number of such tag scopes which would define logical collections of tags.

  • tags: Returns an array of tags of the current node. For example, var mytags = mynode.tags would set all the tags of the mynode object. You can also set the tags of the current node using this method.
  • addTag: You can use this method to add a particular tag into the current node object. For example, mynode.addTag("cookbook") would add the tag cookbook with mynode.
  • removeTag: Use this method in order to remove a tag from the current node. For example, mynode.removeTag("cookbook") would remove the tag cookbook from mynode.

    However, this method does not remove a particular tag from the tag scope.

  • specializeType: Sometimes you want to change the content type of your content item. If you want to change the content type of a content node, you use this method.
  • isSubType: This is a useful method. With this, you can find out whether your content node is of a certain type or of any of the subtypes of the certain given content type. For example, mynode.isSubType("iabook:product") will return true if mynode is of product type.

People API

People API methods are used to perform several operations related to users and groups. These APIs offer access to Alfresco groups and people. The following list is a subset of the available APIs and services of a people object. More extensive properties, methods, and services are available in the JavaScript APIs.

  • createPerson: Creates a new person or user, the new node created in the repository is of the type cm:person. You supply the username of the new person to be created.
  • deletePerson: Deletes a user from the repository.
    For example, people.deletePerson("snig.bhaumik") would remove the user from the repository.
  • getPerson: You use this method to retrieve the person object (object of type cm:person) having the given username.
    You can then use or change any property of this ScriptNode object. Some of the available properties of a person object are:
    • cm:firstName: Gets or sets the first name of the person.
    • cm:lastName: Gets or sets the last name of the person.
    • cm:sizeQuota: Gets or sets the quota size the person can use.
    • cm:sizeCurrent: Gets the current content size the person has already used. This is a read-only property.
    • cm:username: Gets the username of the person. This is a read-only property since you cannot change a person’s username.
    • cm:homeFolder: Gets the Home Space NodeRef of the person.
    • cm:jobtitle: Gets or sets the job title of the person.
    • cm:organizationId: Gets or sets the organization of the person.
    • cm:email: Gets or sets the e-mail of the person.
    • cm:mobile: Gets or sets the mobile number of the person.

    As the person object returned here is a standard ScriptNode object, you can also use all advanced functionalities like addAspect, createAssociation, and so on to enhance the default behavior of the person object.

  • changePassword: The getPerson object detailed above does not allow you to change a user’s password. This method enables you to change the password of the current user. However, you must provide the old password as well in this method along with the new password, for example, changePassword("oldpass", "newpass").
  • setPassword: The changePassword method can only change the password of the current user. However, if you want to change the password of any user, then you need to use this method. For example, people.setPassword("snig.bhaumik","newpass") would set the password as newpass for the user snig.bhaumik.

    However, quite understandably, for using this method, you must have admin rights in the repository.

  • isAdmin: Use this method to determine whether the specified person is an administrator or not.
  • createGroup: Creates a new group in the system. The new node created in the repository is of type cm: authorityContainer. You supply the user name of the new group to be created.

    Alfresco always prefixes the keyword GROUP_ with the name of the new group you have provided.

  • getGroup: Retrieves our group object from the repository. This method returns an object of type cm: authorityContainer.
  • getMembers: Use this method to retrieve the list of member users of a certain group. You pass the group object as a parameter in this method. Returns an array of person object nodes. For example, var userlist = people.getMembers(grpobj).

Search API

Search API is one of the important APIs you would use more frequently while developing custom solutions on Alfresco.

Alfresco uses Lucene to search content items for you. The properties and aspects you create and use in your content items are indexed in Lucene, and you can perform your searches using most of the standard Lucene search query syntaxes.

Apart from some XPath-based searches, searching in Alfresco mostly is done using Lucene. Alfresco supports very extensive Lucene-based search queries and functionalities. Most of the search API results return array ScriptNode objects.

Thus understanding search API in Alfresco mostly and essentially means understanding the Lucene syntaxes and usage in the APIs. However, there are a few other search APIs available in Alfresco which are worth investigating.

Once you are familiar with the search APIs available, you need to get to the understanding of Lucene query syntaxes, since in most cases while searching for content items in the repository you will end up with writing some complex Lucene queries.

Here is a brief list of search APIs.

  • xpathSearch: Returns an array of ScriptNode objects as per the XPath provided. For example, search.xpathSearch("*[@cm:name=’InfoAxon’]/*"). This returns all nodes with the name InfoAxon.
  • findNode: Searches for a node having the nodeRef passed.
    For example, search.findNode("workspace://SpacesStore/157d5f2d-579b-46dc-b1be-0242509367a7") returns the node having this noderef. This method returns, at most, one object, or null in case no node exists by this noderef.
  • tagSearch: Searches for nodes having the supplied tag associated.
    For example, search.tagSearch(null, "cookbook") returns an array of ScriptNode objects which are tagged with cookbook. The first parameter null would have the search performed in the main store – SpacesStore. If you want to search other stores, you need to provide the store in the first parameter.
  • luceneSearch: This is probably the mostly used search API. As the name suggests, you use this method for performing Lucene-based searches. There are a few overloaded luceneSearch methods available.
  • luceneSearch (query): Simplest version of the Lucene search method, in main store, SpacesStore.
  • luceneSearch (store, query): Simplest version of the Lucene search method, in the given store.
  • luceneSearch (query, sortcolumn, sortdirection): Performs search as per the query provided, sorts the result with the column provided as per the sort direction given, in the main store – SpacesStore.
  • luceneSearch (store, query, sortcolumn, sortdirection): Performs search as per the query provided, sorts the result with the column provided as per the sort direction given, in the given store.
    In the query parameter, you put Lucene query statements.
    For example, search.luceneSearch("TEXT:InfoAxon") will perform full text search in the repository and returns all nodes having the InfoAxon word in the content.

It is important to know that the PATH values, the property names, the type names, and so on are case sensitive in Lucene query.

Summary

Alfresco offers the repository functionalities in form of JavaScript APIs. In this article, we understood the API structure and features offered. We also took a look at how to write and execute Scripts using the APIs.


Further resources on this subject:


About the Author :


Snig Bhaumik

Snigdhendu Bhaumik is the Technical Director of InfoAxon Technologies Ltd, based in India. He is also the Director of Open Source Innovation and Heads the Knowledge Management Practice at InfoAxon – India’s first and pioneer Open Source Integration company.

A computer engineer by education and developer at heart, Snigdhendu has 10 years of experience in various technologies such as Alfresco, Liferay, Pentaho, and Microsoft .NET. An open source enthusiast and regular community participant, Snigdhendu was the original contributor of Alfresco Calendar component. He specializes in Knowledge Management and Business Intelligence domains, and is responsible for designing and architecting KM and BI solution offerings.

Books From Packt


Alfresco 3 Records Management
Alfresco 3 Records Management

Alfresco 3 Web Content Management
Alfresco 3 Web Content Management

Alfresco 3 Web Services
Alfresco 3 Web Services

Alfresco 3 Business Solutions
Alfresco 3 Business Solutions

Liferay Portal 6 Enterprise Intranets
Liferay Portal 6 Enterprise Intranets

CMS Made Simple 1.6: Beginner's Guide
CMS Made Simple 1.6: Beginner's Guide

CMS Design Using PHP and jQuery
CMS Design Using PHP and jQuery

CMS Made Simple Development Cookbook
CMS Made Simple Development Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software