Root objects for an execution script Alfresco provides a set of default root objects also known as Script Node objects that wrap the common Alfresco repository concepts such as nodes, as
Trang 1Objectives of a controller
This is an optional component of a web script, but generally used when you want
to access the repository and perform certain operations Similar to the role of a controller in the MVC architecture, here also the main objective of the controller is to dictate what to do behind the scenes and what to display in the view The controller builds a data model that is passed to the FreeMarker response templates and
rendered Web scripts in Alfresco support two types of controllers:
• JavaScript controller
• Java-backed controller
In the following sections, we will talk about these both in detail
JavaScript controller
A controller is used in order to perform some business logic, and one of the available controllers is JavaScript, which is also known as execution script You need to follow the naming convention for a web script execution script, which is:
<serviceId>.<httpMethod>.js
where serviceId is the web script ID and httpMethod can be GET, POST, PUT,
or DELETE
For example, if we have a web script that is responsible for getting the news, we can have the filename as getNewsHeadline.get.js
Root objects for an execution script
Alfresco provides a set of default root objects also known as Script Node objects that wrap the common Alfresco repository concepts such as nodes, aspects, associations, and properties
The list of these root objects, which you can use for an execution script, is as follows:
• companyhome: The company home template node This is available only
if authenticated
• userhome: Current user's home space template node This is available only
if authenticated
• person: Current user's person object template node This is available only
if authenticated
• args: An associative array of any URL parameters
Trang 2• search: The host object providing access to Lucene Search.
• people: The host object providing access to Alfresco people and groups
• actions: The host object providing invocation of registered Alfresco actions
• logger: The host object providing access to console logging facilities for debugging of scripts
• session: Session-related information such as the current authentication ticket
• classification: Access to the root elements of the classification API
• utils: Access to a library of useful helper functions not provided as part of the generic JavaScript
• avm: Access to WCM objects such as avm stores and web projects
• webprojects: The root of the WCM JavaScript API It provides access to web projects, sandboxes, WCM assets, and WCM project membership
• crossrepository: Cross repository copy support This enables copying of nodes between document management spaces and WCM spaces
• argsM: An associative array of any URL parameters
• url: Provides access to the URL (or parts of the URL) that triggered the web script
• formdata: Provides access to multi-part/formdata requests allowing the upload of files via web scripts
• model: An empty associative array that may be populated by the JavaScript Values placed into this array are available as root objects in web script
response templates
• roothome: The repository root node
• guest: A Boolean indicating whether the web script executes as "Guest"
• server: An associative array of metadata properties describing the
repository server hosting the web script
JavaScript methods for the AVM
repository
Each of these root objects has different APIs For more details on this, you can refer to
the Alfresco wiki's JavaScript API page at http://wiki.alfresco.com/wiki/3.2_ JavaScript_API and see some examples at http://wiki.alfresco.com/wiki/ JavaScript_API_Cookbook In the next section, we will talk about FreeMarker APIs that are available for the AVM repository
Trang 3AVM API
avm is the root object for JavaScript APIs, and with this root object you can access the AVM repository The available APIs for the avm root node are as follows:
• stores: This returns all store objects in the AVM repository
• lookupStore(storeid): This returns the store object for the specified store ID
• lookupStoreRoot(storeid): This returns the root node for the specified store ID
• lookupNode(path): This returns a single AVM node based on the given full path, including store to the node
• webappsFolderPath(storeid): This returns the root path to the AVM
webapps folder for the specified store ID
AVM store API
When you use any of the previous mentioned AVM API, you will get the object of the AVM store This store object can have the APIs described next:
• id: This returns the internal ID of the store
• name: This returns the name of the store
• creator: This returns the user who has created this store
• createdDate: This returns the date on which the store was created
• lookupRoot: This returns the root node for the store
• lookupNode(path): This returns the node for the specified path relative to the AVM webapps root folder for the store
• luceneSearch(query): This executes a search against the store and returns
an array of AVM nodes as the result
AVM node API
• version: Returns node's version Generally it will be –1 (Head revision)
• path: Returns fully qualified AVM path to the node
• parentPath: Returns fully qualified AVM path to the parent of the node
• isDirectory: Returns true if this node is a directory
• isFile: Returns true if this node is a file
• isLocked: Returns true if this node is currently locked
Trang 4• isLockOwner: Returns true if this node is locked by the current user.
• hasLockAccess: Returns true if this user has the permission to perform operations on the node when locked This is true if the item is either
unlocked, locked by the current user, or locked and the current user has the Content Manager role in the associated web project
• rename(name): This renames the node In AVM you cannot change the
cm:name property directly to change the name
Java-backed controller
If the script and template are not sufficient enough to achieve the required
functionality, you can have a Java Bean where you will have full control over the Alfresco Repository and also the Java API With Web script, you can bind a Java Bean as a Spring Bean in Alfresco When you have a Java bean, you can also have
a combination of web Java script with it The sequence of execution will be first Java script will be executed first and then Java bean if you have both used for any web script
How to declare a Java Bean
To bind a Java Bean as a Spring Bean for any web script, you need to make a bean entry in the web-script-custom-context.xml file in the /WEB-INF/classes/ alfresco/extension folder Also, you have to follow a proper naming convention for that bean ID, which will be:
id="webscript.<packageId>.<serviceId>.<httpMethod>"
where packageId is the package in which the web script descriptor file is located,
serviceId is the web script ID, and httpMethod can be GET, POST, PUT, or DELETE Also, the parent of this bean should be webscript while configuring this:
<bean id="webscript.org.cignex.news.getNewsHeadline.get"
class="com.cignex.web.scripts.bean.news.GetNewsHeadline"
parent="webscript" />
Creating a Java Bean class
When creating a Java Bean class, GetNewsHeadline, as in the previous section, this class must implement the org.alfresco.web.scripts.WebScript interface, which has the method:
public void execute(WebScriptRequest req, WebScriptResponse res)
Trang 5You need to implement this method in your Java Bean class There are two helper classes provided to simplify the development of a Java-backed web script: org alfresco.web.scripts.AbstractWebScript and org.alfresco.web.scripts DeclarativeWebScript
Implementing web scripts
Implementation of a web script consists of mainly four parts These are explained in the following sections
Creating a web script
Create the required files for a web script A description document and a rendering template are required You can also have a controller script and other components described in the earlier sections of this chapter, if required
Storing the web script
There are two ways of storing a web script in Alfresco We will discuss both
these methods:
Storing it on the filesystem
If you want to store it on the filesystem, you need to store it in the
<<alfresco_server>>/tomcat/shared/extension/templates/webscripts
folder You can create the desired folder structure inside this folder
and then put all of the web script files in there
Storing it in Alfresco Explorer
You can store the web script files in the Company Home | Data Dictionary | Web
Scripts Extensions page Create the required folder structure under this path as
shown in the next screenshot:
Trang 6Click on Create Space and provide a name for the folder you want to create and click
on the Create Space button.
Once done with the creation of folders, place the web script files, description
document, rendering template, and controller script (if you have one) in that folder
with the help of the Add Content option, as shown in the following screenshot:
To upload the files, click on Add Content as shown in the previous screenshot Then browse to the file on your local desktop and click on OK to upload that content to the
specified space:
Trang 7Registering the web script
Once you are done with storing the required web script files, you need to register them in Alfresco For registering the web scripts stored in Alfresco Explorer, navigate
to http://localhost:8080/alfresco/service/index and click on the Refresh
Web Scripts button, as shown in the following screenshot:
You will see a message about the completion of maintenance of web scripts, which also specifies the number of web scripts:
Click on the Refresh Web Scripts button You will see a message showing how
many web scripts have recently been found and registered
Trang 8While registering web scripts stored on the filesystem for the first time, you need to restart the Alfresco server After the web script is registered, if you change something
in the execution script or presentation template, you can click on the Refresh Web
Scripts button on the index page of web scripts; there is no need to restart the server.
In this way, Alfresco supports Hot Deployment of web scripts.
Listing the web scripts for external access
Once the web script is registered, you can start using it with the URL Navigate to
http://localhost:8080/alfresco/service/index, and you will see the different browse options there If you want to check it, you can click on any of the available
browse options Clicking on Browse by Web Script URI will browse all of the web
scripts' URI By doing so, you can verify your web script is there:
Trang 9Integrating WCM with external
applications—case studies
In an earlier chapter on web forms, we talked about how we can use Alfresco WCM for content production Now in this section, we will discuss some of the case studies where the actual application is outside of Alfresco, but the content will be stored
in Alfresco WCM and needs to be served from Alfresco only For that, we can use Alfresco web scripts, which will act as an integration point for Alfresco WCM content and the actual application
Integrating Alfresco WCM and Liferay with a news portlet
Let's consider the case where we want to have a news portlet in some Liferay Portal Application So here, rendering of the portlet will be handled in Liferay, but the actual news content and the headlines for the news are stored in Alfresco WCM
We have some news content stored in the /ROOT/common/inc folder, and we will try
to fetch the headlines for these news items
Web script for getting news headlines
In this example, we will create a web script for fetching the news headlines from Alfresco We will use JavaScript as the controller and will return the response in XML format This XML response will then be processed by a portlet in Liferay and the final news headline will be displayed on the news portlet
Description document
The description document, getNewsHeadline.get.desc.xml, which describes the URL and the authentication mechanism for the web script is as follows:
<webscript>
<shortname>Listing Of News Headlines</shortname>
<description>Listing Of News Headlines for Cignex home page thru Webscript</description>
<url>/org/cignex/news/getNewsHeadlines.xml?storeId={storeId}</url> <authentication>user</authentication>
</webscript>
Trang 10Execution script
JavaScript controller, getNewsHeadline.get.js, executes the search query to fetch the news items' nodes from the WCM repository This is done using the Lucene Search API to search the content of a specific web form Here in this example, it's the news web form Keep in mind that this Lucene Search will only be applied to the Staging Sandbox of a web project Here we have storeId as one of the web script parameters, but that should point to the Staging Sandbox of a web project:
var storeId = args["storeId"];
var newsNodes = new Array();
if(storeId != null) {
var webProjectStore = avm.lookupStore(storeId);
if(webProjectStore != null) {
var queryForNews = "@wca\\:parentformname:news AND @cm\\:name:\"* xml\"";
var resultNodes = webProjectStore.luceneSearch(queryForNews); if(resultNodes != null) {
logger.log("Reslut nodes: " + resultNodes.length);
for (var i=0; i<resultNodes.length; i++)
{
newsNodes[i] = resultNodes[i];
}
}
}
if(newsNodes != null) {
model.m_newsNodes=newsNodes;
}
}
else{
logger.log("ERROR: 'store' argument not specified.");
}
Response template
The rendering template for the XML response, getNewsHeading.xml.ftl file,
is as follows:
<#ftl ns_prefixes={"D", "http://www.alfrescobook.com/webforms"}>
<news>
<#if m_newsNodes?exists>
<#list m_newsNodes as newsNode>
<#assign newsItemDom = newsNode.xmlNodeModel/>
<#if newsItemDom?exists>
<#assign newsItem = newsItemDom.news>
<#if newsItem?exists>
<newsItem>
<newsId>${newsNode.name</newsId>