2.1 Web Scripts

From alfrescowiki

Jump to: navigation, search

Back to 2.1 RESTful API.


NOTE: This document describes features to be found in Alfresco v2.1. (Newer versions: v3)

This page provides the technical details for Web Script development.

See also:

Web Scripts FAQ

Web Scripts Examples

Web Scripts Hello World Quick Start

Alfresco REST Design Guidelines

Contents

Why use Web Scripts?

Web scripts allow you to:

  • Build custom URL-identified and HTTP accessible Content Management Web Services
  • Turn your Alfresco repository into a content management powered HTTP Server
  • Easily access, manage, and cross-link your content via a tailored RESTful API

You do not need tooling or Java knowledge. All you need is your favourite text editor or the Alfresco web client: no compilation, generators, server restarts, or complex installs.

What is a Web Script?

Web scripts enable you to open up Alfresco, and make it accessible to other tools and applications. You can:

  • Provide the Alfresco repository with content services that are accessible from anywhere
  • Query the repository, extract content, and alter the repository behaviour
  • Expose the repository for document management and web content management
  • Provide customized search facilities

Web scripts can generate dynamic feeds from documents that are managed within the Alfresco repository. The document management repository and the WCM repository are both accessible through the web scripting interface. You can have dynamically delivered content that is managed by Alfresco's WCM functionality.

Each web script is bound to a HTTP method and custom URL. A library of URLs may be built up to provide a complete (RESTful or STRESTful) HTTP API. Libraries may be AMPlified allowing them to be installed on any Alfresco server.

See the Web Scripts FAQ for more information.

Types of Web Scripts

There are two types of web script that you can use:

  • Data web scripts
  • User interface web scripts

Data web scripts

Data web scripts return data. The data can be in almost any format. For example, CSV files, XML files, JavaScript objects, and data-interchange formats such as JSON. Data web scripts allow you to make calls to Alfresco from other applications, and from other extensions. Alfresco's OpenSearch has been re-hosted as a series of web scripts.

For example, you could create the following API for a fictitious blog application powered by Alfresco:

Execute a full-text search for blog entries

GET http://<host>:<port>/alfresco/service/sample/blog/search?q=tutorial

Execute a search for blog entries by category

GET http://<host>:<port>/alfresco/service/sample/blog/category/web20

Retrieve meta-data for a blog entry

GET http://<host>:<port>/alfresco/service/sample/blog/2007/03/04/new-release

Update meta-data for a blog entry

POST http://<host>:<port>/alfresco/service/sample/blog/2007/03/04/new-release?status=Draft

Delete a blog entry

DELETE http://<host>:<port>/alfresco/service/blog/2007/03/04/new-release

User interface web scripts

User interface web scripts allow you to dynamically build user interfaces within the Alfresco web client, or within third-party applications. You can create your own rich user interface components, each with its own look and feel. The user interface script can be self-contained, or you can leverage the data from a data web script.

Using Web Scripts in Portals

Portlets can leverage data web scripts as a data API, and can incorporate UI web scripts as widgets.

JSR-168 portlet construction and integration is now much easier with web scripts. Pre-built components provide some of the most common features required in portals, such as document browsing, mapping of web content, tracking of workflow and tasks, and tracking of web content forms, tasks and assets.

These new components use a much easier AJAX-based user interface. This simplifies browsing, hides complex information, and provides detachable previews and summaries. Out-of-the-box integrations with Liferay 4.3 and JBoss Portal 2.6 will be available soon. You create new portlets from simple scripts using FreeMarker or JavaScript.

The dashlets that were discussed earlier are available as JSR-168-compliant portlets. So the same portlets that you see in your Alfresco dashboard can be used in a JSR-168-compliant portal framework.

You can use the web script data API from within a portal. You can make HTTP calls and return data in any data format, such as CSV, XML, and JSON.

Integrating with other applications

It is easy to integrate with other applications. For example, a new Microsoft Word integration built using web script technology provides a simple, light-weight browser control that displays web script components based upon the context of the document being edited.

The plugin provides an Office-tailored set of components. These include a document dashboard for personal context, current tasks and actions available on the document. In addition, the plugin provides a repository browser, a document detail view, task and workflow information, and a pane that provides a federated search using the OpenSearch API.

Components of a Web Script

A web script consists of the following components:

  • A description document, which describes the URL that that will initiate the script. For example, the service is given a short name and description, along with authentication and transactional needs. URL bindings are described as URL templates.
  • An optional execution script, written in Javascript, which will do the actual work. For example, the script may query the Alfresco repository to build a set of data items to render in the response, or for URLs that intend to modify the repository (hopefully, PUT, POST & DELETE method bindings), the script may update the Alfresco repository. The JavaScript has access to all URL arguments, Alfresco services and repository data entry points.
  • One or more FreeMarker templates that will render any output in the correct format for your specific needs. For example, HTML, ATOM, XML, RSS, JSON, CSV, or any combination of these. The URL response is rendered via one of the supplied templates where the chosen template is based on the required response content-type or status outcome. The template has access to all URL arguments, common repository data entry points and any data items built by the optional execution script.

How Script Components Work Together

WebOrientedRestStyleArchitecture.jpg

1. The URL containing the request arrives at the Web Script REST dispatcher.

2. The dispatcher finds the appropriate web script for the URL. If one is found, the dispatcher executes the web script but only after successfully authenticating first, if required. The first step of execution is to invoke the JavaScript bound into the web script.

3. With JavaScript, you have access to the full set of Alfresco repository content services. You can search for information, navigate around the repository, modify information, create new documents, set properties on those documents, move data around, and delete data. In addition, you can implement security policies.

4. The results from the JavaScript are rendered using FreeMarker response templates. The response format can be HTML, ATOM, XML, RSS, JSON, CSV, or any combination of these. You must provide the appropriate templates.

5. The web script REST dispatcher sends the rendered results back via a response using the same protocol as URL request.

6. The web script client receives the response in the request format.

Writing a Web Script

This section demonstrates how to create a web script. The web script in question is the fictitious blog search listed above which performs a full-text search rendering results in both HTML and ATOM formats. Search requires at least guest access.

Writing a web script consists of four steps:

  1. Create the web script.
  2. Store the web script.
  3. Register the web script.
  4. List all the web scripts.

More Web Scripts Examples

See the Web Scripts FAQ for more information.

Getting Started

First, choose a URL and HTTP method.

