Java Foundation API

cancel
Showing results for 
Search instead for 
Did you mean: 

Java Foundation API

resplin
Intermediate
1 2 8,095

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com



Java_APIOverview


Introduction


Alfresco's Java Foundation 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 Explorer Web Client uses this API and is packaged together with the repository in a single .war file for deployment to an application server.


Java Foundation API Reference


For reference material on the Java Foundation API, the first port of call is the Java Doc for the repository project which is updated with each nightly build.


Access to Java Foundation API


The Java Foundation API is in fact 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 (that is, Spring beans) can be found in:


  1. the configuration file /projects/repository/config/alfresco/public-services-context.xml
  2. the service interface org.alfresco.service.ServiceRegistry

There are three approaches to accessing the interfaces in your own code:


  1. Use standard Spring dependency injection (recommended, if your client code is also Spring based)
  2. Manual access via the Spring getBean() method
  3. Indirectly via Alfresco's ServiceRegistry

Spring provides excellent documentation on how to bind Beans together, so that will not be duplicated here.


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 is.



  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();
    ...

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:


  1. Use Spring declarative transaction demarcation (recommended, if your client is also Spring)
  2. Use Alfresco's UserTransaction support

Excellent documentation for method 1 can be found at the Spring Framework site.


Using RetryingTransactionHelper


The prefered method of manually controlling transactions is via the RetryingTransactionHelper.



                RetryingTransactionCallback<Object> txnWork = new RetryingTransactionCallback<Object>()
                {
                    public Object execute() throws Exception
                    {
                        // Do stuff
                        Object result = ...
                        return result;
                    }
                };
                TransactionService transactionService = serviceRegistry.getTransactionService();
                Object result = transactionService.getRetryingTransactionHelper().doInTransaction(txnWork, true);

By using the RetryingTransactionHelper the various concurrency strategies are automatically enforced, transaction rollback scenarios are properly handled and extensive logging can be switched on.

Transactions can be read-only or read-write and optionally continue with any existing transaction or start a completely new transaction.



    /**
     * Execute a callback in a transaction until it succeeds, fails
     * because of an error not the result of an optimistic locking failure,
     * or a deadlock loser failure, or until a maximum number of retries have
     * been attempted.
     *
     * It is possible to force a new transaction to be created or to partake in
     * any existing transaction.
     *
     * @param cb                The callback containing the unit of work.
     * @param readOnly          Whether this is a read only transaction.
     * @param requiresNew       true to force a new transaction or
     *                          false to partake in any existing transaction.
     * @return                  Returns the result of the unit of work.
     * @throws                  RuntimeException  all checked exceptions are converted
     */
    public <R> R doInTransaction(RetryingTransactionCallback<R> cb, boolean readOnly, boolean requiresNew)

Handling UserTransaction Directly


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.

2 Comments
maxdykhno
Member II

Hi, Richard!
Since we've got "three approaches to accessing the interfaces in your own code...". is there any differences in using each of these approach? Maybe there are some cases where it is better to use ServiceRegistry than directly inject NodeService for example?

resplin
Intermediate

This page is out-of-date. Our current documentation and advice is in this section of the documentation:
Java API | Alfresco Documentation 

And here:

Platform extension points | Alfresco Documentation 

But whenever possible, we encourage you to use the modern REST API:

http://api-explorer.alfresco.com