Java API
From AlfrescoWiki
Contents |
[edit] Introduction
Alfresco's Content Management Java Services API is a set of services providing full access to the capabilities of the Alfresco Repository. It is an in-process API meaning that the client must sit within the same process as the Repository. For example, the Alfresco Web Client uses this API and is packaged together with the Repository in a single .war file for deployment to an application server.
[edit] Java Services API Reference
For reference material on the Service API, the first port of call is the Javadoc which is updated with each nightly build.
[edit] Access to Java Services
The Service API is in fact comprised of a set of interfaces; each interface represents a function of the Repository. A Spring Framework Bean is provided as the implementation for each interface.
The list of available public services (i.e. Spring beans) can be found in:
- the configuration file /projects/repository/config/alfresco/public-services-context.xml
- the service interface org.alfresco.service.ServiceRegistry
There are three approaches to accessing the interfaces in your own code:
- Use standard Spring dependency injection (recommended, if your client code is also Spring based)
- Manual access via the Spring getBean() method
- Indirectly via Alfresco's ServiceRegistry
Spring provides excellent documentation on how to bind Beans together, so that won't be duplicated here.
[edit] Alfresco ServiceRegistry
The ServiceRegistry maintains a list of available Repository services and some meta-data about each. In particular, the ServiceRegistry provides access to each service interface. The registry is a service itself and therefore is accessed using either method 1 or 2 as described above.
The static variable SERVICE_REGISTRY found on the interface org.alfresco.service.ServiceRegistry provides the Spring Bean name to lookup by.
The following example demonstrates how to get hold of the Registry, determine if the Node Service is supported, and then access it, if it does.
ApplicationContext appContext = new ClassPathXmlApplicationContext("alfresco/application-context.xml");
ServiceRegistry registry = (ServiceRegistry)appContext.getBean(ServiceRegistry.SERVICE_REGISTRY);
if (registry.isServiceProvided(ServiceRegistry.NODE_SERVICE)
{
NodeService nodeService = registry.getNodeService();
...
[edit] User Transaction
By default, each invocation of a Service method is wrapped in its own transaction. This has been configured via Spring. To control the transaction boundary in your own client code, the following approaches may be taken:
- Use Spring declarative transaction demarcation (recommended, if your client is also Spring)
- Use Alfresco's UserTransaction support
Excellent documentation for method 1 can be found at the Spring Framework site.
Alfresco's UserTransaction may be accessed via the ServiceRegistry as follows:
UserTransaction trx = serviceRegistry.getTransactionService().getUserTransaction();
With a UserTransaction in hand, it is possible to mark the beginning and end of a transaction, thus forcing any service calls within the begin and end to be included in that transaction. For example, the following two NodeService calls are wrapped in the same transaction. Without the UserTransaction, the default behaviour would be for each NodeService call to be in its own transaction.
NodeService nodeService = serviceRegistry.getNodeService();
try
{
trx.begin()
nodeService.createNode(...);
nodeService.createNode(...);
trx.commit();
}
catch(Throwable e)
{
try
{
if (trx.getStatus() == Status.STATUS_ACTIVE)
{
trx.rollback();
}
}
catch(Throwable ee)
{
// Handle double exception in whatever way is appropriate eg. log it
}
throw e;
}
Although the example shows the usage of one service, any mixture of Alfresco's public services can be pulled into the same transaction.
It is important to note that a UserTransaction cannot be re-used. That is, once a commit or rollback has been issued, a new UserTransaction has to be retrieved (via getUserTransaction()) to begin another.
The TransactionUtil provides support for handling the exceptions, rollback and so forth.
TransactionWork<NodeRef> someWork = new TransactionWork<NodeRef>()
{
public NodeRef doWork()
{
...
return resultNodeRef;
}
};
NodeRef nodeRef = TransactionUtil.executeInUserTransaction(transactionService, someWork);
[edit] Examples
There is a package org.alfresco.example in the Repository project. We will be adding concise examples, uncluttered by the stresses of a unit test, to this package.
The first class in there is a very basic SimpleExampleWithContent.