GET /alfresco/service/sample/blog/search?q={searchTerm}

All web script URLs must start with /alfresco/service (although alternative url prefixes also exist). The rest of the URL is up to you, but must be unique. NOTE the following URL namespaces are reserved for Alfresco use:

/alfresco/service/sample
/alfresco/service/api
/alfresco/service/ui
/alfresco/service/office
/alfresco/service/wcm

Step 1: Creating a Web Script

With a URL decided, it is necessary to bind an implementation to it. Our example blog search implementation will consist of the following files:

blogsearch.get.desc.xml
blogsearch.get.js
blogsearch.get.html.ftl
blogsearch.get.atom.ftl
blogsearch.get.html.400.ftl
blogsearch.get.atom.400.ftl

Creating a web script includes the following steps:

  1. Create a description document.
  2. Create an execution script (optional).
  3. Create a response template.

1. Create a Description Document

The above URL is described by creating an .xml description document in one of the web script folders. For now, assume that all files are placed into the repository folder: /Company Home/Data Dictionary/Web Scripts.

Within any web script folder, sub-folders may be used to organise web scripts. For example, we can place our search web script in the folder

/Company Home/Data Dictionary/Web Scripts/org/alfresco/sample

and within this folder, create the file

blogsearch.get.desc.xml

Naming is important. Web scripts employ convention over configuration for their definition to reduce the amount of required typing. The postfix .desc.xml informs Alfresco that this is a web script description document.

The complete folder and file name

org/alfresco/sample/blogsearch.get.desc.xml

defines

  1. A package of org/alfresco/sample
  2. A service id of blogsearch
  3. A binding to the HTTP GET method


The content of a web script description document is defined as follows (Note: this demonstrates all possible settings):

<webscript>
  <shortname>Blog Search</shortname>
  <description>Find all blog entries whose content contains the specified search term</description>
  <url>/sample/blog/search?q={searchTerm}</url>
  <url>/sample/blog/search.atom?q={searchTerm}</url>
  <url>/sample/b/s?q={searchTerm}</url>
  <url>/sample/b/s.atom?q={searchTerm}</url>
  <format default="html">extension</format>
  <authentication runas="user1">guest</authentication>
  <transaction>required</transaction>
</webscript>

Where:

  • shortname is a human readable name for the web script
  • description (optional) is documentation for the web script
  • url (one or more) is a URL Template to which the web script is bound; variants of the url template which specify a format do not need to be registered, however, they are useful for documentation purposes
  • format (optional) is how the required response content-type is declared on the url; valid values (optional) are:
    • argument specifies the required content-type is declared via the format url argument, for example /search?q=tutorial&format=atom
    • extension specifies the required content-type is declared via the url extension, for example /search.atom?q=tutorial
    • any specifies either of the above is supported
    • Note: if not specified, the default value is any
    • Note: if the URL does not specify a required content-type at all, the default content-type is taken from the (optional) default attribute of the format element. By default, if not set, the html format is assumed. In some cases, a URL may decide upon a response content-type at runtime. For these URLs, specify an empty format, for example format=""
    • Note: if specified, the default attribute must not be empty or blank.
  • authentication (optional) is the required level of authentication; valid values are:
    • none specifies that no authentication is required at all
    • guest specifies that at least guest authentication is required
    • user specifies that at least named user authentication is required
    • admin specifies that at least a named admin authentication is required
    • Note: if not specified, the default value is none
    • Note: the optional runas attribute can be used to declare an alternative user name to run the web script as. This is valid for classpath-stored web scripts only.
  • transaction (optional) is the required level transaction; valid values are:
    • none specifies that no transaction is required at all
    • required specifies that a transaction is required (and will inherit an existing transaction, if open)
    • requiresnew specifies that a new transaction is required
    • Note: if not specified, the default value is none if authentication is also none, otherwise the value is required

The description provides Alfresco with all the necessary information to bind the web script to one or more URLs. It also provides enough to document the web script.

URL Templates

A URL template is simply a URL containing tokens which may be substituted with actual values. The URL template syntax is minimal and simple. Common forms of URL template include:

/content/a/b/c/d.txt
/blog/search?q={searchTerm}
/blog/search?q={searchTerm}&amp;n={numResults}
/blog/category/{category}?n={itemsperpage?}
/user/{userid}

A token of the form {<name>?} means it is optional. Typically, tokens are used for URL arguments, but may also be used for path segments.

Note the third example passes two parameters to the web script. Normally an ampersand (&) is used to separate parameters, though in your template one must use the escaped literal "&amp;" instead.

For now, web scripts do not enforce mandatory arguments. However, it is still useful to provide a full URL template for documentation purposes.

URL templates are specified relative to http://<host>:<port>/alfresco/service.

Which part of the URL is used for binding?

When a URL request is made, Alfresco locates the appropriate web script by finding the closest match to a URL template in a web script description document. The part of the URL template that is used for matching is the static part. This is from the start of the URL template up to either the URL arguments or the first path token, whichever comes first. For example, the above URL templates are matched on:

/content/a/b/c/d.txt (exact match)
/blog/search (starts with match)
/blog/category (starts with match)
/user/ (starts with match)

The following URLs match one of the above:

/content/a/b/c/d.txt
/blog/search
/blog/search?q=tutorial
/blog/category
/blog/category/web20
/user/fred

however, the following do not:

/content/a/b/c/d.txt.plain
/blog
/usr/fred

Response Formats

A web script inherently supports a default response format. A response format is a web script registered short name (for example, atom) for a MIME type/subtype (for example application/atom+xml).

However, it is possible for any web script to support multiple response formats. When this is the case, it is necessary to determine which format to respond with when a web script URL is requested. This is achieved by encoding the format in the URL (subject to web script Description) as either:

  • format url argument, for example /blog/search?q=tutorial&format=atom
  • extension, for example /blog/search.atom?q=tutorial

When the format is not specified in the URL, the default response format is returned. The out-of-the-box formats are:

  • html => text/html
  • text => text/plain
  • xml => text/xml
  • atom => application/atom+xml
  • rss => application/rss+xml
  • json => application/json
  • opensearchdescription => application/opensearchdescription+xml
  • mediawiki => text/plain (Media Wiki markup)
  • portlet => text/html (head & tail chopped)

For example:

GET http://<host>:<port>/service/search/keyword?q=alfresco&format=atom
GET http://<host>:<port>/service/search/keyword.atom?q=alfresco</b>

For more information, see: registered short name

2: Create an Execution Script

A web script may optionally execute some JavaScript on invocation of its respective URL. The JavaScript can perform queries or updates against the Repository. Also, the JavaScript may build a data model that is passed to the appropriate web script response template for subsequent response rendering.

For our example blog search service we create the following file in the same folder as the web script description document

blogsearch.get.js

Again, naming conventions apply where execution script file names have the following structure

<serviceId>.<httpMethod>.js

The full Alfresco JavaScript API is available within web scripts. However, there are some differences with regards to available root objects.

  • document (not available)
  • space (not available)
  • script (not available - TODO: fix this: should be available if script held in repo)
  • companyhome (only available if authenticated)
  • person (only available if authenticated)
  • userhome (only available if authenticated)


Web scripts also have access to the following additional root objects:

argsM
an associative array of any URL parameters (where each key is a parameter name and each value is an array containing the parameter values, even if only one is supplied) - complements the root object args. See example. [sorry, available 2.1 Enterprise onwards].
url
provides access to the URL (or parts of the URL) that triggered the web script.
formdata
provides access to multipart/form-data requests allowing the upload of files via web scripts. [sorry, available 2.1 Enterprise onwards].
model
An empty associative array which 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 is executing as "Guest".
server
An associative array of meta-data properties describing the Repository server hosting the web script.


For our example blog search, we can write the following JavaScript to perform the search:

var nodes = search.luceneSearch("TEXT:" + args.q);
model.resultset = nodes;

NOTE: For simplicity, the above script searches the whole Repository, but it could easily be modified to search within a specific folder or specific type of content.

The result of the search is added to the model root object and given the name resultset. Web script response templates rendered after the execution of the JavaScript will now also have the root object named resultset, which in this case represents an array of nodes that match the search criteria.

Of course, a Web script can also perform updates, in which case, the model root object can be used to record items that have been updated, status, and so on.

Debugging an Execution Script

The Alfresco Server provides a built-in Javascript debugger.

3: Create a Response Template

The final stage of a web script is to render a response for the HTTP request. Multiple response formats may be provided. Responses are rendered by FreeMarker templates.

For our example blog search service, we create the following file in the same folder as the web script description document

blogsearch.get.html.ftl

Again, naming conventions apply where response template file names have the following structure

<serviceId>.<httpMethod>.<format>.ftl

where

  • format specifies the format of the response template whose value is one of the following formats.

The full Alfresco Template API is available within web scripts. However, there are some differences with regards to available root objects:

  • document is not available
  • space is not available
  • template is not available - TODO: fix this: should be available if template held in repo
  • companyhome is only available if authenticated
  • person is only available if authenticated
  • userhome is only available if authenticated


Web scripts also have access to the following additional root objects:

argsM
an associative array of any URL parameters (where each key is a parameter name and each value is an array containing the parameter values, even if only one is supplied) - complements the root object args. See example. [sorry, available 2.1 Enterprise onwards].
guest
A boolean indicating whether the web script is executing as "Guest".
date
A date representing the date and time of the web script request.
server
An associative array of meta-data properties that describe the hosting Alfresco server.
roothome
The Repository root node.
url
An object providing access to the URL (or parts of the URL) that triggered the web script.
webscript
An associative array of meta-data properties that describe this web script.

And remember, the template also has access to any root objects created by the execution script, if one has been associated with the web script.


Web script templates also have access to the following additional methods:

absurl(url)
Returns an absolute URL representation of the passed url. Useful when rendering links within ATOM (and similar formats).
xmldate(date)
Returns an ISO8601 formatted result of the passed date. Useful when rendering dates within XML.
scripturl(queryString)
Returns a url that references this web script. The passed queryString is added to the url. System arguments such as guest and format are automatically added. Note, this method is particularly useful for protection against the runtime environment within which the web script is executing. In some environments (such as a Portal) the url may be encoded.
clienturlfunction(funcName)
Generates a client-side JavaScript function that can generate a URL back to this web script.


For our example blog search, we can write the following FreeMarker to render the HTML response:

<html>
  <body>
    <img src="${url.context}/images/logo/AlfrescoLogo32.png" alt="Alfresco" />
    Blog query: ${args.q}
    <br>
    <table>
      <#list resultset as node>
      <tr>
        <td><img src="${url.context}${node.icon16}"/>
        <td><a href="${url.serviceContext}/api/node/content/${node.nodeRef.storeRef.protocol}/${node.nodeRef.storeRef.identifier}/${node.nodeRef.id}/${node.name?url}">${node.name}</a>
      </tr>
      </#list>
    </table>
  </body>
</html>

Note how the above template makes use of standard root objects, for example ${args.q}, web script specific root objects, for example ${url.context}, and root objects created by the execution script, for example <#list resultset as node>.

Multiple Response Formats

Multiple response formats are simply supported by creating further template files following the naming convention outlined above.

Note: New and updated Templates are automatically registered and will be honoured when the web script is next invoked.

For our example blog search, we can support an ATOM response by adding the following file

blogsearch.get.atom.ftl

whose content is

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <generator version="${server.version}">Alfresco (${server.edition})</generator>
  <title>Blog query: ${args.q}</title> 
  <updated>${xmldate(date)}</updated>
  <icon>${absurl(url.context)}/images/logo/AlfrescoLogo16.ico</icon>
  <#list resultset as node>
  <entry>
     <title>${node.name}</title>
     <link rel="alternate" href="${absurl(url.serviceContext)}/api/node/content/${node.nodeRef.storeRef.protocol}/${node.nodeRef.storeRef.identifier}/${node.nodeRef.id}/${node.name?url}"/>
     <icon>${absurl(url.context)}${node.icon16}</icon>
     <id>urn:uuid:${node.id}</id>
     <updated>${xmldate(node.properties.modified)}</updated>
     <summary>${node.properties.description!""}</summary>
     <author> 
       <name>${node.properties.creator}</name>
     </author> 
  </entry>
  </#list>
</feed>

With our example blog search description document and associated templates, the following URL mappings are made

  • /alfresco/service/blog/search?q=tutorial => HTML template
  • /alfresco/service/blog/search.html?q=tutorial => HTML template
  • /alfresco/service/blog/search?q=tutorial&format=atom => ATOM template
  • /alfresco/service/blog/search.atom?q=tutorial => ATOM template

Response Status

Web scripts use HTTP response status codes to:

  • inform a client of an error situation (for example, item not found)
  • inform a client of an occurrence of an event (for example, item created)
  • instruct a client to perform a follow-up request (for example, authorization required)
  • inform a client of success

Response status codes are set in the execution script via the status root object.

We can add a status to our blog search example indicating that search terms have not been provided on the search URL. We use status code 400 (Bad Request). The execution script is extended as follows:

if (args.q == null || args.q.length == 0)
{
   status.code = 400;
   status.message = "Search term has not been provided.";
   status.redirect = true;
}
else
{
   // perform search as before
   var nodes = search.luceneSearch("TEXT:" + args.q);
   model.resultset = nodes;
}

Redirect allows the rendering of a custom response template for the specified status code. If redirect is not set (that is, false), the response header status code is set but the relevant standard web script response template is used, as would normally apply.

If redirect is true, then an appropriate status response template is searched for. The search is performed in the following order:

Web script specific template named <scriptid>.<method>.<format>.<code>.ftl 
located in the same folder as the web script description document and used for the specified status code only, for example
/org/alfresco/sample/blogsearch.get.html.400.ftl
Web script specific template named <scriptid>.<method>.<format>.status.ftl 
located in the same folder as the web script description document used for any status code, for example

/org/alfresco/sample/blogsearch.get.html.status.ftl

Package level template named <format>.<code>.ftl 
this template is first located in the package of the web script, but if not found, is searched for in the parent package hierarchy, up to the root package, for example
/org/alfresco/sample/html.400.ftl
Package level template named <format>.status.ftl 
this template is first located in the package of the web script, but if not found, is searched for in the parent package hierarchy, up to the root package, for example
/org/alfresco/sample/html.status.ftl
Default template named <code>.ftl 
located in the root package and always renders html, for example
/400.ftl
Default template named status.ftl 
located in the root package (provided out-of-the-box) and always renders html, for example
/status.ftl

Status Response templates have access to the same root objects as standard web script response templates with the addition of the 'status' object. The exception is that the default templates /<code>.ftl and /status.ftl only have access to the root objects 'url', 'status', 'server' and 'date'.

To provide a custom Bad Request status response for our blog search we create the following file in the same folder as the web script description document

blogsearch.get.html.400.ftl

whose content is

<html>
  <body>
    ${status.message}
  </body>
</html>

We can also provide a meaningful response for atom requests which can be machine read:

blogsearch.get.atom.400.ftl
<?xml version="1.0" encoding="UTF-8"?>
<response>
  <code>${status.code}</code>
  <codeName>${status.codeName}</codeName>
  <codeDescription>${status.codeDescription}</codeDescription>
  <message>${status.message}</message>
</response>

Remember, these templates are optional, as the search for an appropriate status template will always eventually find the default template /status.ftl.

Localization of Status Code Messages

The resource bundle /alfresco/messages/webscripts.properties contains status code names and descriptions for all HTTP codes.

Step 2: Storing a Web Script

Store your web scripts in any of the following folders. These folders are listed in the sequence in which Alfresco searches for scripts:

  1. repository folder: /Company Home/Data Dictionary/Web Scripts Extensions
  2. repository folder: /Company Home/Data Dictionary/Web Scripts
  3. class path folder: /alfresco/extension/templates/webscripts
  4. class path folder: /alfresco/templates/webscripts

Within any of these folders, you can use subfolders to organize web scripts.

Warning!

Do not store web scripts in:

/org/alfresco

or any of its subfolders. These folders are reserved for Alfresco use.

Step 3: Registering a Web Script

New and updated web scripts can be registered without restarting the Alfresco server. This makes it easy to use the Alfresco repository to develop web scripts.

To register a web script:

  1. In the address bar of your browser, type the following URL: http://<host>:<port>/alfresco/service/
    The Web Scripts Home page appears.
  2. Click on Refresh list of Web Scripts. Alfresco registers any scripts that you have added since the last time that you clicked this button.

Step 4: Listing all Registered Web Scripts

Alfresco provides URLs for listing all registered web scripts and refreshing the list of web scripts when new scripts are added or removed.

The URLs for listing all web scripts are

http://<host>:<port>/alfresco/service/
http://<host>:<port>/alfresco/service/index

The resulting HTML page provides a Refresh button to update the list.

Configuring a Web Script

Configuration is accessed via the 'config' root object, which is available during both script and template execution.

There are 3 types of configuration, 'global', 'scoped' and 'script'. Global and scoped config are specified in alfresco config files, as used in the Web Client, whereas script config is defined in an XML with an arbitary structure stored locally with the web script. The following sections describe these in more detail.

Global and Scoped Config

Global and scoped config is read using the Config_Service, by default the following files are read:

  • alfresco/webscript-framework-config.xml
  • alfresco/extension/webscript-framework-config-custom.xml
  • any webscript-framework-config-custom.xml found in the META-INF folder of any JAR on the classpath

Config sections that do not have an evaluator or condition are known as 'global' config sections i.e. these will always appear in a config lookup, a typical global config section has the following appearance.

<config>
  <server>
     <errorpage>/jsp/error.jsp</errorpage>
     <loginpage>/jsp/login.jsp</loginpage>
     <guesthome enabled="true">/jsp/guesthome.jsp</guesthome>
     <url>/</url>
     <url>/alf</url>
     <url>/alfresco</url>
  </server>
</config>

Scoped config, on the other hand, is a config section that does have an evaluator and condition, for example.

<config evaluator="string-compare" condition="Remote">
   <remote>
      <endpoint>http://localhost:8080/alfresco</endpoint>
   </remote>
</config>

Accessing Global and Scoped Config

Accessing the configuration above is achieved using the same techniques and syntax as any other model data, the global config is exposed via the 'config.global' root object and the scoped config is exposed via the 'config.scoped' root object.

For example to access the server config from the example above the following syntax would be used in a JavaScript:

var serverCfg = config.global.server;

and the following syntax would be used in a FreeMarker template:

<#assign serverCfg=config.global.server>

Accessing scoped config is slightly different in that some context is required (to perform the scoped lookup against). This is achieved using the syntax to access a Map. For example to access the remote config in the scoped "Remote" section from the example above the following syntax would be used in a JavaScript:

var remote = config.scoped["Remote"].remote;

and the following syntax would be used in a FreeMarker template:

<#assign remoteCfg=config.scoped["Remote"].remote>

Object Model

When accessing configuration the object model of the result will differ depending on the element accessed, this is determined by whether the element has a custom element reader registered. If it doesn't the generic implementation is used (org.alfresco.config.element.GenericConfigElement).

The generic implementation provides the following API:

  • .name
  • .value
  • .attributes
  • .children
  • .childrenMap

name: string representing the name of the element value: string representing the text value of the element attributes: Map of attributes for the element children: List of child elements childrenMap: Map of child element lists by element name whose

Some examples of using this API to access elements of the "server" example above are shown below.

config.global.server.children[0].name; will return 'errorpage' config.global.server.children[0].value; will return '/jsp/error.jsp' config.global.server.children[2].attributes["enabled"]; will return 'true' config.global.server.childrenMap["url"][1].value will return '/alf' (the value of the 2nd child element named 'url')

This syntax is the same whether its used in a script or template, furthermore, the standard builtin features of the scripting or templating language can be used, for example to get the number of child elements would be done as follows in a FreeMarker template:

server config has ${config.global.server.children?size} child elements.

If a custom element reader has been registered the object representing the element determines the object model that needs to be used. However, all custom implementations extend the generic implementation so the API described above should be available, but the reason for having a custom implementation is to provide a cleaner API so in theory the generic approach above shouldn't be required.

Take the "server" configuration, if this had a custom implementation that exposed the child elements as get methods the values of the errorpage, loginpage and guesthome elements could be retrieved as follows:

config.server.errorpage
config.server.loginpage
config.server.guesthome

Script Config

Script config is read from an XML file packaged with the web script. For example, given a webscript called "myscript", in the simplest case there will be a 'myscript.get.desc.xml' file and a 'myscript.get.html.ftl' file. To add config to the webscript add a file named 'myscript.get.config.xml'.

The config service is not used to load this file it is loaded as is by the script or template engine, the builtin XML parsing support is then used to provide access to the full content.

The sections below highlight how to access the XML in scripts and templates, both sections will use the following XML as an example:

<test id="hello">
   <foo>
      <bar>bar1Value</bar>
      <bar>bar2Value</bar>
      <bar>bar3Value</bar>
   </foo>
</test>

JavaScript Access

The JavaScript engine uses E4X which is essentially "ECMAScript For XML", for a quick tutorial see http://www.w3schools.com/e4x/default.asp and/or http://wso2.org/library/1050

Shown below are some examples of E4X syntax being used to access the example XML above.

var s =  new XML(config.script);
logger.log("id of test element = " + s.@id);
logger.log("value of first bar element = " + s.foo.bar[0]);
logger.log("values of all bar elements:");
for each(var b in s..bar)
{
   logger.log(b);
}

FreeMarker Access

FreeMarker has builtin support for processing XML data, see the FreeMarker documentation for details and examples (http://www.freemarker.org/docs/xgui.html).

Shown below are some examples of FreeMarker syntax being used to access the example XML above.

id of test element = ${config.script.test.@id}<br/>
value of first bar element = ${config.script.test.foo.bar[0]}<br/>
values of all bar elements:<br/><ul>
<#list config.script.test.foo.bar as b>
<li>${b}</li>
</#list>
</ul>

Invoking a Web Script

Web scripts are URL addressable and HTTP accessible, so it is a case of putting together the correct HTTP request.

For example, using GET

http://<host>:<port>/alfresco/service/sample/blog/search?q=tutorial
http://<host>:<port>/alfresco/wcservice/sample/blog/search?q=tutorial

Note that all web scripts are made available at both of the above locations, the difference being that the first uses HTTP Basic Authentication, while the second uses the same authentication mechanism as the web client (which can be configured in a number of different ways).

The first address is useful for external systems that wish to programmatically invoke Alfresco RESTfully (that is, using standard HTTP mechanisms), whereas the second is useful when single sign on is required across both the web client and the web script.

Security

JavaScript, Templates and Java code associated with a web script are executed as the currently authenticated user at the time the web script is invoked. Some web scripts do not require authentication, in which case, they either do not touch the Alfresco Repository, or they execute as a pre-defined user.

If a web script requires authenticated access and the request is unauthenticated, an appropriate login dialog may be first presented. Upon successful login, the web script is then executed.

Authorized Access

Web scripts may allow authenticated access. To force authenticated access specify the following URL argument:

alf_ticket=<ticket>

For example

http://<host>:<port>/alfresco/service/sample/blog/search?q=tutorial&alf_ticket=<ticket>
Guest Access

Web scripts may allow guest access. To force guest access specify the following URL argument:

guest=true

For example

http://<host>:<port>/alfresco/service/sample/blog/search?q=tutorial&guest=true
Hiding Repository Hosted Web Scripts

Web scripts held in the repository (under Data Dictionary) may be hidden from all users except for those that have responsibility for maintaining them. This is achieved by simply removing Read access to those who do not need to know of them. Everyone will still be able to execute hidden web scripts as long as they are first authenticated (if the web script requires authentication).

Logging

The Web Scripts Framework provides logging of web script registration and execution.

HTTP Method Tunneling

Not all clients can issue all HTTP methods. In the most severe case, a client may be restricted to GET and POST only. In this situation, web scripts provide two mechanisms for issuing any HTTP method via POST:

HTTP Request Header 'X-HTTP-Method-Override'
URL parameter 'alf_method
Note: this approach takes priority over the Request Header, if both specified

In either case, the value is set to the HTTP method name to be invoked.

For example, if the HTTP DELETE method is not supported by a client, but the client wishes to delete a blog entry, the following may be issued:

POST X-HTTP-Method-Override=DELETE /alfresco/service/sample/blog/2007/03/04/new-release
POST /alfresco/service/sample/blog/2007/03/04/new-release?alf_method=DELETE

Update: HEAD builds from 17th Jan onwards...

GET also supports the URL parameter alf_method allowing, for example, testing of (some) non-GET methods via a Browser URL.

Forcing Success Response Status

Not all clients can gracefully handle non-success HTTP Responses, for example, the Flash runtime player - the runtime for Adobe Flex applications.

In this situation, web scripts provide a mechanism to force all HTTP Responses to indicate success in their Response Header. However, the Response body will still represent the content as if a non-success status had occurred.

To force HTTP Response Header success set the following HTTP Request Header:

alf-force-success-response = true

JSON Callbacks

If your web scripts provide JSON responses, it is likely they will be invoked directly from within a Web Browser via the XMLHttpRequest object. However, due to security reasons, you may run into cross-domain issues, a restriction that requires you to proxy your requests on the server side. Typically, to workaround these issues, public services such as Yahoo! JSON Services provide a callback mechanism.

Web scripts also provide this mechanism which wraps the JSON output text in parentheses and a function name of your choosing. A callback is invoked by adding the following URL parameter on JSON URL requests:

alf_callback=function

where function is the name of a client-side javascript function to be invoked.

The following simple HTML page demonstrates this:

<html>
  </body>
    <script>
      function showTitle(res)
      {
        alert(res.feed.title);
      }
    </script>
    <script src="http://localhost:8080/alfresco/service/sample/blog/category/web20.json&alf_callback=showTitle"/>
  </body>
</html>

This will result in the JSON response looking like this:

showTitle( ...json output... );

Cache Control

(sorry, available 2.1 Enterprise onwards)

A web script may specify how its response is cached. See example. Each Web Script Runtime may or may not adhere to the caching requirements of the web script; if the runtime does not support caching, the requirements are just ignored. Alfresco 2.1 caching is only supported by the Servlet Runtime, by virtue of caching built into the Web Browser or a Proxy server.

Definition-time Cache Control

Definition-time cache control is optionally specified via the Web Script Description. An example of a definition-time cache control is:

<webscript>
  ...
  <cache>
    <never>false</never>
    <public/>
    <mustrevalidate/>
  </cache>
</webscript> 

Where:

  • never (optional) specifies whether caching should be applied at all; valid values (optional) are:
    • true (default) specifies the web script response should never be cached
    • false specifies the web script response may be cached
    • Note: If never is not specified, the default is true
  • public (optional) specifies whether authenticated responses should be cached in a public cache; valid values (optional) are:
    • true (default) specifies the web script authenticated response may be cached in a public cache
    • false specifies the web script authenticated response may not be cached in a public cache
    • Note: If public is not specified, the default is false
  • mustrevalidate (optional) specifies whether a cache must re-validate its version of the web script response in order to ensure freshness; valid values (optional) are:
    • true (default) specifies that validation must occur
    • false specifies that validation may occur
    • Note: If mustrevalidate is not specified, the default is true

Run-time Cache Control

Run-time cache control is optionally specified via the root object cache which is available to the web script execution script. At run-time, expiry criteria may be set, and definition-time controls may be overridden.

Java-backed Web Scripts

Sometimes, scripts and templates are not powerful enough to implement the required functionality behind a URL. For example, streaming content.

For these scenarios it is possible to bind an Alfresco Spring configured Java Bean into the web script. The Java Bean may take full control, or work in conjunction with the script and templates.

Spring Bean Declaration

To bind a Spring bean to a web script it is only necessary to create a bean with an id of the following structure:

id="webscript.<packageId>.<serviceId>.<httpMethod>"

and ensure its parent is the "webscript" bean:

parent="webscript"

Note: <packageId> is the package (directory) that the Web Script descriptor (.desc.xml file) is located in, not the package of the Java class that implements the logic for the Web Script.

For example:

<bean id="webscript.org.alfresco.sample.blogsearch.get"
      class="org.alfresco.sample.BlogSearch"
      parent="webscript" />

Note that the bean id is made up of:

  • prefix = webscript (must always start with this value)
  • packageId = org.alfresco.sample
  • serviceId = blogsearch
  • httpMethod = get

From this we can determine that the descriptor for this Web Script is called blogsearch.get.desc.xml and is located in the directory org/alfresco/sample (either in the repository or in the classpath, as described at Web Scripts#Step_2:_Storing_a_Web_Script).

As with any Spring bean, other service(s) that your Java class requires (including the Alfresco APIs) may be dependency injected into your Java bean.

Web Script Java Class

The Java Class must implement the Java Interface:

org.alfresco.web.scripts.WebScript

which declares the following methods:

/**
 * Gets the Service Description
 * 
 * @return service description
 */
public WebScriptDescription getDescription();
    
/**
 * Execute service
 * 
 * @param req
 * @param res
 * @throws IOException
 */
public void execute(WebScriptRequest req, WebScriptResponse res)
  throws IOException;

Java Helper Classes

Abstract helper classes are also provided to simplify the development of a Java backed Web Script.

The first helper class is:

org.alfresco.web.scripts.AbstractWebScript

which allows a web script to take full control over the request. This is achieved by providing an implementation of the execute method. The helper class provides access to information such as the web script description document and methods for invoking JavaScript and templates.

The second helper class is:

org.alfresco.web.scripts.DeclarativeWebScript

which allows a web script to mix Java, JavaScript, and templates. This kind of web script supports all the behaviour described in this document, with the addition of first executing some Java. As with the execution script, the Java code can build a data model that is available to Response templates. The Java to be executed is placed into the executeImpl method.

Managing Response Status

A Java implemented web script also has support for response status codes. There are two approaches to sending a response code:

Approach 1 - Throw an Exception

All exceptions thrown from a web script are caught by the web script Runtime and converted to response status codes. By default, the status code 500 (Internal Error) is used. However, the exception WebScriptException supports the constructor:

public WebScriptException(int statusCode, String message)

This constructor is used to explicitly set a response code in an error situation, for example

if (req.getParameter("q") == null || req.getParameter("q").length() == 0)
{ 
   throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Search term not provided");
}

Using this approach will always render the relevant status response template.

Approach 2 - Explicit Setting of Response Status

The helper class DeclarativeWebScript provides the method executeImpl whose signature is:

protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status)

The status argument may be used to explicitly set a response status code & message, as well as control the redirect to a status response template, for example

if (req.getParameter("q") == null || req.getParameter("q").length() == 0)
{
   status.setCode(HttpServletResponse.SC_BAD_REQUEST);
   status.setMessage("Search term not provided");
   status.setRedirect(true);
   return;
}

Exceptions may be handled as follows:

catch(AuthenticationException e)
{
   status.setCode(HttpServletReponse.SC_FORBIDDEN);
   status.setMessage("Invalid username & password");
   status.setException(e);
   status.setRedirect(true);
}

Standalone Test Server

Web scripts naturally live within a web server. This can hamper testing, in particular, the development of unit tests, or the testing of advanced Java web scripts.

To ease testing (and also to remove lengthy web application build/deploy times), the following standalone test harness is provided

org.alfresco.web.scripts.TestWebScriptServer

It supports two modes of operation:

  • Mock Web Server (interactive testing)
  • Helper methods for executing web script requests (automated testing)

Mock Web Server

Just start the TestWebScriptServer application (it supports a main entry point) and interact with it via the one of the following commands:

   ##
   ##  Meta commands 
   ## 
   
   ok> help 
   
       List this help. 
   
   ok> r 
   
       Repeat last command. 
   
   ok> user [<userName>] 
   
       Switch to specified <userName>.  If <userName> is omitted, the currently 
       selected user is shown.
       
       A ticket may be specified instead of username. 
   
   ok> quit | exit
   
       Quit this Web Script server.
   
   ## 
   ##  HTTP Requests
   ## 
   
   ok> get <path>
   
       Issue a HTTP GET request to the Web Script located at <path>.  The response
       is dumped to the console.
       
       <path> URL relative to /alfresco/service
       
       e.g. get /sample/blog/search?q=tutorial
   
   ok> put <path>
   
       Issue a HTTP PUT request to the Web Script located at <path>.  The response
       is dumped to the console.
       
       <path> URL relative to /alfresco/service
       
   ok> post <path>
   
       Issue a HTTP POST request to the Web Script located at <path>.  The response
       is dumped to the console.
       
       <path> URL relative to /alfresco/service
   
   ok> delete <path>
   
       Issue a HTTP DELETE request to the Web Script located at <path>.  The response
       is dumped to the console.
       
       <path> URL relative to /alfresco/service
       
   ok> tunnel <encoding> <method> <path>
   
       Tunnel a request via POST.
       
       The actual <method> is encoded as either the URL parameter named alf:method or 
       the request header named X-HTTP-Method-Override as specified via the <encoding>
       parameter:
       
       param - encode method as URL parameter
       header - encode method in Request Header
       
       e.g. to tunnel 'get /index' via post (where method is encoded in header) issue
       
       tunnel header get /index
      
   ## 
   ##  Request Header Commands 
   ## 
   
   ok> header 
   
       Show all defined headers. 
   
   ok> var <headerName>=<headerValue> 
   
       Define or update a header value. 
   
       <headerName> header name 
       <headerValue> header value 
   
       e.g. 
   
       header alf-force-success=true 
   
   ok> header <headerName>= 
   
       Delete an existing header value. 
   
       <headerName> header name 
       
   ## 
   ##  end 
   ## 

For example (to invoke our example blog search Web Script):

 ok> get /sample/blog/search?q=tutorial
   <html>
    <body>
      <img src="/alfresco/images/logo/AlfrescoLogo32.png" alt="Alfresco" />
      Blog search: tutorial
      <br>
      <table>
       <tr>
         <td><img src="/alfresco/images/filetypes/_default.gif"/>
         <td><a href="/alfresco/download/direct/workspace/SpacesStore/d0ea49aa-cda3-11db-a118-718e716a085b/Alfresco-Tutorial.pdf">Alfresco-Tutorial.pdf</a>
       </tr>
      </table>
    </body>
  </html>
 78ms

Running Mock Test Server

As mentioned above, the Mock Test Server has a main method. The easiest way to run it is through Eclipse, if you already have it setup for development. Just use a RunAs Java Application and run TestWebScriptServer. You'll need to point your repository and a database at an existing repository.

Another way is to create a script that includes all the jars in WEB-INF\lib in the classpath, and starts up the server.

Unit Test Helper Methods

Within a unit test, the following pattern may be used:

// retrieve an instance of the test server
TestWebScriptServer server = TestWebScriptServer.getTestServer();

// submit a request
MockHttpServletResponse res = server.submitRequest("get", "/blog/search?q=tutorial");

// process response
byte[] content = res.getContentAsByteArray();
String contentAsString = res.getContentAsString();

Unit Testing a Web Script

Only available since 3.0

When you write a data web script, it is recommended that you also write a corresponding unit test. This ensures that all elements of the script are working as expected. Re-running the test periodically also ensures that functionality and features do not regress as development progresses.

A web script unit test can be created by extending the base class org.alfresco.repo.web.scripts.BaseWebScriptTest. This base TestCase encapsulates a reference to an initialized TestWebScriptServer, which can be accessed and used to execute web scripts.

There are also four methods that help when making a call to a web script:

  • protected MockHttpServletResponse getRequest(String url, int expectedStatus)
  • protected MockHttpServletResponse deleteRequest(String url, int expectedStatus)
  • protected MockHttpServletResponse postRequest(String url, int expectedStatus, String body, String contentType)
  • protected MockHttpServletResponse putRequest(String url, int expectedStatus, String body, String contentType)

Each method name indicates which HTTP method will be used when the request is submitted. The URL argument contains the URL of the web script that is to be submitted to the test web script server. The URL should not be fully qualified, instead it should start after the /alfresco/service part of a standard URL. For example /api/sites.

The expected status argument indicates the expected status code of the resulting response. If the actual status code resulting from the request is different from the expected code, an assert failure will be raised and the unit test will fail. If the received status code is 500 (internal error), the associated stack trace will be outputted to standard out for information.

The post and put methods also take a body and content type arguments. The body string makes up the body of the request that is sent to the test server, whilst the content type is set on the contentType header value. For example, application/json.

Example

public class SiteServiceTest extends BaseWebScriptTest
{

   private static final String URL_SITES = "/api/sites";
   private static final String URL_MEMBERSHIPS = "/memberships";

   ...

   public void testPostMemberships() throws Exception
   {
       // Create a site
       String shortName  = GUID.generate();
       createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
        
       // Build the JSON membership object
       JSONObject membership = new JSONObject();
       membership.put("role", SiteModel.SITE_CONSUMER);
       JSONObject person = new JSONObject();
       person.put("userName", USER_TWO);
       membership.put("person", person);
        
       // Post the memebership
       MockHttpServletResponse response = postRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS, 200, membership.toString(), "application/json");
       JSONObject result = new JSONObject(response.getContentAsString());
        
       // Check the result
       assertEquals(SiteModel.SITE_CONSUMER, membership.get("role"));
       assertEquals(USER_TWO, membership.getJSONObject("person").get("userName")); 
       
       // Get the membership list
       response = getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS, 200);   
       JSONArray result2 = new JSONArray(response.getContentAsString());
       assertNotNull(result2);
       assertEquals(2, result2.length());
   }

   public void testGetMembership() throws Exception
   {
       // Create a site
       String shortName  = GUID.generate();
       createSite("myPreset", shortName, "myTitle", "myDescription", true, 200);
       
       // Test error conditions
       getRequest(URL_SITES + "/badsite" + URL_MEMBERSHIPS + "/" + USER_ONE, 404);
       getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/baduser", 404);
       getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_TWO, 404);
        
       // Test GET Membership
       MockHttpServletResponse response = getRequest(URL_SITES + "/" + shortName + URL_MEMBERSHIPS + "/" + USER_ONE, 200);
       JSONObject result = new JSONObject(response.getContentAsString());
        
       // Check the result
       assertEquals(SiteModel.SITE_MANAGER, result.get("role"));
       assertEquals(USER_ONE, result.getJSONObject("person").get("userName")); 
   }

   ...
  
}

Content Streaming Web Scripts

Available from 3.0

It is often desirable for a web script to stream back binary content directly from the repository back to the client. This is possible using a purely Java backed webscript, but a more declarative style provides more implementation flexibility.

This can be achieved by using the StreamContent kind of webscript. This allows a JavaScript file to be executed, as per a normal declarative web script. Once the script has been executed it used information placed within the shared model to determine what content to stream back to the client. There is, therefore, no corresponding template for this kind of declarative web script.

Describing a ContentStream WebScript

When describing a content stream web script the kind attribute of the root webscript tag must be set to "org.alfresco.repository.content.stream". This will ensure the correct web script implementation is used, see the following example:

<webscript kind="org.alfresco.repository.content.stream">
  <shortname>Thumbnails</shortname>
  <description>Get a named thumbnail for a content resource</description>
  <url>/api/node/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}</url>  
  <url>/api/path/{store_type}/{store_id}/{id}/content{property}/thumbnails/{thumbnailname}</url>
  <format default="">argument</format>
  <authentication>guest</authentication>
  <transaction>required</transaction>
</webscript>

Note that the format has not been set. This is because the resulting format will be matched to the mimetype of the content being returned to the client.

Setting the content to stream in JavaScript

.. TODO

Overview of ContentStream model properties

Appendix A: Web Script Root Objects

formdata

A host object providing access to multipart/form-data requests allowing file upload from a web script. See example. (sorry, 2.1 Enterprise onwards).

Note: You must use enctype="multipart/form-data" in your form tag or the formdata variable will not be populated with fields.

hasField
boolean indicating the existence of a named form field in the multipart request
fields
an array of formfield where each entry represents a field within the multipart request

formfield

A host object providing access to a form field within a multipart/form-data request.

name
the name of the form field (Note that form fields may not be uniquely named)
isFile
boolean indicating whether this field represents a file (content)
value
string representing the field value (in the case of isFile is true, a best effort conversion is attempted)
content
a ScriptContent representing the content of the field
mimetype
the mimetype of the content (or null, if isFile is false)
filename
the filename of the source file used to provide the content (or null, if isFile is false, or a filename was not provided)

url

A host object providing access to the URL (or parts of the URL) that triggered the web script.

context
Alfresco context path, for example /alfresco
serviceContext
Alfresco service context path, for example /alfresco/service
service
Web script path, for example /alfresco/service/blog/search
full
Web script URL, for example /alfresco/service/blog/search?q=tutorial
args
Web script URL arguments, for example q=tutorial
match
The part of the web script URL that matched the web script URL template
extension
The part of the web script URL that extends beyond the match path (if there is no extension, an empty string is returned)


For example, imagine a web script URL template of

/user/{userid}

and a web script request URL of

/alfresco/service/user/fred?profile=full&format=html

The url root object will respond as follows:

  • url.context => /alfresco
  • url.serviceContext => /alfresco/service
  • url.service => /alfresco/service/user/fred
  • url.full => /alfresco/service/user/fred?profile=full&format=html
  • url.args => profile=full&format=html
  • url.match => /user/
  • url.extension => fred

status

An associative array of response status properties that allow control over the status and content of the web script response.

code
(read/write) status code (primarily a HTTP status code, but can be any number)
codeName
(read) human readable status code name
codeDescription
(read) human readable status code description
message
(read/write) status message
redirect
(read/write) a boolean indicating whether to redirect to a status specific response template
exception
(read/write) the exception (if any) which has caused this status
location (sorry, enterprise 2.1.2 onwards)
(read/write) the absolute URI to which the client should resubmit a request - often used with 3xx redirect status codes. See example.

cache

An associative array of cache control properties that allow control over how the web script response is cached. See example. (sorry, 2.1 Enterprise onwards).

neverCache
(read/write boolean) control whether web script response should be cached at all; true means never cache. If not set, the default value is specified by the cache control section of the web script definition.
isPublic
(read/write boolean) control whether web script response should be cached by public caches. If not set, the default value is specified by the cache control section of the web script definition.
mustRevalidate
(read/write boolean) control whether cache must re-validate its version of the web script response to ensure freshness. If not set, the default value is specified by the cache control section of the web script definition.
maxAge
(read/write long) specifies the maximum amount of time (in seconds, relative to the time of request) that the response will be considered fresh. If not set, the default value is null.
lastModified
(read/write date) specifies the time that the content of the response last changed. If not set, the default value is null.
ETag
(read/write string) specifies a unique identifier that changes each time the content of the response changes. If not set, the default value is null.

server

An associative array of meta-data properties that describe the hosting Alfresco server.

versionMajor
server major version number, for example 1.2.3
versionMinor
server minor version number, for example 1.2.3
versionRevision
server revision number, for example 1.2.3
versionLabel
server version label, for example Dev
versionBuild
server build number, for example build-1
version
server version, for example major.minor.revision (label)
edition
server edition, for example Enterprise
schema
server schema, for example 10

webscript

An associative array of meta-data properties describing the web script.

id
The web script Id
shortName
The web script short name
description
The web script description
defaultFormat
The default response format if none explicitly specified in web script URL
formatStyle
The accepted ways of specifying the format in the web script URL
URIs
A (string) array of URL templates
method
HTTP Method
requiredAuthentication
required level of authentication
requiredTransaction
required level of transaction
storePath
the path of the persistent store where the web script is stored
scriptPath
the path (within storePath) of web script implementation files
descPath
the path (within storePath) of the web script description document
Personal tools
Download and go
© 2014 Alfresco Software, Inc. All Rights Reserved. Legal | Privacy | Accessibility