SlideShare uma empresa Scribd logo
1 de 151
Baixar para ler offline
API Development Course
Copyright (c) 2007 by Alfresco and others.
    Information in this document is subject to change without notice. No part of this document may
    be reproduced or transmitted in any form or by any means, electronic or mechanical, for any
    purpose, without the express written permission of Alfresco. The trademarks, service marks,
    logos or other intellectual property rights of Alfresco and others used in this documentation
    (“Trademarks”) are the property of Alfresco and their respective owners. The furnishing of this
    document does not give you license to these patents, trademarks, copyrights or other intellectual
    property except as expressly provided in any written agreement from Alfresco.
    The United States export control laws and regulations, including the Export Administration
    Regulations of the U.S. Department of Commerce, and other applicable laws and regulations
    apply to this documentation which prohibit the export or re-export of content, products, services,
    and technology to certain countries and persons. You agree to comply with all export laws,
    regulations and restrictions of the United States and any foreign agency or authority and assume
    sole responsibility for any such unauthorized exportation.
    If you need technical support for this product, contact Customer Support by email at
    support@alfresco.com. If you have comments or suggestions about this documentation, contact
    us at documentation@alfresco.com.
    This edition applies to version 2.1 of the licensed program.




2
Contents
   Introduction................................................................................................................................ 6
        Welcome.............................................................................................................................. 7
             How this course is delivered....................................................................................... 7
             Course Schedule......................................................................................................... 7
             How Prepared are You?..............................................................................................8
             Topics not Covered..................................................................................................... 8
             Introductions.................................................................................................................8
   Getting Started...........................................................................................................................9
        Alfresco SDK..................................................................................................................... 10
             Introduction.................................................................................................................10
             Downloading and Unpacking the Alfresco SDK........................................................ 10
             Importing the Alfresco SDK projects into Eclipse......................................................11
             Associating Source Code and Javadocs with the Alfresco Libraries......................... 14
             SDK samples............................................................................................................. 16
             SVN Repository......................................................................................................... 19
             SDK Reference.......................................................................................................... 20
        Best Practices....................................................................................................................22
             Coding Standards...................................................................................................... 22
             Alfresco Module Packages (AMP).............................................................................22
        Alfresco Repository Architecture....................................................................................... 24
             Out of the Box........................................................................................................... 24
             Service & Component Architecture........................................................................... 25
             Repository Foundation Services API.........................................................................27
             Repository APIs......................................................................................................... 28
             Repository Server Protocols...................................................................................... 29
             Terminology................................................................................................................30
   Developing against the Alfresco Repository........................................................................33
        Spring Framework............................................................................................................. 34
             Introduction.................................................................................................................34
             Bean Factory..............................................................................................................34
             Inversion of Control (IoC).......................................................................................... 35
             Application Context.................................................................................................... 39
        Foundation Services API................................................................................................... 40
             Introduction.................................................................................................................40
             Access to Repository Foundation Services...............................................................40
             FirstFoundationClient walkthrough............................................................................ 40
             Other Foundation Services........................................................................................ 48
        JCR API............................................................................................................................. 50
             Introduction.................................................................................................................50
             JCR Compliance Levels............................................................................................ 50
             JCR Repository Model...............................................................................................50




                                                                                                              API Development Course 3
FirstJCRClient Walkthrough.......................................................................................51
                      JCR Transactions...................................................................................................... 53
            Web Services API............................................................................................................. 55
                 Introduction.................................................................................................................55
                 Available Web Services.............................................................................................55
                 Access to Web Services in Java...............................................................................55
                 Web Services Data Types.........................................................................................56
                 Content Manipulation Language (CML).....................................................................56
                 FirstWebServiceClient Walkthrough.......................................................................... 57
            Separating Concerns using AOP...................................................................................... 61
                 Public Services and AOP proxies............................................................................. 61
                 Security Enforcement.................................................................................................61
                 Transaction Management.......................................................................................... 64
        Extending the Alfresco Repository....................................................................................... 69
            Repository Policies............................................................................................................ 70
                 Introduction.................................................................................................................70
                 Available Policies....................................................................................................... 70
                 Policy Types...............................................................................................................71
                 Custom Aspect with Behaviour Howto...................................................................... 71
            Repository Actions.............................................................................................................79
                 Introduction.................................................................................................................79
                 Repository Action Howto........................................................................................... 79
                 Repository Action with Parameters Howto................................................................ 85
            Content Transformers........................................................................................................91
                 Introduction.................................................................................................................91
                 Content Transformer Howto...................................................................................... 91
                 ContentTransformerRegistry...................................................................................... 95
                 Further Reading......................................................................................................... 97
            Metadata Extractors...........................................................................................................98
                 Introduction.................................................................................................................98
                 MetadataExtracterRegistry.........................................................................................98
                 Metadata Extractor Howto......................................................................................... 99
                 Further Reading....................................................................................................... 103
        Extending the Alfresco Web Client..................................................................................... 105
            JavaServer Faces............................................................................................................106
                 Introduction...............................................................................................................106
                 Login Page Walkthrough......................................................................................... 106
            Actions Framework.......................................................................................................... 116
                 Introduction...............................................................................................................116
                 Update UI Action Walkthrough................................................................................ 116
                 Actions Framework Reference................................................................................ 120
            Dialog Framework............................................................................................................123
                 Introduction...............................................................................................................123




4 Alfresco Enterprise Edition Version 3.2
Custom Dialog Howto..............................................................................................123
             Further Information.................................................................................................. 128
         Dialog Framework Reference.................................................................................. 130
    Wizard Framework...........................................................................................................132
         Introduction...............................................................................................................132
         Custom Wizard Howto.............................................................................................132
         Further Reading....................................................................................................... 137
         Wizard Framework Reference................................................................................. 139
Packaging Extensions.......................................................................................................... 142
    Alfresco Module Packages.............................................................................................. 143
         Introduction...............................................................................................................143
         Basic AMP Howto....................................................................................................143
         Further Reading....................................................................................................... 149
         Alfresco Module Package Reference...................................................................... 150




                                                                                                     API Development Course 5
Introduction


Introduction




6 Alfresco Enterprise Edition Version 3.2
Introduction


Welcome
    Welcome to Alfresco API development. This course has been designed to provide you with the
    knowledge and skills necessary to develop against the Alfresco Repository APIs and to develop
    extensions for the Alfresco enterprise content management system.

How this course is delivered
    This course is delivered in 17 modules, each module focusing on a specific subject. All modules
    include a combination of introductory materials, an outline of objectives followed by instructor-
    led discussions and walkthroughs. Each module will close with one or more exercises which will
    allow students to use and demonstrate what they have learned in each module.

Course objectives
    At the conclusion of this course you should be comfortable with all the concepts and tasks
    required to competently:
        • Set up your own development environment and use the Alfresco SDK
        • Develop against the Alfresco APIs (Foundation Services, JCR, Web Services)
        • Develop extensions for the Alfresco Repository
        • Develop extensions for the Alfresco Web Client
        • Package and deploy extensions

Certification track objectives
    At the conclusion of this course, you should have also acquired the requisite knowledge and
    abilities to pass the Alfresco API developer exam in preparation for the Certified Alfresco ECM
    professional certificate.

Course Schedule
Day 1
        • Getting Started
               • Alfresco SDK
               • Best Practices
               • Alfresco Repository Architecture
        • Developing against the Alfresco Repository
               • The Spring Framework
               • Foundation Services API
               • Java Content Repository (JCR) API
               • Web Services API

Day 2
        • Developing against the Alfresco Repository
               • Separating Concerns using AOP
        • Extending the Alfresco Repository
               • Repository Policies
               • Repository Actions



                                                                               API Development Course 7
Introduction

                  • Content Transformers
                  • Metadata Extractors

Day 3
          • Extending the Web Client
                  • JavaServer Faces
                  • Actions Framework
                  • Dialog Framework
                  • Wizard Framework
          • Packaging Extensions
                  • Alfresco Module Packages

How Prepared are You?
          • Can you program in Java?
          • Do you have a basic understanding of XML?
          • Have you followed the Alfresco administration course?
          • Have you followed the Alfresco customisation course?
          • Are you familiar with the Eclipse IDE?

Topics not Covered
          • Installing Alfresco
          • Repository configuration
          • Web Client configuration
          • Customising the Data Dictionary
          • Developing JavaScript extensions
          • Developing Freemarker templates
          • Developing Web Scripts

Introductions
          • Name
          • Company
          • Title, function, job responsibility
          • Alfresco experience (API development experience)
          • Courses already taken
          • Reasons for taking this course
          • Expectations




8 Alfresco Enterprise Edition Version 3.2
Getting Started


Getting Started




                  API Development Course 9
Getting Started


Alfresco SDK

Introduction
     The Alfresco SDK provides support for developers who wish to extend or customise the Alfresco
     platform. It has been designed for the developer to get developing with minimal fuss for the
     following development scenarios:

          • Developing extensions for the Alfresco Repository and Web Client.
          • Embedding Alfresco into applications via Alfresco's Java Foundation Services API or
            standards-compliant JCR API.
          • Developing applications against a remote Alfresco Repository via Alfresco's Web Services
            API.

     Typically, the SDK is used stand-alone, but an Alfresco installation is also required if performing
     any of the following:

          • Customising the Alfresco Web Client
          • Deploying a custom module to a remote Alfresco repository
          • Testing a custom application that connects to a remote Alfresco repository

             The SDK is not designed for re-building Alfresco since it does not provide full build scripts
             and artifacts. If you wish to develop bug fixes or extend the core functionality of the
             Alfresco platform, you should use the full Alfresco development environment provided in
             the Alfresco SVN Repository. For more information, see SVN Repository on page 19.

Downloading and Unpacking the Alfresco SDK
     You will need to install the following software and development tools in order to use the SDK
     correctly:

          • the Java SE Development Kit (JDK) version 1.5 (5.0) or above;
          • a supported database of your choice (MySQL is recommended for development
            purposes);
          • the Eclipse IDE 3.x (highly recommended).

     The Alfresco SDK bundle is provided with each release of Alfresco, for both the Enterprise and
     Community Networks.

         1. Downloading the Alfresco SDK
              The Enterprise SDK is only available to Enterprise clients and partners. The Community
              SDK is freely available and can be downloaded from the Download Alfresco Community
              Network page on the Alfresco Developer web site. The SDK is provided in both ZIP and
              TAR (tar.gz) formats.
         2. Unpacking the Alfresco SDK

              To install the SDK, simply unpack the downloaded ZIP or TAR bundle to a directory of your
              choice.




10 Alfresco Enterprise Edition Version 3.2
Getting Started




          For a description of the contents of the Alfresco SDK, see SDK Contents on page 20.

Importing the Alfresco SDK projects into Eclipse
   When using the Alfresco SDK, the Eclipse IDE is highly recommended. The SDK contains
   several pre-configured Eclipse projects that you can import directly into Eclipse with the following
   procedure.

     1. Setting the Eclipse Compiler Compliance Level
          Alfresco uses Java 1.5 (5.0) language features, therefore Eclipse must be configured
          appropriately for the Java SE Development Kit (JDK) version 1.5 (5.0) or above.
          a.   From the Eclipse main menu, select Window # Preferences...
          b.   In the Preferences dialog, select Java # Compiler in the tree view.
          c.   In the JDK Compliance panel, set the Compiler compliance level to 5.0 or above:




                                                                              API Development Course 11
Getting Started




              d.   Click OK
         2. Importing the Alfresco SDK projects
              a.   From the Eclipse main menu, select File # Import...
              b.   In the Import dialog, select General # Existing Projects into Workspace import
                   source and click Next >
              c.   Choose Select root directory option and click Browse...
              d.   Navigate to the file system directory where you unpacked the Alfresco SDK and click
                   OK. The Alfresco SDK projects are now listed under Projects.
                          Do not navigate to the samples sub-directory, otherwise you will not see the SDK
                          AlfrescoEmbedded and SDK AlfrescoRemote projects in the list.




12 Alfresco Enterprise Edition Version 3.2
Getting Started




           In order to run the samples or to develop your own extension modules, you must
           import at least the SDK AlfrescoEmbedded and SDK AlfrescoRemote projects. The
           other SDK projects are samples for common development scenarios that you can
           study and run to learn more about developing Alfresco extension modules.

           For more information about the available projects, see SDK Eclipse Projects on page
           20.
      e.   Once you have selected the projects you wish to import, click Finish.

The imported projects are displayed in the Package Explorer:




                                                                        API Development Course 13
Getting Started




Associating Source Code and Javadocs with the Alfresco Libraries
     Once the Alfresco SDK projects have been imported into Eclipse, it is useful to have access to
     Alfresco's source code and Java documentation. The following procedure explains how to do this
     by associating the source code and Javadocs with the Alfresco libraries within Eclipse.

         1. Expand the SDK AlfrescoEmbedded project in the Project Explorer.
         2. Right click on the alfresco-repository.jar and select Properties from the popup
            menu.
                     The JAR files may not be in alphabetical order.
         3. Associating source code
              a.   In the Properties for alfresco-repository.jar dialog, select Java Source
                   Attachment in the tree view.
              b.   In the Java Source Attachment panel, click External File...
              c.   Navigate to src directory within your unpacked Alfresco SDK.
              d.   Select repository-src.zip and click Open.




14 Alfresco Enterprise Edition Version 3.2
Getting Started




4. Associating Javadocs
   a.   In the Properties for alfresco-repository.jar dialog, select Javadoc Location in the
        tree view.
   b.   In the Javadoc Location panel, select Javadoc in archive and click Browse...
   c.   Navigate to doc/api directory within your unpacked Alfresco SDK.
   d.   Select repository-doc.zip and click Open.




   e.   Click Validate... to validate the Javadoc location, then click either OK to view the
        Javadocs in a web browser or Cancel if not.




                                                                        API Development Course 15
Getting Started




         5. Click OK, to close the Properties dialog.
     Once the source code and Javadocs have been attached, the alfresco-repository.jar icon
     changes to include a small document:




             The above steps need to be repeated for the following JARs:
                  •   alfresco-core.jar
                  •   alfresco-remote-api.jar
                  •   alfresco-web-client.jar
                  •   alfresco-web-service-client.jar (only Java source code is available)


SDK samples
FirstFoundationClient and JCR Samples
     The SDK FirstFoundationClient, SDK FirstJCRClient and SDK JCRSamples sample projects
     demonstrate how to access an embedded Alfresco repository via the Foundation Services API
     and the standards-compliant JCR API. These samples can be tested directly from within Eclipse
     and will automatically start an Alfresco repository in embedded mode.
     Before starting, the embedded repository needs to be configured. By default, the sample projects
     are configured to use a MySQL database named alfresco and a data directory with a relative
     path of ./alf_data. These parameters are defined in the custom-repository.properties
     file in the source/alfresco/extension directory of each project. It is good practice to define
     an absolute path for the data directory (dir.root parameter) and to configure all of the SDK
     projects to share the same database and the same dir.root.
     Example custom-repository.properties file:
     dir.root=C:/alf_data




16 Alfresco Enterprise Edition Version 3.2
Getting Started


#db.username=alfresco
#db.password=alfresco

#
# MySQL connection (This is default and requires mysql-connector-java-3.1.12-
bin.jar, which ships with the Alfresco server)
#
#db.driver=org.gjt.mm.mysql.Driver
#db.url=jdbc:mysql://localhost/alfresco

The alfresco MySQL database also needs to be created using the scripts provided in the
extras/databases/mysql directory of the unpacked Alfresco SDK. To create the database from
the command line:
C:alfresco-enterprise-sdkextrasdatabasesmysql>mysql -u root -p <
 db_setup.sql
Enter password: ********

The samples can now be tested by running the main Java classes from within Eclipse. In the
following example, the FirstFoundationClient class is run as a Java Application:




The Alfresco repository is automatically started in embedded mode. Because this is the first time
the repository has been started, the initial bootstrap is executed to create the database tables. As
you can see from the console messages below, the embedded repository uses C:alf_data as
it's data directory (dir.root).




                                                                           API Development Course 17
Getting Started




     The other embedded repository samples (SDK FirstJCRClient and SDK JCRSamples) can be
     run in the same way.

Web Services Samples
     The SDK FirstWebServiceClient and SDK WebServiceSamples sample projects demonstrate
     how to access a remote Alfresco repository via the Web Services API. A remote Alfresco
     repository needs to be installed and running before testing one of these samples.
     Before running one of the Web Services samples, a remote repository needs to be installed
     and configured. The easiest solution for development purposes is to install Alfresco on the local
     machine and configure it to use the same alfresco MySQL database and the same C:/alf_dir
     data directory as the embedded repository used for the other samples.
     The location of the remote repository is configured in the webserviceclient.properties
     file in the source/alfresco/extension directory of each Web Services project. If the remote
     repository is installed on the same machine and configured to use the default 8080 port, you will
     not have to modify the default value.
     Example webserviceclient.properties file:
     #
     # Set the following property to reference the Alfresco server that you would
       like web service client
     # to communicate with
     repository.location=http://localhost:8080/alfresco/api

     Once the remote repository has been installed and started, the Web Clients samples can be
     tested by running the main Java classes from within Eclipse. In the following example, the
     FirstWebServiceClient class is run as a Java Application:




Custom Repository Samples
     The SDK CustomAction and SDK CustomAspect sample projects demonstrate how to develop
     custom modules that may be deployed to an Alfresco repository. Initially, custom repository



18 Alfresco Enterprise Edition Version 3.2
Getting Started

   modules can be developed and tested using unit tests and an embedded Alfresco repository. The
   SDK CustomAspect project has a sample unit test that does this.
   An Ant build.xml file is provided for packaging the repository samples. The package target
   packages the compiled classes and extension files into a JAR file. To deploy the samples,
   copy the JAR file to the WEB-INF/lib folder of an existing Alfresco installation and restart the
   application server.
   For deployment in a production environment, a custom repository module should be packaged as
   an Alfresco Module Package (AMP).
   For more information on creating a custom repository action, see the Repository Action Howto
   on page 79. For a detailed presentation of the SDK CustomAspect sample, see the Custom
   Aspect with Behaviour Howto on page 71.

Custom Web Client Samples
   The SDK CustomDialog, SDK CustomJSP, SDK CustomLogin, SDK CustomWizard, and SDK
   TaggingSample sample projects demonstrate how to develop custom modules for the Alfresco
   Web Client. Custom Web Client modules have to be deployed to an existing Alfresco installation
   for testing.
   An Ant build.xml file is provided for packaging the Web Client samples. The package-
   jar target packages the compiled classes and extension files into a JAR file. The package-
   extension target then packages the JAR file along with the JSPs into a ZIP file. The optional
   integrate-extension target can be used to integrate the packaged ZIP file into an Alfresco
   Web Client WAR file. The alfresco.war file must be copied to the same directory as the
   build.xml file before running the Ant build and then re-deployed to the application server.
   For deployment in a production environment, a custom Web Client module should be packaged
   as an Alfresco Module Package (AMP).
   The SDK CustomDialog and SDK CustomWizard are presented in detail in the Custom Dialog
   Howto on page 123 and the Custom Wizard Howto on page 132. The SDK TaggingSample
   sample is presented in detail in the Repository Action Howto on page 79.

Basic AMP Sample
   The SDK Basic AMP sample project demonstrates how to structure a project and how to arrange
   classes and configuration files to generate an Alfresco Module Package (AMP). For more
   information see Basic AMP Howto on page 143.

SVN Repository
   The Alfresco Subversion repository gives you access to all of the Alfresco source code and build
   artifacts. It provides the latest work-in-progress developments. It should only be used if you wish
   to extend the Alfresco core framework or work on Alfresco bug fixes as it allows you to perform
   full re-builds of Alfresco itself. For most requirements, it is best to use the Alfresco SDK.
   Public read-only access to the Alfresco Subversion repository is available from the Alfresco web
   site. To checkout the source code, use the following procedure:
      1. Install Subversion and ensure that svn is on the path.
      2. Checkout the HEAD of the code stream:
          svn co svn://svn.alfresco.com/alfresco/HEAD

          or
          svn co http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD
      3. Keep up to date by issuing the command:
          svn update



                                                                              API Development Course 19
Getting Started


SDK Reference
SDK Contents
     bin
         Supporting dll's, exe's.
     doc
         Zipped Javadoc's for all pre-built libraries.
     extras
         Additional files - database setup and migration scripts.
     lib
         Alfresco pre-built libraries (JAR files).
     lib/deployment
         Alfresco libraries required for WCM deployment to a remote server.
     lib/remote
         Alfresco libraries required for access to a remote Alfresco repository via web services.
     lib/server
         Alfresco libraries required for embedding an Alfresco repository.
     licenses
         License files.
     samples
         Sample Eclipse projects for common development scenarios (see SDK Eclipse Projects on
         page 20).
     src
         Zipped source code for all pre-built libraries.
     license.txt
         Alfresco licence file.
     notice.txt
         Notices
     readme.txt
         Alfresco SDK readme.

SDK Eclipse Projects
     SDK AlfrescoEmbedded
         Project containing all of the Alfresco libraries needed to build a custom module that will be
         embedded into the Alfresco repository or Web Client.
     SDK AlfrescoRemote
         Project containing all of the Alfresco libraries needed to build a custom Web Services client.
     SDK Basic AMP
         Sample project demonstrating how to build an AMP (Alfresco Module Package) file.
     SDK CustomAction
         Sample project demonstrating how to develop a custom Action that may be deployed to an
         Alfresco repository.
     SDK CustomAspect
         Sample project demonstrating how to develop a custom Aspect with behaviour that may be
         deployed to an Alfresco repository.



20 Alfresco Enterprise Edition Version 3.2
Getting Started

SDK CustomDialog
  Sample project demonstrating how to develop and configure a custom Dialog for the Alfresco
  Web Client.
SDK CustomJSP
  Sample project demonstrating how to develop and configure a custom JSP for the Alfresco
  Web Client.
SDK CustomLogin
  Sample project demonstrating how to override the Login page of the Alfresco Web Client.
SDK CustomWizard
  Sample project demonstrating how to develop and configure a custom Wizard for the Alfresco
  Web Client.
SDK FirstFoundationClient
  Sample project demonstrating how to access an Alfresco (embedded) repository via the
  Foundation Services API.
SDK FirstJCRClient
  Sample project demonstrating how to access an Alfresco (embedded) repository via the
  standards-compliant JCR API.
SDK FirstWebServiceClient
  Sample project demonstrating how to access a remote Alfresco repository via the Web
  Services API.
SDK JCRSamples
  More sample projects demonstrating how to access an Alfresco (embedded) repository via the
  standards-compliant JCR API.
SDK TaggingSample
  Advanced sample project demonstrating how to develop a custom Action that takes
  parameters.
SDK WebServiceSamples
  More sample projects demonstrating how to access a remote Alfresco repository via the Web
  Services API.




                                                                      API Development Course 21
Getting Started


Best Practices

Coding Standards
Coding Standards - Formatting
          • The core coding standards are the standard Java Code Conventions.
          • Braces are on new lines.
          • 4 space for tabbing, except for Web Client project that uses 3 spaces.
          • 120 characters on a line is fine.
          • Import declarations are managed by Eclipse's standard ordering rules (CTRL-SHIFT-O).
            This helps prevent code merge conflicts.
          • XML documents use 3 space tabbing. The Eclipse plug-in, XMLBuddy, is generally used.

Coding Standards - Exceptions
          • When generating a new exception, always attach the cause to it.
          • Don't log exceptions unless you are adding the logic to absorb the exception.
          • Put as much context and formatting into the error message as possible.
          • Use RuntimeException derived exceptions, unless there is a really good reason to bother
            the client code with a checked exception.
          • Pay attention to the Javadoc specification on unchecked exceptions. Don't declare them
            on the interface, just in the Javadocs.

Coding Standards - Logging
          • Use the Apache Commons Logging API so that all logging output is uniform.
          • Use the class hierarchy categories, but where deviations are made, add comments to the
            Javadocs.
          • INFO messages are only added at the request of Alfresco users. All other informative
            messages are DEBUG.
          • Put as much context and formatting into the message as time will allow.
          • Wrap all calls to logger.debug and logger.info, and only log messages if
            logger.isDebugEnabled and logger.isInfoEnabled respectively.

Coding Standards - File Formats
          • UTF-8 encoding of all text files
          • Windows line endings (CR-LF)

Alfresco Module Packages (AMP)
     An Alfresco Module Package (AMP) is a collection of code, XML, images, CSS, etc. that
     collectively extend the functionality or data provided by the standard Alfresco Repository. An AMP
     file can contain as little as a set of custom templates or a new category. It can contain a custom
     model and associated UI customisations. It could contain a complete new set of functionality, for
     example records management. As a general rule of thumb, anything that is considered to be an
     “installable” extension to the Alfresco repository should be called a module and packaged as an
     AMP file.
     AMP files can be installed into the Alfresco WAR using the Module Management Tool. An AMP
     file has a standard format that can be customised if required.



22 Alfresco Enterprise Edition Version 3.2
Getting Started

    Once the contents of the AMP file has been mapped into an Alfresco WAR using the Module
    Management Tool, the WAR can be deployed to the application server. When the repository
    is next started, the installed module configuration will be detected, and the repository will be
    bootstrapped to include the new module functionality and data.

AMP Project Structure
    An Alfresco Module project can be structured in any way that suits the developer environment. As
    long as the resulting AMP file is packaged correctly and the required property and context files
    are present, the module will install successfully.
    The recommended project structure is as follows:
    
    |-- source
       |
       |-- java
          |-- <module package structure starts here>
       |
       |-- web
          |-- css
          |-- images
          |-- jsp
          |-- scripts
    |
    |-- config
       |-- <resource package structure starts here>
    |
    |-- build
       |-- dist
       |-- lib
    |
    |-- build.xml

    source/java/
       Contains the Java source for the Alfresco Module.
    source/web/
       Contains any web UI resources (JSPs, images, CSS, JavaScript).
    config/
       Contains configuration files and resources used by the module.
    build/
       Build directory for compiled class files.
    build/dist/
       Build directory for AMP files.
    build/lib/
       Build directory for JAR files.

    The recommended package structure for Java source (source/java), configuration files and
    resources (config) is org.alfresco.module.<moduleid>, where moduleid is the unique
    module id of the module.
    Alfresco Module Packages are presented in more detail later on in the course. For more details,
    see Introduction on page 143.




                                                                                API Development Course 23
Getting Started


Alfresco Repository Architecture

Out of the Box
     Out-of-the-box, Alfresco's simple installation procedure provides a pre-configured deployment
     aimed at reaching a complete and working Content Management application as quickly and easily
     as possible. The deployment is as follows:




     This is typical of a web architecture, where an application server houses the logic for both the
     user interface and domain. Storage of data and content is provided by persistent back-ends such
     as a database or file system. Any number of web browsers can connect to the application without
     prior client installation costs.

     In this particular case, the application server houses both the Alfresco Application and the
     Alfresco Repository. An Alfresco Application provides a complete solution tailored for a specific
     area of Content Management such as Document Management (DM), Web Content Management
     (WCM) and Records Management (RM). The Alfresco Repository provides a set of reusable
     cross-cutting Content Management services such as content storage, query, versioning and
     transformation which may be utilised by one or more applications.

     Although this is the default installed deployment, it is only one of many ways of utilising the
     capabilities and components of Alfresco. When we first set out to design Alfresco, we wanted to
     break away from the mould of typical Content Management architectures which are monolithic
     and closed. The result is that Alfresco can neatly fit into existing environments and each of its



24 Alfresco Enterprise Edition Version 3.2
Getting Started

   components may be used in isolation or together to form the basis of many differing Content
   Management solutions.
   The remainder of this module explores the anatomy of the Alfresco Repository which will give a
   good understanding of the concepts and capabilities and how it achieves openness, scalability
   and flexibility.

Service & Component Architecture
   Every part of the Alfresco Repository is either a component or a service. A component is
   an implementation black box that provides a specific feature or capability. A service is an
   interface entry point for a client to bind to and use. This fundamental approach allows for existing
   components to be switched with new implementations, new components to be added with ease
   and for clients to connect and use services without knowledge of how they're implemented.

   If there's a feature of Alfresco you don't need, you can take it out, providing a lighter and possibly
   faster Alfresco. If there's a feature you wish to re-implement, you can replace it, either by
   providing a better implementation, or integrating with your existing environment.

   Implementation of this approach is simplified by using the open source project Spring Framework
   which Alfresco has taken to heart and has made a core foundation of its architecture. With
   Spring, Alfresco components are declaratively configured and bound together. Aspect-oriented
   programming allows the weaving of infrastructure concerns such as Transactions and Security
   into components without polluting their implementation. Environment touch points are abstracted
   such as resource (e.g. database) connections.
   The Alfresco Repository structure looks like this:




                                                                                API Development Course 25
Getting Started




     The public interface point is the Alfresco Repository Foundation Services. Each service is
     exposed as a Java Interface to which a Repository client can bind and invoke without knowledge
     of its underlying implementation. A Service Registry lists the available services. Behind services
     are the implementation black boxes i.e. components. Each service and component is configured
     via the Spring framework in XML “context” files.
             The Spring context file public-service-context.xml provides the configuration and
             binding of the Alfresco Repository Foundation Services.
     The Repository Foundation Services are the lowest level of public interface providing access
     to all Repository capabilities. Binding to this interface is possible via the Repository Service
     Registry, or via Spring dependency injection if the client is also Spring aware. Access to
     Foundation Services is limited to Repository clients who reside in the same process as the
     Repository. That is, the Foundation Services are an excellent API for clients who wish to embed
     the Repository.
     An important point to note is that the Foundation Services are where transaction and security
     policies are enforced. The policies themselves are declaratively specified and enforced via the
     injection of a transaction and security implementation into each service. Every service of Alfresco
     is transactional and secure.
     Other forms of API are provided too, however, all public entry points eventually go through this
     layer.
     Alfresco supports a common scheme for making extensions to the Repository i.e. configuring
     a component, adding a new component or service, or removing capabilities. Extensions are



26 Alfresco Enterprise Edition Version 3.2
Getting Started

   encapsulated outside of the core Repository and plugged-in automatically. This means the core
   Repository can be upgraded to a newer version and extensions remain intact.

Repository Foundation Services API
   The heart of the Alfresco Repository is responsible for the storage and retrieval of content. This
   is split into nodes, content and index information. Nodes provide meta-data and structure to
   content. A node may support properties (e.g. author) and relate to other nodes (e.g. represent
   folder hierarchies or annotations). Content is the actual information being recorded e.g. a Word
   document or XML fragment. Meta-data and content may be structured according to the rules
   defined in a Content Model. For example, the Alfresco Document Management application relies
   on a model that describes Folders and Files. Indexing information allows the retrieval of meta-
   data and content via many different lookup options.
   Repository storage and retrieval is provided by the following Foundation Services:
      • Node Service for managing meta-data i.e. nodes
      • Content Service for managing content
      • Search Service for performing queries
   By default, Alfresco has chosen to store meta-data in a database and content in a file system.
   Using a database immediately brings in the benefits of databases that have been developed over
   many years such as transaction support, scaling & administration capabilities. Content is stored in
   the file system to allow for very large content, random access, streaming and options for different
   storage devices.
   The Alfresco out-of-the-box implementations of the above services are built upon strong
   open source projects that already have many man-years of development effort and strong
   communities: Hibernate and Lucene.




                                                                             API Development Course 27
Getting Started




     Apart from the strong Object/Relational mapping that Hibernate provides, it also brings pluggable
     caching support and SQL dialects. The first allows for tuning of the Alfresco meta-data store to
     provide optimum read and write performance in both single and clustered environments. The
     second allows for nearly any SQL database back-end by configuring just two properties; the
     Alfresco community has already confirmed working support for MySQL, Oracle, DB2, Sybase,
     SQL Server.
     By externalising the indexing of meta-data and content and using the Lucene engine as a basis,
     it is possible to perform complex queries which combine property, location, classification and
     full-text predicates in a single query against any content type. Multiple query languages are
     supported including Lucene's native language as well as XPath and a SQL-like language in the
     future. To ensure reliable operation, transactional support has been added to both Lucene and
     the content file store providing ACID operations across the complete store. Security is woven into
     each of the service layer ensuring illegal modifications are not permissible and hidden meta-data
     and content are not returned.
     Nearly all other Foundation services and clients rely upon these three core building blocks.

Repository APIs
     The Alfresco Repository actually provides three APIs. We've already seen one - the Repository
     Foundation Services - a set of local Java Interfaces covering all capabilities which are ideal for
     clients who wish to embed the Repository.
     The two other APIs are:
          • JCR
          • Web Services

     JCR (Content Repository API for Java Technologies) is a standard Java API (as defined by
     JSR-170) for accessing Content Repositories. Alfresco provides support for level 1 and level 2
     giving standardised read and write access. Supporting this API provides the following benefits:
          • No risk: The Alfresco Repository can be trialled and developed against, but swapped out
            with another JCR Repository if it does not fit requirements.
          • Familiarity: Developers who know JCR, know Alfresco.
          • Tools: Tools, Clients and other 3rd Party JCR solutions are immediately available to the
            Alfresco community.

     Alfresco JCR is implemented as a light facade on top of the Repository Foundation Services.
     So, although a familiar API is provided, it sits upon a fully transactional, secure and scalable
     Repository which supports many deployment options. Alfresco will continue investment in JCR by
     both broadening the compliance of the full specification as well driving forward JSR-283, the next
     version of the JCR.
     Web Services is the final API provided by the Alfresco Repository. This API supports remote
     access and bindings to any client environment, not just Java. For example, the Alfresco
     community is already using PHP, Ruby and Microsoft .NET. Numerous standards and integration
     efforts are focused around Web Services - SOA is now recognised as a way forward for
     integrating disparate systems including Content Management and building new enterprise-wide
     solutions. BPEL plays an important role in orchestrating all of these services. Alfresco fits neatly
     into this way of thinking.




28 Alfresco Enterprise Edition Version 3.2
Getting Started




   Once again, the Repository Foundation Services serve as the base. Both the JCR and Web
   Services API eventually go through this layer meaning that all encapsulated content model logic
   and rules are honoured.

Repository Server Protocols
   A Repository is useless if the content it manages cannot be accessed. To provide the widest
   possible range of access points, the Alfresco Repository supports a variety of communication
   protocols. These are:
      • CIFS (Common Internet File System)
      • WebDAV
      • FTP
      • NFS
   All of these protocols essentially expose Folders of Files and as such the Alfresco
   implementations map neatly onto Folder and File nodes held in the Repository as described by
   the Alfresco Document Management content model.
   WebDAV, FTP and NFS are well known protocols, but CIFS deserves some more attention.
   CIFS transforms the Alfresco Repository into a standard file system. Any tool that understands
   how to read and write to a file system, also knows how to directly read and write to the Alfresco
   Repository. On the surface, it would seem that a drive mapping to WebDAV provides an
   equivalent capability, but this isn't the case. CIFS projects an actual file system giving extra
   compatibility with the hosting operating system. For example, in Windows, it's possible to use
   Offline Synchronisation and Briefcase features against the Alfresco Repository providing native
   and well-known tools for offline Repository working. Many commercial CMS offerings do not
   provide this feature. In fact, Alfresco may have the only server-side Java implementation of the



                                                                             API Development Course 29
Getting Started

     CIFS protocol having brought on board the engineers who spent 7 years developing such a
     capability.




     Like every other feature of the Repository, the protocol components are Spring configured and
     as with all other components may or may not be included in a deployment. Typically, they are
     enabled when the Repository is deployed as a server to provide access points for remote clients.
     The various Repository deployment options are explored later in this document.

     Protocol components are implemented against the Repository Foundation Services. This is
     important to note, as each protocol will honour the behaviour and content logic encapsulated
     behind the Foundation Services. In fact, it cannot be bypassed.

Terminology
Store Reference (StoreRef)
     A StoreRef is made up of a store protocol and a store id.




30 Alfresco Enterprise Edition Version 3.2
Getting Started




    public static final String PROTOCOL_WORKSPACE = "workspace";
    public static final String PROTOCOL_AVM = "avm";
    public static final String URI_FILLER = "://";

    The standard store used by the Web Client has the following StoreRef:
    workspace://SpacesStore

Node Reference (NodeRef)
    A NodeRef is made up a store reference and a node id.




    private static final String URI_FILLER = "/";

    The node id is a 16 byte (128 bit) A “Universally Unique Identifier” or UUID.

    Example NodeRef:
    workspace://SpacesStore/808b2b34-a99f-11db-b572-8337f65f7e0d

Qualified Name (QName)
    A QName represents the qualified name of a Repository item. Each QName consists of a local
    name qualified by a namespace.




                                                                               API Development Course 31
Getting Started




     Namespace scoped Name Format {URI}localname or prefix:localName
     Examples
     {http://www.alfresco.org/model/content/1.0}auditable

     or
     cm:auditable

Node Browser
     The Node Browser is your friend!




32 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository


Developing against the Alfresco Repository




                                                   API Development Course 33
Developing against the Alfresco Repository


Spring Framework

Introduction
     The Spring Framework is a full-stack Java/JEE application framework. Spring's main aim is to
     make J2EE easier to use and promote good programming practise. It does this by enabling a
     POJO-based programming model remaining faithful to the fundamental ideas of Expert One-on-
     One J2EE Design and Development. Spring is portable between application servers.

Bean Factory
     A Spring BeanFactory is a generic factory that enables objects to be retrieved by name, and
     which can manage relationships between objects. Bean factories support two modes of object:
          • Singleton: in this case, there's one shared instance of the object with a particular name.
          • Prototype or non-singleton: in this case, each retrieval will result in the creation of an
            independent object.
     Beans are defined in an XML bean definition file that is loaded when a new Bean Factory is
     created.

Bean Factory Example
         1. Writing a simple JavaBean class
             Here's the simplest Java Bean you can get!
             package ex01_simplebean;

             public class Bean1
             {

             }
         2. Defining the Spring beans
             Two Spring beans are defined for the same class. bean1 is a singleton bean and
             multibean1 is a prototype bean (singleton="false"):
             <beans>
                <bean id="bean1"
                      class="ex01_simplebean.Bean1" />

                <bean id="multibean1"
                      class="ex01_simplebean.Bean1"
                      singleton="false" />
             </beans>
         3. Testing with a Main program
             a.    Creating a new Spring Bean Factory
                   The bean definition file is loaded into the Spring Bean Factory:
                   ClassPathResource res = new ClassPathResource(
                           "ex01_simplebean/ApplicationContext.xml");
                   XmlBeanFactory factory = new XmlBeanFactory(res);

                   The following messages are written to the console:
                   15:13:26,515 INFO [XmlBeanDefinitionReader] Loading XML
                    bean definitions from class path resource [ex01_simplebean/
                   ApplicationContext.xml]
                   15:13:26,593 INFO [XmlBeanFactory] Creating shared instance of
                    singleton bean 'bean1'
             b.    Getting bean1 from the Bean Factory



34 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository

               We retrieve bean1 from the Bean Factory using the getBean() method:
               Bean1 bean1a = (Bean1) factory.getBean("bean1");
               System.out.println("Retrieved Bean1: " + bean1a.toString());

               Bean1 bean1b = (Bean1) factory.getBean("bean1");
               System.out.println("Retrieved Bean1: " + bean1b.toString());

               Each call retrieves the same bean (there is only one instance):
               Retrieved Bean1: ex01_simplebean.Bean1@471e30
               Retrieved Bean1: ex01_simplebean.Bean1@471e30
          c.   Getting multibean1 from the Bean Factory
               Now we retrieve multibean1 from the Bean Factory.
               Bean1 bean1a = (Bean1) factory.getBean("multibean1");
               System.out.println("Retrieved MultiBean1: " + bean1a.toString());

               Bean1 bean1b = (Bean1) factory.getBean("multibean1");
               System.out.println("Retrieved MultiBean1: " + bean1b.toString());

               This time each call retrieves a new instance of the bean:
               Retrieved MultiBean1: ex01_simplebean.Bean1@10ef90c
               Retrieved MultiBean1: ex01_simplebean.Bean1@a32b


Inversion of Control (IoC)
    Through its bean factory concept, Spring is an Inversion of Control container. Spring is most
    closely identified with a flavour of Inversion of Control known as Dependency Injection. The
    concept behind Inversion of Control is often expressed in the Hollywood Principle: “Don't call me,
    I'll call you.” IoC moves the responsibility for making things happen into the framework, and away
    from application code. Whereas your code calls a traditional class library, an IoC framework calls
    your code.

Dependency Injection
    Dependency Injection is a form of IoC that removes explicit dependencies on container APIs.
    Ordinary Java methods are used to inject dependencies such as collaborating objects or
    configuration values into application object instances. The two major flavors of Dependency
    Injection are:
       • Setter Injection (injection via JavaBean setters)
       • Constructor Injection (injection via constructor arguments).
    Spring provides sophisticated support for both, and even allows you to mix the two when
    configuring the one object.

Setter Injection Example
      1. Writing a simple JavaBean class
          This simple JavaBean supports properties. The values of the properties are set by the
          Spring Bean Factory when the bean is instantiated.
          package ex02_setter;

          public class Bean1
          {
              public void setString(String val) { m_strVal = val; }
              public String getString() { return m_strVal; }

               public void setInt(int val) { m_intVal = val; }
               public int getInt() { return m_intVal; }




                                                                               API Development Course 35
Developing against the Alfresco Repository

                   public void setList(List strings) { m_strings = strings; }
                   public List getList() { return m_strings; }

                   private String m_strVal;
                   private int m_intVal;
                   private List m_strings;
             }
         2. Defining the Spring beans
             A single bean is defined with initial values for the properties that will be initialised via the
             “setter” methods on the JavaBean:
             <beans>
                <bean id="bean1" class="ex02_setter.Bean1">
                   <property name="string">
                      <value>a string</value>
                   </property>
                   <property name="int">
                      <value>125</value>
                   </property>
                   <property name="list">
                      <list>
                         <value>item1</value>
                         <value>item2</value>
                         <value>item3</value>
                      </list>
                   </property>
                </bean>
             </beans>
         3. Testing with a Main program
             We retrieve bean1 from the Bean Factory and print out the values of the properties:
             Bean1 bean1a = (Bean1) factory.getBean("bean1");
             System.out.println("Retrieved Bean1: " + bean1a.toString());

             String strVal = bean1a.getString();
             System.out.println("String property: " + strVal);
             int intVal = bean1a.getInt();
             System.out.println("Int property: " + intVal);
             List strings = bean1a.getList();
             System.out.println("List property: " + strings);

             The properties have automatically been initialised by the Bean Factory:
             Retrieved Bean1: ex02_setter.Bean1@21b6d
             String property: a string
             Int property: 125
             List property: [item1, item2, item3]

Constructor Injection Example
         1. Writing a simple JavaBean class
             This time the JavaBean has a constructor and some properties.
             The String property is passed to the constructor and the int property has a “setter”
             method.
             package ex03_constructor;

             public class Bean1
             {
                 public Bean1(String val)
                 {
                     m_strVal = val;
                 }

                   public String getString() { return m_strVal; }



36 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository


              public void setInt(int val) { m_intVal = val; }
              public int getInt() { return m_intVal; }

              private String m_strVal;
              private int m_intVal;
         }
      2. Defining the Spring beans
         This time a bean is defined with a constructor argument.
         The String property will be initialised via the constructor and the int property via the
         “setter” method on the JavaBean:
         <beans>
            <bean id="bean1" class="ex03_constructor.Bean1">

                  <constructor-arg index="0">
                     <value>a string</value>
                  </constructor-arg>

               <property name="int">
                  <value>125</value>
               </property>
            </bean>
         </beans>
      3. Testing with a Main program
         We retrieve bean1 from the Bean Factory and print out the values of the properties:
         Bean1 bean1a = (Bean1) factory.getBean("bean1");
         System.out.println("Retrieved Bean1: " + bean1a.toString());

         String strVal = bean1a.getString();
         System.out.println("String property: " + strVal);
         int intVal = bean1a.getInt();
         System.out.println("Int property: " + intVal);

         The properties have automatically been initialised by the Bean Factory:
         Retrieved Bean1: ex03_constructor.Bean1@12152e6
         String property: a string
         Int property: 125

Dependency Injection Example
      1. Writing the JavaBean classes
         a.   Two more simple JavaBean classes
              These two JavaBeans will be used as dependencies:
              package ex04_dependency;

              public class Bean2
              {

              }
              package ex04_dependency;

              public class Bean3
              {

              }
         b.   Establish a constructor dependency
              The Bean1 class depends on the Bean2 class via the constructor:
              package ex04_dependency;



                                                                              API Development Course 37
Developing against the Alfresco Repository


                   public abstract class Bean1
                   {
                       public Bean1(Bean2 bean2)
                       {
                           m_bean2 = bean2;
                       }
                       ...
                       public Bean2 getBean2()
                       {
                           return m_bean2;
                       }
                       ...
                       private Bean2 m_bean2;
                   }
             c.    Establish a setter dependency

                   The Bean1 class depends on the Bean3 class via a property setter:
                   public void setBean3(Bean3 bean3)
                   {
                       m_bean3 = bean3;
                   }

                   public Bean3 getBean3()
                   {
                       return m_bean3;
                   }

                   private Bean3 m_bean3;
         2. Defining the Spring beans

             bean1 depends on bean2 and bean3. The Bean Factory will instantiate the bean2 and
             bean3 objects before “injecting” them into bean1 via the constructor property setter
             respectively:
             <beans>
                <bean id="bean1" class="ex04_dependency.Bean1">
                   <constructor-arg index="0">
                      <ref bean="bean2"/>
                   </constructor-arg>
                   <property name="bean3">
                      <ref bean="bean3"/>
                   </property>
                </bean>

                <bean id="bean2" class="ex04_dependency.Bean2"/>
                <bean id="bean3" class="ex04_dependency.Bean3"/>
             </beans>
         3. Testing with a Main program

             We retrieve bean1 from the Bean Factory and print out the dependencies:
             Bean1 bean1 = (Bean1) factory.getBean("bean1");
             System.out.println("Retrieved Bean1: " + bean1.toString());

             Bean2 bean2 = bean1.getBean2();
             Bean3 bean3 = bean1.getBean3();
             System.out.println("Retrieved Bean2 Dependency: " + bean2.toString());
             System.out.println("Retrieved Bean3 Dependency: " + bean3.toString());

             The dependencies have automatically been injected by the Bean Factory:
             Retrieved Bean1: ex04_dependency.Bean1$$EnhancerByCGLIB$$d8a83b@1cb25f1
             Retrieved Bean2 Dependency: ex04_dependency.Bean2@2808b3
             Retrieved Bean3 Dependency: ex04_dependency.Bean3@535b58




38 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository


Application Context
    To start using Spring you either instantiate a Spring BeanFactory or an ApplicationContext.
    ApplicationContext is derived from BeanFactory and provides all of the BeanFactory
    funtionality and more including:
       • MessageSource, providing access to messages in, i18n-style
       • Access to resources, such as URLs and files
       • Event propagation to beans implementing the ApplicationListener interface
       • Loading of multiple (hierarchical) contexts, allowing each to be focused on one particular
         layer, for example the web layer of an application

Web Application Context
    A Spring WebApplicationContext is just an ordinary ApplicationContext that has some extra
    features necessary for web applications. It is bound in the ServletContext and is created by a
    ContextLoaderListener.

Context Loader Listener
    The Spring ContextLoaderListener is declared in WEB-INF/web.xml:
    <listener>
       <listener-class>
          org.springframework.web.context.ContextLoaderListener
       </listener-class>
    </listener>

Spring contextConfigLocation
    Use the contextConfigLocation <context-param> to set which context files to load:
    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>
          classpath:alfresco/web-client-application-context.xml
          classpath:web-services-application-context.xml
          classpath:alfresco/application-context.xml
       </param-value>
       <description>Spring config file locations</description>
    </context-param>




                                                                             API Development Course 39
Developing against the Alfresco Repository


Foundation Services API

Introduction
     The Foundation 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 run 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.

Access to Repository Foundation Services
     The Foundation Services API is 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 Spring configuration file public-services-context.xml
          • the Service Registry interface org.alfresco.service.ServiceRegistry
     There are three ways to access Foundation Services:
         1. use Spring IoC to directly inject services into your code (If your layer is also Spring
            enabled);
         2. use the Alfresco Service Registry;
         3. manually access services via the Spring getBean() method.

FirstFoundationClient          walkthrough
     Before getting started, you should be familiar with the Introduction on page 34.

     The sample uses several of the key foundation services, including the ServiceRegistry,
     TransactionService, AuthenticationService, SearchService, NodeService and
     ContentService. After initialising the Spring Application Context and starting the repository in
     embedded mode, we will use the Spring getBean() method to access the ServiceRegistry.
     We will then use the ServiceRegistry to access the other foundation services.
     After authenticating to the repository using the AuthenticationService, we will search for
     the “Company Home” node using the SearchService. We will then create a new node with
     properties and add an aspect using the NodeService. Finally, we will write some content to the
     new node using the ContentService. The sample will be wrapped in a single user transaction
     with the help of the TransactionService.

         1. Getting the ServiceRegistry
             The Service Registry maintains a list of available foundation services and some meta-data
             about each. In particular, the Service Registry provides access to each service interface.
             The registry is a service itself and is therefore accessed using either Spring IoC or the
             Spring getBean() method. The static variable SERVICE_REGISTRY found on the interface
             org.alfresco.service.ServiceRegistry provides the Spring Bean name to lookup by.
             The FirstFoundationClient sample uses the getBean() method on the Spring
             Application Context to retrieve the ServiceRegistry:
             ApplicationContext ctx =
              ApplicationContextHelper.getApplicationContext();

             final ServiceRegistry serviceRegistry = (ServiceRegistry)
              ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);




40 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository

2. Using the TransactionService to run the example in a user transaction

   By default, all repository foundation services are transactional and each invocation of
   a service method is wrapped in its own transaction. These transactions are defined
   declaratively in Spring configuration files and not in your Java code. In most cases,
   declarative transactions are preferred to user transactions since they are less invasive.
   There are situations, however, when user transactions do need to be used explicitly in your
   code.

   The FirstFoundationClient uses a RetryingTransactionHelper to run the example
   as a unit of work inside a user transaction. The work is defined as an instance of the
   RetryingTransactionCallback class. The doInTransaction() method is then called to
   run the unit of work in a transaction.

   The RetryingTransactionHelper is obtained via the
   getRetryingTransactionHelper() method on the TransactionService.




         For clarity, not all of the available methods are shown. For a complete description,
         please consult the Javadocs: Interface TransactionService

   The TransactionService and RetryingTransactionHelper are presented in more
   detail in the section on Transactions.

   The following example runs the example work in a user transaction via the
   RetryingTransactionHelper:

   TransactionService transactionService =
       serviceRegistry.getTransactionService();
   RetryingTransactionCallback<Object> exampleWork =
       new RetryingTransactionCallback<Object>()
   {
       public Object execute() throws Exception
       {
           doExample(serviceRegistry);
           return null;
       }
   };
   transactionService.
       getRetryingTransactionHelper().doInTransaction(exampleWork);
3. Using the AuthenticationService for authentication



                                                                       API Development Course 41
Developing against the Alfresco Repository

             Before making any call to the repository through the public Foundation Services API,
             a user must first be authenticated. This is done via the AuthenticationService by
             using the authenticate() method and providing a username and password. Once
             authenticated, a ticket can be requested using either the getNewTicket() or the
             getCurrentTicket() method. The ticket can then be used to re-validate the user using
             the validate() method.

             The AuthenticationService defines the API for managing authentication information
             against a username.




                     For clarity, not all of the available methods are shown. For a complete description,
                     please consult the Javadocs: Interface AuthenticationService
             In the example, the authenticate() method is used to authenticate as the “admin” user.
             The password must be passed as a character array.
             AuthenticationService authenticationService =
              serviceRegistry.getAuthenticationService();
             authenticationService.authenticate("admin", "admin".toCharArray());
         4. Using the SearchService to locate the “Company Home” node

             The SearchService provides many methods for searching the Alfresco repository using
             any of the available query languages: Lucene, XPath or JCR-XPath. The Lucene query
             language allows you to run powerful searches, including full text searches on the content
             and node properties.

             To run a Lucene search using the query() method, you must specify the StoreRef of the
             store you wish to search, the query language (using one of the static attributes defined on
             the SearchService interface - LANGUAGE_LUCENE for example) and the query as a String.
             The parameters can either be passed directly to the query() method, or be defined on a
             new SearchParameters object which is then passed to the query() method. The query
             results are returned as a ResultSet object.




42 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository




         For clarity, not all of the available methods are shown. For a complete description,
         please consult the Javadocs: Interface SearchService

   The following example runs a Lucene query using the PATH syntax to locate the
   “Company Home” by it's absolute path. The getNodeRef(0) call is used to retrieve the first
   NodeRef from the ResultSet. In theory, the query should only return one result.

   SearchService searchService = serviceRegistry.getSearchService();
   StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE,
    "SpacesStore");
   ResultSet resultSet = searchService.query(
           storeRef,
           SearchService.LANGUAGE_LUCENE,
           "PATH:"/app:company_home"");
   NodeRef companyHome = resultSet.getNodeRef(0);

   For more information on using the SearchService and on query string syntax, see the
   Search page on the Alfresco Wiki.
5. Using the NodeService to create a node

   The NodeService provides methods for operations on nodes and stores.

   Stores are created with createStore().

   Nodes are created with createNode() and deleted with deleteNode(). Properties
   are set with either setProperty() or setProperties(). Properties are removed
   with removeProperty(). Aspects are applied with addAspect() and removed with
   removeAspect().

   Associations are created and removed with createAssociation() and
   removeAssociation(). Associations can be navigated with getSourceAssocs() or
   getTargetAssocs(). Child associations can be navigated with getChildAssocs() and
   getParentAssoc().

   Almost all NodeService methods take a NodeRef as an argument. A NodeRef is obtained
   either by navigation or from the results of a search. Otherwise a new NodeRef object can
   be created from the node's unique UUID.




                                                                       API Development Course 43
Developing against the Alfresco Repository




                     For clarity, not all of the available methods are shown. For a complete description,
                     please consult the Javadocs: Interface NodeService

             a.    Setting properties

                   Properties are set on nodes using either the setProperty() or setProperties()
                   methods. setProperty() allows a single property to be set, whilst setProperties()
                   takes a Map of properties and sets all of the node's properties at once. Each property
                   is identified by it's QName and it's value must be Serializable.
                   public void setProperty(
                           NodeRef nodeRef,
                           QName qname,
                           Serializable value)

                   public void setProperties(
                           NodeRef nodeRef,
                           Map<QName, Serializable> properties)

                   nodeRef
                      NodeRef of the node to set the property on.




44 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository

     qname
        QName of the property to set.

     value
        Value of the property. The value must be Serializable.
     properties
        Map of all the properties of the node keyed by QName.

     The property QNames are usually defined as a static constants on the dictionary
     model interfaces. For example, the cm:name property is defined by the static constant
     ContentModel.PROP_NAME.

     The following example creates a Map containing the cm:name property that will be
     used in the next step:
     String name = "Foundation API sample (" + System.currentTimeMillis() +
      ")";
     Map<QName, Serializable> contentProps = new HashMap<QName,
      Serializable>();
     contentProps.put(ContentModel.PROP_NAME, name);
b.   Creating a node

     Nodes are created using the createNode() method. A node is created as a child
     of a parent node. The child association name and child association type have to be
     supplied as QName objects, as well as the QName of the type of node to create and
     optionally a Map of properties to set on the newly created node.
     public ChildAssociationRef createNode(
             NodeRef parentRef,
             QName assocTypeQName,
             QName assocQName,
             QName nodeTypeQName,
             Map<QName, Serializable> properties)

     parentRef
        NodeRef of the parent node. The created node will be one of it's children.

     assocTypeQName
        QName of the type of association to create. This is used for verification against the
        data dictionary.

     assocQName
        QName of the association.

     nodeTypeQName
        QName of the node type.

     properties
        Optional Map of properties to set keyed by QName.

     The association and node type QName objects are usually defined as a static constants
     on the dictionary model interfaces. For example, the cm:contains association type is
     defined by the static constant ContentModel.ASSOC_CONTAINS and the cm:content
     node type is defined by the static constant ContentModel.TYPE_CONTENT. If a
     constant does not exist, a QName can be created using the QName.createQName()
     static method as in the example below.

     The createNode() method returns a ChildAssociationRef to the newly created
     child association. The NodeRef of the newly created node is obtained by calling the
     getChildRef() on the ChildAssociationRef object.



                                                                      API Development Course 45
Developing against the Alfresco Repository

                   The following example creates a new node of type cm:content, using the standard
                   cm:contains child association. The Map created in the previous step sets the
                   cm:name property on the newly created node.

                   NodeService nodeService = serviceRegistry.getNodeService();
                   ChildAssociationRef association = nodeService.createNode(companyHome,
                           ContentModel.ASSOC_CONTAINS,
                           QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX,
                    name),
                           ContentModel.TYPE_CONTENT,
                           contentProps);
                   NodeRef content = association.getChildRef();
             c.    Adding an aspect

                   Aspects are applied to nodes using the addAspect() method. The node is identified
                   by it's NodeRef and the aspect by it's QName. The property values are provided as a
                   Map.

                   public void addAspect(
                           NodeRef nodeRef,
                           QName aspectTypeQName,
                           Map<QName, Serializable> aspectProperties)

                   nodeRef
                      NodeRef of the node to apply the aspect to.

                   aspectTypeQName
                       QName of the aspect to apply.

                   aspectProperties
                      Map containing a minimum of the mandatory properties required for the aspect.

                   The aspect QNames are usually defined as a static constants on the dictionary model
                   interfaces. For example, the cm:titled aspect is defined by the static constant
                   ContentModel.ASPECT_TITLED.

                   The following example applies the cm:titled aspect and sets the cm:title and
                   cm:description properties:

                   Map<QName, Serializable> titledProps = new HashMap<QName,
                    Serializable>();
                   titledProps.put(ContentModel.PROP_TITLE, name);
                   titledProps.put(ContentModel.PROP_DESCRIPTION, name);
                   nodeService.addAspect(content, ContentModel.ASPECT_TITLED,
                    titledProps);
         6. Using the ContentService to write content

             The ContentService provides methods for reading, writing and transforming content.

             In order to read or write content from and to a node, you must first obtain a
             ContentReader or a ContentWriter via the getReader() and getWriter() methods
             respectively. Methods can then be used on the ContentReader or ContentWriter to
             read and write content. Both the ContentReader and the ContentWriter implement the
             methods defined by the ContentAccessor interface. These methods allow you to get and
             set information about the content, for example to set the mime type, the encoding or to get
             the size.

             The actual content is stored on the cm:content property (ContentModel.PROP_CONTENT)
             of each node. When requesting a ContentReader or a ContentWriter, the NodeRef
             needs to be supplied along with the ContentModel.PROP_CONTENT QName.

             The ContentService is also used for transforming content. A suitable transformer can
             be obtained for a given transformation (defined by a source and target mime type) using

46 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository

the getTransformer() and getImageTransformer() methods. The transformation can
then be performed by calling transform directly on the content transformer. Otherwise,
a transformation can be attempted from a source ContentReader object to target
ContentWriter object by calling the transform() method on the ContentService.

For more information, see Introduction on page 91.




      For clarity, not all of the available methods are shown. For a complete description,
      please consult the Javadocs:
         •   Interface ContentService
         •   Interface ContentReader
         •   Interface ContentWriter
         •   Interface ContentAccessor
The following example gets a ContentWriter to the newly created node. The property
to be updated is defined by the QName ContentModel.PROP_CONTENT. The boolean true
value is to request that the content is updated atomically when the content write stream
is closed. The content mime type and encoding are set before writing the content with the
putContent() method.

ContentService contentService = serviceRegistry.getContentService();
ContentWriter writer = contentService.getWriter(content,
 ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF-8");
String text = "The quick brown fox jumps over the lazy dog";
writer.putContent(text);



                                                                    API Development Course 47
Developing against the Alfresco Repository

     Once completed, the newly created node may be viewed via the Web client.




             The web client will need to be re-started after executing the sample to see the changes in
             effect.

Other Foundation Services
FileFolderService
     The FileFolderService provides methods specific to manipulating Alfresco defined content
     files and folders. The methods can be more convenient and easier to use than the equivalent
     NodeService and ContentService methods. Certain methods, such as create(), return a
     FileInfo object. A NodeRef can then be retrieved using the FileInfo.getNodeRef() method.




48 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository

For clarity, not all of the available methods are shown. For a complete description, please
consult the Javadocs:
   •   Interface FileFolderService
   •   Interface FileInfo




                                                                    API Development Course 49
Developing against the Alfresco Repository


JCR API

Introduction
     The JCR API (Java Content Repository) specifies a standard, implementation independent API to
     access content repositories in Java. It is defined by the Java Specification Request (JSR) 170 as
     part of the Java Community Process (JCP). The official JSR-170 Specification can be found on
     the JCP web site at the following address: http://jcp.org/en/jsr/detail?id=170
     Alfresco implements the JCR API against its own scalable repository and is actively contributing
     to the next version of JCR defined by the Java Specification Request (JSR) 283.

JCR Compliance Levels
     The JSR 170 specification defines two compliance levels and a set of additional optional features
     which repositories of either level may support.
     Level 1 provides for read functions and includes:
          • Retrieval and traversal of nodes and properties
          • Reading the values of properties
          • Transient namespace remapping
          • Export to XML/SAX
          • Query facility with XPath syntax
          • Discovery of available node types
          • Discovery of access control permissions

     Level 2 adds additional write functions:
          • Adding and removing nodes and properties
          • Writing the values of properties
          • Persistent namespace changes
          • Import from XML/SAX
          • Assigning node types to nodes

     Optionally, any combination of the following features may be added to an implementation of either
     level:
          • Transactions
          • Versioning
          • Observation (Events)
          • Locking
          • SQL syntax for query

JCR Repository Model
     Like the Alfresco repository, a JCR repository consists of one or more workspaces, each of
     which contains a tree of items. An item is either a node or a property. Each node may have
     zero or more child nodes and zero or more child properties. There is a single root node per
     workspace, which has no parent. Unlike the Alfresco repository, all other nodes have only one
     parent. Properties have one parent (a node) and cannot have children; they are the leaves of the
     tree. All of the actual content in the repository is stored within the values of the properties.



50 Alfresco Enterprise Edition Version 3.2
Developing against the Alfresco Repository

    Any item in the tree hierarchy can be identified by either an absolute or a relative path using
    a Unix style path syntax. The path / refers to the root node of a workspace and the path /
    app:company_home refers to the “Company Home” space in the standard Alfresco SpacesStore
    workspace. The special paths “.” and “..” (meaning respectively, “this” and “parent”) are also
    supported.

FirstJCRClient   Walkthrough
    Before getting started, you should be familiar with the Introduction on page 34.

    The sample uses several of the basic JCR APIs, including Repository, Session and Node. After
    initialising the Spring Application Context and starting the repository in embedded mode, we will
    use the Spring getBean() method to access the JCR.Repository.

    After logging into the JCR repository, we will navigate to the “Company Home” node. We will then
    create a new node with properties, add an aspect and write some content. Finally, we will mix the
    JCR API calls with the Alfresco Foundation Services API calls to set the content mime type. The
    sample is wrapped by an implicit JCR transaction.

      1. Getting the JCR.Repository

          The JCR repository as a whole is represented by a Repository object. JSR-170 does not
          dictate how to obtain the Repository object. In Alfresco, the JSR repository is a Spring
          bean called JCR.Repository.

          The JCR.Repository bean is defined in jcr-api-context.xml. It has one configuration
          parameter; the default workspace name. This is used when a JCR client performs a login
          without specifying the workspace. The default workspace is SpacesStore, the same one
          used by the Alfresco Web Client.
          <bean id="JCR.Repository"
                class="org.alfresco.jcr.repository.RepositoryImpl"
                init-method="init">
             <property name="serviceRegistry">
                <ref bean="ServiceRegistry"/>
             </property>
             <property name="importerComponent">
                <ref bean="importerComponent"/>
             </property>
             <property name="defaultWorkspace">
                <value>SpacesStore</value>
             </property>
          </bean>

          The following example uses the Spring getBean() method to access the JCR Repository:
          ApplicationContext context = new
           ClassPathXmlApplicationContext("classpath:alfresco/application-
          context.xml");
          Repository repository = (Repository)context.getBean("JCR.Repository");
      2. Logging into the repository (creating a Session)

          A client connects to the repository by calling the login() method on the Repository
          object. The client must supply a Credentials object and optionally a workspace name.
          Behind the scenes, Alfresco uses the authentication system of the Alfresco repository
          which by default is Alfresco's own, but it could also be NTLM, LDAP or your own
          depending on how the repository has been configured.

          If a workspace is not provided, the default as defined earlier will be used. The Session
          returned from login is tied to the workspace and allows read and write operations upon
          that workspace. By default, the Session is also backed by a transaction. Work performed



                                                                               API Development Course 51
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide
2140 api developer-student-guide

Mais conteúdo relacionado

Mais procurados

Commonwealth Life Perusahaan Asuransi Jiwa Terbaik Indonesia
Commonwealth Life Perusahaan Asuransi Jiwa Terbaik IndonesiaCommonwealth Life Perusahaan Asuransi Jiwa Terbaik Indonesia
Commonwealth Life Perusahaan Asuransi Jiwa Terbaik IndonesiaBen Seo
 
Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...
Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...
Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...Paula Peterson
 
Parallels Plesk Panel 9 Reseller's Guide
Parallels Plesk Panel 9 Reseller's GuideParallels Plesk Panel 9 Reseller's Guide
Parallels Plesk Panel 9 Reseller's Guidewebhostingguy
 
Protective Device Coordination
Protective Device CoordinationProtective Device Coordination
Protective Device Coordinationjoeengi
 
Erp cloud service integration how end to-end_automation
Erp cloud service integration how end to-end_automationErp cloud service integration how end to-end_automation
Erp cloud service integration how end to-end_automationVikas Rai PRINCE2® ITIL®
 
06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...
06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...
06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...Roxanne Grinage
 
SOA A View from the Trenches
SOA A View from the TrenchesSOA A View from the Trenches
SOA A View from the TrenchesTim Vibbert
 
Tfa collector docv121210
Tfa collector docv121210Tfa collector docv121210
Tfa collector docv121210Hanh Nguyen Duy
 
ISO/IEC 17025 Accreditation Requirements
ISO/IEC 17025 Accreditation RequirementsISO/IEC 17025 Accreditation Requirements
ISO/IEC 17025 Accreditation RequirementsACLASS
 
AppLoader User Guide
AppLoader User GuideAppLoader User Guide
AppLoader User GuideNRG Global
 
Acrobat document
Acrobat documentAcrobat document
Acrobat documentesregroup
 

Mais procurados (18)

Commonwealth Life Perusahaan Asuransi Jiwa Terbaik Indonesia
Commonwealth Life Perusahaan Asuransi Jiwa Terbaik IndonesiaCommonwealth Life Perusahaan Asuransi Jiwa Terbaik Indonesia
Commonwealth Life Perusahaan Asuransi Jiwa Terbaik Indonesia
 
NHS Fusion Financials - Accounts Department User Guide
NHS Fusion Financials - Accounts Department User GuideNHS Fusion Financials - Accounts Department User Guide
NHS Fusion Financials - Accounts Department User Guide
 
Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...
Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...
Interoperable Seafood Traceability Technology Architecture Issues Brief 11 6 ...
 
Admin
AdminAdmin
Admin
 
B13922
B13922B13922
B13922
 
Parallels Plesk Panel 9 Reseller's Guide
Parallels Plesk Panel 9 Reseller's GuideParallels Plesk Panel 9 Reseller's Guide
Parallels Plesk Panel 9 Reseller's Guide
 
Hacking.pdf
Hacking.pdfHacking.pdf
Hacking.pdf
 
Connection en
Connection enConnection en
Connection en
 
Protective Device Coordination
Protective Device CoordinationProtective Device Coordination
Protective Device Coordination
 
Erp cloud service integration how end to-end_automation
Erp cloud service integration how end to-end_automationErp cloud service integration how end to-end_automation
Erp cloud service integration how end to-end_automation
 
06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...
06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...
06/25/12 Posted to HireLyrics U.S. Citizens Public Docket Alaska Families New...
 
SOA A View from the Trenches
SOA A View from the TrenchesSOA A View from the Trenches
SOA A View from the Trenches
 
Icp
IcpIcp
Icp
 
Tfa collector docv121210
Tfa collector docv121210Tfa collector docv121210
Tfa collector docv121210
 
ISO/IEC 17025 Accreditation Requirements
ISO/IEC 17025 Accreditation RequirementsISO/IEC 17025 Accreditation Requirements
ISO/IEC 17025 Accreditation Requirements
 
AppLoader User Guide
AppLoader User GuideAppLoader User Guide
AppLoader User Guide
 
Manual ssb
Manual ssbManual ssb
Manual ssb
 
Acrobat document
Acrobat documentAcrobat document
Acrobat document
 

Destaque

Tech talk live on new alfresco api
Tech talk live on new alfresco apiTech talk live on new alfresco api
Tech talk live on new alfresco apiAlfresco Software
 
Alfresco Share Customization Made Easy With Side Labs
Alfresco Share Customization Made Easy With Side LabsAlfresco Share Customization Made Easy With Side Labs
Alfresco Share Customization Made Easy With Side LabsAlfresco Software
 
Intro to the Alfresco Public API
Intro to the Alfresco Public APIIntro to the Alfresco Public API
Intro to the Alfresco Public APIJeff Potts
 
Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64Alfresco Software
 
Alfresco Day Vienna 2016: Alfrescos neue Rest API
Alfresco Day Vienna 2016: Alfrescos neue Rest APIAlfresco Day Vienna 2016: Alfrescos neue Rest API
Alfresco Day Vienna 2016: Alfrescos neue Rest APIAlfresco Software
 
Installing and Getting Started with Alfresco
Installing and Getting Started with AlfrescoInstalling and Getting Started with Alfresco
Installing and Getting Started with AlfrescoWildan Maulana
 
Intro to Alfresco for Developers
Intro to Alfresco for DevelopersIntro to Alfresco for Developers
Intro to Alfresco for DevelopersJeff Potts
 
Getting Started with CMIS
Getting Started with CMISGetting Started with CMIS
Getting Started with CMISJeff Potts
 
Alfresco In An Hour - Document Management, Web Content Management, and Collab...
Alfresco In An Hour - Document Management, Web Content Management, and Collab...Alfresco In An Hour - Document Management, Web Content Management, and Collab...
Alfresco In An Hour - Document Management, Web Content Management, and Collab...Alfresco Software
 

Destaque (9)

Tech talk live on new alfresco api
Tech talk live on new alfresco apiTech talk live on new alfresco api
Tech talk live on new alfresco api
 
Alfresco Share Customization Made Easy With Side Labs
Alfresco Share Customization Made Easy With Side LabsAlfresco Share Customization Made Easy With Side Labs
Alfresco Share Customization Made Easy With Side Labs
 
Intro to the Alfresco Public API
Intro to the Alfresco Public APIIntro to the Alfresco Public API
Intro to the Alfresco Public API
 
Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64Alfresco tech talk live public api episode 64
Alfresco tech talk live public api episode 64
 
Alfresco Day Vienna 2016: Alfrescos neue Rest API
Alfresco Day Vienna 2016: Alfrescos neue Rest APIAlfresco Day Vienna 2016: Alfrescos neue Rest API
Alfresco Day Vienna 2016: Alfrescos neue Rest API
 
Installing and Getting Started with Alfresco
Installing and Getting Started with AlfrescoInstalling and Getting Started with Alfresco
Installing and Getting Started with Alfresco
 
Intro to Alfresco for Developers
Intro to Alfresco for DevelopersIntro to Alfresco for Developers
Intro to Alfresco for Developers
 
Getting Started with CMIS
Getting Started with CMISGetting Started with CMIS
Getting Started with CMIS
 
Alfresco In An Hour - Document Management, Web Content Management, and Collab...
Alfresco In An Hour - Document Management, Web Content Management, and Collab...Alfresco In An Hour - Document Management, Web Content Management, and Collab...
Alfresco In An Hour - Document Management, Web Content Management, and Collab...
 

Semelhante a 2140 api developer-student-guide

Epo 450 product_guide_en-us
Epo 450 product_guide_en-usEpo 450 product_guide_en-us
Epo 450 product_guide_en-uslvaloto
 
Instructor utilities guide
Instructor utilities guideInstructor utilities guide
Instructor utilities guideapaezgonzal
 
X cart 430-manual
X cart 430-manualX cart 430-manual
X cart 430-manualmadtgw
 
Artromick Ac Hostguide304 for Hospital Computing Solutions
Artromick Ac Hostguide304 for Hospital Computing SolutionsArtromick Ac Hostguide304 for Hospital Computing Solutions
Artromick Ac Hostguide304 for Hospital Computing SolutionsArtromick
 
Quick testprofessional book_preview
Quick testprofessional book_previewQuick testprofessional book_preview
Quick testprofessional book_previewSaurabh Singh
 
WebHost Manager User Manual
WebHost Manager User ManualWebHost Manager User Manual
WebHost Manager User Manualwebhostingguy
 
WebHost Manager User Manual
WebHost Manager User ManualWebHost Manager User Manual
WebHost Manager User Manualwebhostingguy
 
ZebraNet Bridge Enterprise - Manual do Software
ZebraNet Bridge Enterprise - Manual do SoftwareZebraNet Bridge Enterprise - Manual do Software
ZebraNet Bridge Enterprise - Manual do SoftwareUseZ
 
An c xml_punchout_implementation
An c xml_punchout_implementationAn c xml_punchout_implementation
An c xml_punchout_implementationNand Singh
 
Artromick Mcm Manual for Hospital Computing Solutions
Artromick Mcm Manual for Hospital Computing SolutionsArtromick Mcm Manual for Hospital Computing Solutions
Artromick Mcm Manual for Hospital Computing SolutionsArtromick
 
Guia definitiva de shodan
Guia definitiva de shodanGuia definitiva de shodan
Guia definitiva de shodannoc_313
 
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's GuidePlesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guidewebhostingguy
 
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's GuidePlesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guidewebhostingguy
 
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's GuidePlesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guidewebhostingguy
 
ARQUIVO ROUBADO
ARQUIVO ROUBADOARQUIVO ROUBADO
ARQUIVO ROUBADOD813061988
 
Spartan 3e用户手册
Spartan 3e用户手册Spartan 3e用户手册
Spartan 3e用户手册zhaojk90
 
TRU_v29_Reference_Manual_EN_20140325.pdf
TRU_v29_Reference_Manual_EN_20140325.pdfTRU_v29_Reference_Manual_EN_20140325.pdf
TRU_v29_Reference_Manual_EN_20140325.pdfPEDRO MORALES HERNANDEZ
 
1ux2y54tcwomq2gtx7pd
1ux2y54tcwomq2gtx7pd1ux2y54tcwomq2gtx7pd
1ux2y54tcwomq2gtx7pdJuanfe1978
 
Pengenalan kepada Pentaho
Pengenalan kepada PentahoPengenalan kepada Pentaho
Pengenalan kepada PentahoHisyammudin
 

Semelhante a 2140 api developer-student-guide (20)

Epo 450 product_guide_en-us
Epo 450 product_guide_en-usEpo 450 product_guide_en-us
Epo 450 product_guide_en-us
 
Instructor utilities guide
Instructor utilities guideInstructor utilities guide
Instructor utilities guide
 
X cart 430-manual
X cart 430-manualX cart 430-manual
X cart 430-manual
 
Artromick Ac Hostguide304 for Hospital Computing Solutions
Artromick Ac Hostguide304 for Hospital Computing SolutionsArtromick Ac Hostguide304 for Hospital Computing Solutions
Artromick Ac Hostguide304 for Hospital Computing Solutions
 
Quick testprofessional book_preview
Quick testprofessional book_previewQuick testprofessional book_preview
Quick testprofessional book_preview
 
WebHost Manager User Manual
WebHost Manager User ManualWebHost Manager User Manual
WebHost Manager User Manual
 
WebHost Manager User Manual
WebHost Manager User ManualWebHost Manager User Manual
WebHost Manager User Manual
 
ZebraNet Bridge Enterprise - Manual do Software
ZebraNet Bridge Enterprise - Manual do SoftwareZebraNet Bridge Enterprise - Manual do Software
ZebraNet Bridge Enterprise - Manual do Software
 
An c xml_punchout_implementation
An c xml_punchout_implementationAn c xml_punchout_implementation
An c xml_punchout_implementation
 
Artromick Mcm Manual for Hospital Computing Solutions
Artromick Mcm Manual for Hospital Computing SolutionsArtromick Mcm Manual for Hospital Computing Solutions
Artromick Mcm Manual for Hospital Computing Solutions
 
Guia definitiva de shodan
Guia definitiva de shodanGuia definitiva de shodan
Guia definitiva de shodan
 
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's GuidePlesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
 
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's GuidePlesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
 
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's GuidePlesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
Plesk Sitebuilder 4.5 for Linux/Unix Wizard User's Guide
 
Amdin iws7 817-2179-10
Amdin iws7 817-2179-10Amdin iws7 817-2179-10
Amdin iws7 817-2179-10
 
ARQUIVO ROUBADO
ARQUIVO ROUBADOARQUIVO ROUBADO
ARQUIVO ROUBADO
 
Spartan 3e用户手册
Spartan 3e用户手册Spartan 3e用户手册
Spartan 3e用户手册
 
TRU_v29_Reference_Manual_EN_20140325.pdf
TRU_v29_Reference_Manual_EN_20140325.pdfTRU_v29_Reference_Manual_EN_20140325.pdf
TRU_v29_Reference_Manual_EN_20140325.pdf
 
1ux2y54tcwomq2gtx7pd
1ux2y54tcwomq2gtx7pd1ux2y54tcwomq2gtx7pd
1ux2y54tcwomq2gtx7pd
 
Pengenalan kepada Pentaho
Pengenalan kepada PentahoPengenalan kepada Pentaho
Pengenalan kepada Pentaho
 

2140 api developer-student-guide

  • 2. Copyright (c) 2007 by Alfresco and others. Information in this document is subject to change without notice. No part of this document may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose, without the express written permission of Alfresco. The trademarks, service marks, logos or other intellectual property rights of Alfresco and others used in this documentation (“Trademarks”) are the property of Alfresco and their respective owners. The furnishing of this document does not give you license to these patents, trademarks, copyrights or other intellectual property except as expressly provided in any written agreement from Alfresco. The United States export control laws and regulations, including the Export Administration Regulations of the U.S. Department of Commerce, and other applicable laws and regulations apply to this documentation which prohibit the export or re-export of content, products, services, and technology to certain countries and persons. You agree to comply with all export laws, regulations and restrictions of the United States and any foreign agency or authority and assume sole responsibility for any such unauthorized exportation. If you need technical support for this product, contact Customer Support by email at support@alfresco.com. If you have comments or suggestions about this documentation, contact us at documentation@alfresco.com. This edition applies to version 2.1 of the licensed program. 2
  • 3. Contents Introduction................................................................................................................................ 6 Welcome.............................................................................................................................. 7 How this course is delivered....................................................................................... 7 Course Schedule......................................................................................................... 7 How Prepared are You?..............................................................................................8 Topics not Covered..................................................................................................... 8 Introductions.................................................................................................................8 Getting Started...........................................................................................................................9 Alfresco SDK..................................................................................................................... 10 Introduction.................................................................................................................10 Downloading and Unpacking the Alfresco SDK........................................................ 10 Importing the Alfresco SDK projects into Eclipse......................................................11 Associating Source Code and Javadocs with the Alfresco Libraries......................... 14 SDK samples............................................................................................................. 16 SVN Repository......................................................................................................... 19 SDK Reference.......................................................................................................... 20 Best Practices....................................................................................................................22 Coding Standards...................................................................................................... 22 Alfresco Module Packages (AMP).............................................................................22 Alfresco Repository Architecture....................................................................................... 24 Out of the Box........................................................................................................... 24 Service & Component Architecture........................................................................... 25 Repository Foundation Services API.........................................................................27 Repository APIs......................................................................................................... 28 Repository Server Protocols...................................................................................... 29 Terminology................................................................................................................30 Developing against the Alfresco Repository........................................................................33 Spring Framework............................................................................................................. 34 Introduction.................................................................................................................34 Bean Factory..............................................................................................................34 Inversion of Control (IoC).......................................................................................... 35 Application Context.................................................................................................... 39 Foundation Services API................................................................................................... 40 Introduction.................................................................................................................40 Access to Repository Foundation Services...............................................................40 FirstFoundationClient walkthrough............................................................................ 40 Other Foundation Services........................................................................................ 48 JCR API............................................................................................................................. 50 Introduction.................................................................................................................50 JCR Compliance Levels............................................................................................ 50 JCR Repository Model...............................................................................................50 API Development Course 3
  • 4. FirstJCRClient Walkthrough.......................................................................................51 JCR Transactions...................................................................................................... 53 Web Services API............................................................................................................. 55 Introduction.................................................................................................................55 Available Web Services.............................................................................................55 Access to Web Services in Java...............................................................................55 Web Services Data Types.........................................................................................56 Content Manipulation Language (CML).....................................................................56 FirstWebServiceClient Walkthrough.......................................................................... 57 Separating Concerns using AOP...................................................................................... 61 Public Services and AOP proxies............................................................................. 61 Security Enforcement.................................................................................................61 Transaction Management.......................................................................................... 64 Extending the Alfresco Repository....................................................................................... 69 Repository Policies............................................................................................................ 70 Introduction.................................................................................................................70 Available Policies....................................................................................................... 70 Policy Types...............................................................................................................71 Custom Aspect with Behaviour Howto...................................................................... 71 Repository Actions.............................................................................................................79 Introduction.................................................................................................................79 Repository Action Howto........................................................................................... 79 Repository Action with Parameters Howto................................................................ 85 Content Transformers........................................................................................................91 Introduction.................................................................................................................91 Content Transformer Howto...................................................................................... 91 ContentTransformerRegistry...................................................................................... 95 Further Reading......................................................................................................... 97 Metadata Extractors...........................................................................................................98 Introduction.................................................................................................................98 MetadataExtracterRegistry.........................................................................................98 Metadata Extractor Howto......................................................................................... 99 Further Reading....................................................................................................... 103 Extending the Alfresco Web Client..................................................................................... 105 JavaServer Faces............................................................................................................106 Introduction...............................................................................................................106 Login Page Walkthrough......................................................................................... 106 Actions Framework.......................................................................................................... 116 Introduction...............................................................................................................116 Update UI Action Walkthrough................................................................................ 116 Actions Framework Reference................................................................................ 120 Dialog Framework............................................................................................................123 Introduction...............................................................................................................123 4 Alfresco Enterprise Edition Version 3.2
  • 5. Custom Dialog Howto..............................................................................................123 Further Information.................................................................................................. 128 Dialog Framework Reference.................................................................................. 130 Wizard Framework...........................................................................................................132 Introduction...............................................................................................................132 Custom Wizard Howto.............................................................................................132 Further Reading....................................................................................................... 137 Wizard Framework Reference................................................................................. 139 Packaging Extensions.......................................................................................................... 142 Alfresco Module Packages.............................................................................................. 143 Introduction...............................................................................................................143 Basic AMP Howto....................................................................................................143 Further Reading....................................................................................................... 149 Alfresco Module Package Reference...................................................................... 150 API Development Course 5
  • 7. Introduction Welcome Welcome to Alfresco API development. This course has been designed to provide you with the knowledge and skills necessary to develop against the Alfresco Repository APIs and to develop extensions for the Alfresco enterprise content management system. How this course is delivered This course is delivered in 17 modules, each module focusing on a specific subject. All modules include a combination of introductory materials, an outline of objectives followed by instructor- led discussions and walkthroughs. Each module will close with one or more exercises which will allow students to use and demonstrate what they have learned in each module. Course objectives At the conclusion of this course you should be comfortable with all the concepts and tasks required to competently: • Set up your own development environment and use the Alfresco SDK • Develop against the Alfresco APIs (Foundation Services, JCR, Web Services) • Develop extensions for the Alfresco Repository • Develop extensions for the Alfresco Web Client • Package and deploy extensions Certification track objectives At the conclusion of this course, you should have also acquired the requisite knowledge and abilities to pass the Alfresco API developer exam in preparation for the Certified Alfresco ECM professional certificate. Course Schedule Day 1 • Getting Started • Alfresco SDK • Best Practices • Alfresco Repository Architecture • Developing against the Alfresco Repository • The Spring Framework • Foundation Services API • Java Content Repository (JCR) API • Web Services API Day 2 • Developing against the Alfresco Repository • Separating Concerns using AOP • Extending the Alfresco Repository • Repository Policies • Repository Actions API Development Course 7
  • 8. Introduction • Content Transformers • Metadata Extractors Day 3 • Extending the Web Client • JavaServer Faces • Actions Framework • Dialog Framework • Wizard Framework • Packaging Extensions • Alfresco Module Packages How Prepared are You? • Can you program in Java? • Do you have a basic understanding of XML? • Have you followed the Alfresco administration course? • Have you followed the Alfresco customisation course? • Are you familiar with the Eclipse IDE? Topics not Covered • Installing Alfresco • Repository configuration • Web Client configuration • Customising the Data Dictionary • Developing JavaScript extensions • Developing Freemarker templates • Developing Web Scripts Introductions • Name • Company • Title, function, job responsibility • Alfresco experience (API development experience) • Courses already taken • Reasons for taking this course • Expectations 8 Alfresco Enterprise Edition Version 3.2
  • 9. Getting Started Getting Started API Development Course 9
  • 10. Getting Started Alfresco SDK Introduction The Alfresco SDK provides support for developers who wish to extend or customise the Alfresco platform. It has been designed for the developer to get developing with minimal fuss for the following development scenarios: • Developing extensions for the Alfresco Repository and Web Client. • Embedding Alfresco into applications via Alfresco's Java Foundation Services API or standards-compliant JCR API. • Developing applications against a remote Alfresco Repository via Alfresco's Web Services API. Typically, the SDK is used stand-alone, but an Alfresco installation is also required if performing any of the following: • Customising the Alfresco Web Client • Deploying a custom module to a remote Alfresco repository • Testing a custom application that connects to a remote Alfresco repository The SDK is not designed for re-building Alfresco since it does not provide full build scripts and artifacts. If you wish to develop bug fixes or extend the core functionality of the Alfresco platform, you should use the full Alfresco development environment provided in the Alfresco SVN Repository. For more information, see SVN Repository on page 19. Downloading and Unpacking the Alfresco SDK You will need to install the following software and development tools in order to use the SDK correctly: • the Java SE Development Kit (JDK) version 1.5 (5.0) or above; • a supported database of your choice (MySQL is recommended for development purposes); • the Eclipse IDE 3.x (highly recommended). The Alfresco SDK bundle is provided with each release of Alfresco, for both the Enterprise and Community Networks. 1. Downloading the Alfresco SDK The Enterprise SDK is only available to Enterprise clients and partners. The Community SDK is freely available and can be downloaded from the Download Alfresco Community Network page on the Alfresco Developer web site. The SDK is provided in both ZIP and TAR (tar.gz) formats. 2. Unpacking the Alfresco SDK To install the SDK, simply unpack the downloaded ZIP or TAR bundle to a directory of your choice. 10 Alfresco Enterprise Edition Version 3.2
  • 11. Getting Started For a description of the contents of the Alfresco SDK, see SDK Contents on page 20. Importing the Alfresco SDK projects into Eclipse When using the Alfresco SDK, the Eclipse IDE is highly recommended. The SDK contains several pre-configured Eclipse projects that you can import directly into Eclipse with the following procedure. 1. Setting the Eclipse Compiler Compliance Level Alfresco uses Java 1.5 (5.0) language features, therefore Eclipse must be configured appropriately for the Java SE Development Kit (JDK) version 1.5 (5.0) or above. a. From the Eclipse main menu, select Window # Preferences... b. In the Preferences dialog, select Java # Compiler in the tree view. c. In the JDK Compliance panel, set the Compiler compliance level to 5.0 or above: API Development Course 11
  • 12. Getting Started d. Click OK 2. Importing the Alfresco SDK projects a. From the Eclipse main menu, select File # Import... b. In the Import dialog, select General # Existing Projects into Workspace import source and click Next > c. Choose Select root directory option and click Browse... d. Navigate to the file system directory where you unpacked the Alfresco SDK and click OK. The Alfresco SDK projects are now listed under Projects. Do not navigate to the samples sub-directory, otherwise you will not see the SDK AlfrescoEmbedded and SDK AlfrescoRemote projects in the list. 12 Alfresco Enterprise Edition Version 3.2
  • 13. Getting Started In order to run the samples or to develop your own extension modules, you must import at least the SDK AlfrescoEmbedded and SDK AlfrescoRemote projects. The other SDK projects are samples for common development scenarios that you can study and run to learn more about developing Alfresco extension modules. For more information about the available projects, see SDK Eclipse Projects on page 20. e. Once you have selected the projects you wish to import, click Finish. The imported projects are displayed in the Package Explorer: API Development Course 13
  • 14. Getting Started Associating Source Code and Javadocs with the Alfresco Libraries Once the Alfresco SDK projects have been imported into Eclipse, it is useful to have access to Alfresco's source code and Java documentation. The following procedure explains how to do this by associating the source code and Javadocs with the Alfresco libraries within Eclipse. 1. Expand the SDK AlfrescoEmbedded project in the Project Explorer. 2. Right click on the alfresco-repository.jar and select Properties from the popup menu. The JAR files may not be in alphabetical order. 3. Associating source code a. In the Properties for alfresco-repository.jar dialog, select Java Source Attachment in the tree view. b. In the Java Source Attachment panel, click External File... c. Navigate to src directory within your unpacked Alfresco SDK. d. Select repository-src.zip and click Open. 14 Alfresco Enterprise Edition Version 3.2
  • 15. Getting Started 4. Associating Javadocs a. In the Properties for alfresco-repository.jar dialog, select Javadoc Location in the tree view. b. In the Javadoc Location panel, select Javadoc in archive and click Browse... c. Navigate to doc/api directory within your unpacked Alfresco SDK. d. Select repository-doc.zip and click Open. e. Click Validate... to validate the Javadoc location, then click either OK to view the Javadocs in a web browser or Cancel if not. API Development Course 15
  • 16. Getting Started 5. Click OK, to close the Properties dialog. Once the source code and Javadocs have been attached, the alfresco-repository.jar icon changes to include a small document: The above steps need to be repeated for the following JARs: • alfresco-core.jar • alfresco-remote-api.jar • alfresco-web-client.jar • alfresco-web-service-client.jar (only Java source code is available) SDK samples FirstFoundationClient and JCR Samples The SDK FirstFoundationClient, SDK FirstJCRClient and SDK JCRSamples sample projects demonstrate how to access an embedded Alfresco repository via the Foundation Services API and the standards-compliant JCR API. These samples can be tested directly from within Eclipse and will automatically start an Alfresco repository in embedded mode. Before starting, the embedded repository needs to be configured. By default, the sample projects are configured to use a MySQL database named alfresco and a data directory with a relative path of ./alf_data. These parameters are defined in the custom-repository.properties file in the source/alfresco/extension directory of each project. It is good practice to define an absolute path for the data directory (dir.root parameter) and to configure all of the SDK projects to share the same database and the same dir.root. Example custom-repository.properties file: dir.root=C:/alf_data 16 Alfresco Enterprise Edition Version 3.2
  • 17. Getting Started #db.username=alfresco #db.password=alfresco # # MySQL connection (This is default and requires mysql-connector-java-3.1.12- bin.jar, which ships with the Alfresco server) # #db.driver=org.gjt.mm.mysql.Driver #db.url=jdbc:mysql://localhost/alfresco The alfresco MySQL database also needs to be created using the scripts provided in the extras/databases/mysql directory of the unpacked Alfresco SDK. To create the database from the command line: C:alfresco-enterprise-sdkextrasdatabasesmysql>mysql -u root -p < db_setup.sql Enter password: ******** The samples can now be tested by running the main Java classes from within Eclipse. In the following example, the FirstFoundationClient class is run as a Java Application: The Alfresco repository is automatically started in embedded mode. Because this is the first time the repository has been started, the initial bootstrap is executed to create the database tables. As you can see from the console messages below, the embedded repository uses C:alf_data as it's data directory (dir.root). API Development Course 17
  • 18. Getting Started The other embedded repository samples (SDK FirstJCRClient and SDK JCRSamples) can be run in the same way. Web Services Samples The SDK FirstWebServiceClient and SDK WebServiceSamples sample projects demonstrate how to access a remote Alfresco repository via the Web Services API. A remote Alfresco repository needs to be installed and running before testing one of these samples. Before running one of the Web Services samples, a remote repository needs to be installed and configured. The easiest solution for development purposes is to install Alfresco on the local machine and configure it to use the same alfresco MySQL database and the same C:/alf_dir data directory as the embedded repository used for the other samples. The location of the remote repository is configured in the webserviceclient.properties file in the source/alfresco/extension directory of each Web Services project. If the remote repository is installed on the same machine and configured to use the default 8080 port, you will not have to modify the default value. Example webserviceclient.properties file: # # Set the following property to reference the Alfresco server that you would like web service client # to communicate with repository.location=http://localhost:8080/alfresco/api Once the remote repository has been installed and started, the Web Clients samples can be tested by running the main Java classes from within Eclipse. In the following example, the FirstWebServiceClient class is run as a Java Application: Custom Repository Samples The SDK CustomAction and SDK CustomAspect sample projects demonstrate how to develop custom modules that may be deployed to an Alfresco repository. Initially, custom repository 18 Alfresco Enterprise Edition Version 3.2
  • 19. Getting Started modules can be developed and tested using unit tests and an embedded Alfresco repository. The SDK CustomAspect project has a sample unit test that does this. An Ant build.xml file is provided for packaging the repository samples. The package target packages the compiled classes and extension files into a JAR file. To deploy the samples, copy the JAR file to the WEB-INF/lib folder of an existing Alfresco installation and restart the application server. For deployment in a production environment, a custom repository module should be packaged as an Alfresco Module Package (AMP). For more information on creating a custom repository action, see the Repository Action Howto on page 79. For a detailed presentation of the SDK CustomAspect sample, see the Custom Aspect with Behaviour Howto on page 71. Custom Web Client Samples The SDK CustomDialog, SDK CustomJSP, SDK CustomLogin, SDK CustomWizard, and SDK TaggingSample sample projects demonstrate how to develop custom modules for the Alfresco Web Client. Custom Web Client modules have to be deployed to an existing Alfresco installation for testing. An Ant build.xml file is provided for packaging the Web Client samples. The package- jar target packages the compiled classes and extension files into a JAR file. The package- extension target then packages the JAR file along with the JSPs into a ZIP file. The optional integrate-extension target can be used to integrate the packaged ZIP file into an Alfresco Web Client WAR file. The alfresco.war file must be copied to the same directory as the build.xml file before running the Ant build and then re-deployed to the application server. For deployment in a production environment, a custom Web Client module should be packaged as an Alfresco Module Package (AMP). The SDK CustomDialog and SDK CustomWizard are presented in detail in the Custom Dialog Howto on page 123 and the Custom Wizard Howto on page 132. The SDK TaggingSample sample is presented in detail in the Repository Action Howto on page 79. Basic AMP Sample The SDK Basic AMP sample project demonstrates how to structure a project and how to arrange classes and configuration files to generate an Alfresco Module Package (AMP). For more information see Basic AMP Howto on page 143. SVN Repository The Alfresco Subversion repository gives you access to all of the Alfresco source code and build artifacts. It provides the latest work-in-progress developments. It should only be used if you wish to extend the Alfresco core framework or work on Alfresco bug fixes as it allows you to perform full re-builds of Alfresco itself. For most requirements, it is best to use the Alfresco SDK. Public read-only access to the Alfresco Subversion repository is available from the Alfresco web site. To checkout the source code, use the following procedure: 1. Install Subversion and ensure that svn is on the path. 2. Checkout the HEAD of the code stream: svn co svn://svn.alfresco.com/alfresco/HEAD or svn co http://svn.alfresco.com/repos/alfresco-open-mirror/alfresco/HEAD 3. Keep up to date by issuing the command: svn update API Development Course 19
  • 20. Getting Started SDK Reference SDK Contents bin Supporting dll's, exe's. doc Zipped Javadoc's for all pre-built libraries. extras Additional files - database setup and migration scripts. lib Alfresco pre-built libraries (JAR files). lib/deployment Alfresco libraries required for WCM deployment to a remote server. lib/remote Alfresco libraries required for access to a remote Alfresco repository via web services. lib/server Alfresco libraries required for embedding an Alfresco repository. licenses License files. samples Sample Eclipse projects for common development scenarios (see SDK Eclipse Projects on page 20). src Zipped source code for all pre-built libraries. license.txt Alfresco licence file. notice.txt Notices readme.txt Alfresco SDK readme. SDK Eclipse Projects SDK AlfrescoEmbedded Project containing all of the Alfresco libraries needed to build a custom module that will be embedded into the Alfresco repository or Web Client. SDK AlfrescoRemote Project containing all of the Alfresco libraries needed to build a custom Web Services client. SDK Basic AMP Sample project demonstrating how to build an AMP (Alfresco Module Package) file. SDK CustomAction Sample project demonstrating how to develop a custom Action that may be deployed to an Alfresco repository. SDK CustomAspect Sample project demonstrating how to develop a custom Aspect with behaviour that may be deployed to an Alfresco repository. 20 Alfresco Enterprise Edition Version 3.2
  • 21. Getting Started SDK CustomDialog Sample project demonstrating how to develop and configure a custom Dialog for the Alfresco Web Client. SDK CustomJSP Sample project demonstrating how to develop and configure a custom JSP for the Alfresco Web Client. SDK CustomLogin Sample project demonstrating how to override the Login page of the Alfresco Web Client. SDK CustomWizard Sample project demonstrating how to develop and configure a custom Wizard for the Alfresco Web Client. SDK FirstFoundationClient Sample project demonstrating how to access an Alfresco (embedded) repository via the Foundation Services API. SDK FirstJCRClient Sample project demonstrating how to access an Alfresco (embedded) repository via the standards-compliant JCR API. SDK FirstWebServiceClient Sample project demonstrating how to access a remote Alfresco repository via the Web Services API. SDK JCRSamples More sample projects demonstrating how to access an Alfresco (embedded) repository via the standards-compliant JCR API. SDK TaggingSample Advanced sample project demonstrating how to develop a custom Action that takes parameters. SDK WebServiceSamples More sample projects demonstrating how to access a remote Alfresco repository via the Web Services API. API Development Course 21
  • 22. Getting Started Best Practices Coding Standards Coding Standards - Formatting • The core coding standards are the standard Java Code Conventions. • Braces are on new lines. • 4 space for tabbing, except for Web Client project that uses 3 spaces. • 120 characters on a line is fine. • Import declarations are managed by Eclipse's standard ordering rules (CTRL-SHIFT-O). This helps prevent code merge conflicts. • XML documents use 3 space tabbing. The Eclipse plug-in, XMLBuddy, is generally used. Coding Standards - Exceptions • When generating a new exception, always attach the cause to it. • Don't log exceptions unless you are adding the logic to absorb the exception. • Put as much context and formatting into the error message as possible. • Use RuntimeException derived exceptions, unless there is a really good reason to bother the client code with a checked exception. • Pay attention to the Javadoc specification on unchecked exceptions. Don't declare them on the interface, just in the Javadocs. Coding Standards - Logging • Use the Apache Commons Logging API so that all logging output is uniform. • Use the class hierarchy categories, but where deviations are made, add comments to the Javadocs. • INFO messages are only added at the request of Alfresco users. All other informative messages are DEBUG. • Put as much context and formatting into the message as time will allow. • Wrap all calls to logger.debug and logger.info, and only log messages if logger.isDebugEnabled and logger.isInfoEnabled respectively. Coding Standards - File Formats • UTF-8 encoding of all text files • Windows line endings (CR-LF) Alfresco Module Packages (AMP) An Alfresco Module Package (AMP) is a collection of code, XML, images, CSS, etc. that collectively extend the functionality or data provided by the standard Alfresco Repository. An AMP file can contain as little as a set of custom templates or a new category. It can contain a custom model and associated UI customisations. It could contain a complete new set of functionality, for example records management. As a general rule of thumb, anything that is considered to be an “installable” extension to the Alfresco repository should be called a module and packaged as an AMP file. AMP files can be installed into the Alfresco WAR using the Module Management Tool. An AMP file has a standard format that can be customised if required. 22 Alfresco Enterprise Edition Version 3.2
  • 23. Getting Started Once the contents of the AMP file has been mapped into an Alfresco WAR using the Module Management Tool, the WAR can be deployed to the application server. When the repository is next started, the installed module configuration will be detected, and the repository will be bootstrapped to include the new module functionality and data. AMP Project Structure An Alfresco Module project can be structured in any way that suits the developer environment. As long as the resulting AMP file is packaged correctly and the required property and context files are present, the module will install successfully. The recommended project structure is as follows: |-- source | |-- java |-- <module package structure starts here> | |-- web |-- css |-- images |-- jsp |-- scripts | |-- config |-- <resource package structure starts here> | |-- build |-- dist |-- lib | |-- build.xml source/java/ Contains the Java source for the Alfresco Module. source/web/ Contains any web UI resources (JSPs, images, CSS, JavaScript). config/ Contains configuration files and resources used by the module. build/ Build directory for compiled class files. build/dist/ Build directory for AMP files. build/lib/ Build directory for JAR files. The recommended package structure for Java source (source/java), configuration files and resources (config) is org.alfresco.module.<moduleid>, where moduleid is the unique module id of the module. Alfresco Module Packages are presented in more detail later on in the course. For more details, see Introduction on page 143. API Development Course 23
  • 24. Getting Started Alfresco Repository Architecture Out of the Box Out-of-the-box, Alfresco's simple installation procedure provides a pre-configured deployment aimed at reaching a complete and working Content Management application as quickly and easily as possible. The deployment is as follows: This is typical of a web architecture, where an application server houses the logic for both the user interface and domain. Storage of data and content is provided by persistent back-ends such as a database or file system. Any number of web browsers can connect to the application without prior client installation costs. In this particular case, the application server houses both the Alfresco Application and the Alfresco Repository. An Alfresco Application provides a complete solution tailored for a specific area of Content Management such as Document Management (DM), Web Content Management (WCM) and Records Management (RM). The Alfresco Repository provides a set of reusable cross-cutting Content Management services such as content storage, query, versioning and transformation which may be utilised by one or more applications. Although this is the default installed deployment, it is only one of many ways of utilising the capabilities and components of Alfresco. When we first set out to design Alfresco, we wanted to break away from the mould of typical Content Management architectures which are monolithic and closed. The result is that Alfresco can neatly fit into existing environments and each of its 24 Alfresco Enterprise Edition Version 3.2
  • 25. Getting Started components may be used in isolation or together to form the basis of many differing Content Management solutions. The remainder of this module explores the anatomy of the Alfresco Repository which will give a good understanding of the concepts and capabilities and how it achieves openness, scalability and flexibility. Service & Component Architecture Every part of the Alfresco Repository is either a component or a service. A component is an implementation black box that provides a specific feature or capability. A service is an interface entry point for a client to bind to and use. This fundamental approach allows for existing components to be switched with new implementations, new components to be added with ease and for clients to connect and use services without knowledge of how they're implemented. If there's a feature of Alfresco you don't need, you can take it out, providing a lighter and possibly faster Alfresco. If there's a feature you wish to re-implement, you can replace it, either by providing a better implementation, or integrating with your existing environment. Implementation of this approach is simplified by using the open source project Spring Framework which Alfresco has taken to heart and has made a core foundation of its architecture. With Spring, Alfresco components are declaratively configured and bound together. Aspect-oriented programming allows the weaving of infrastructure concerns such as Transactions and Security into components without polluting their implementation. Environment touch points are abstracted such as resource (e.g. database) connections. The Alfresco Repository structure looks like this: API Development Course 25
  • 26. Getting Started The public interface point is the Alfresco Repository Foundation Services. Each service is exposed as a Java Interface to which a Repository client can bind and invoke without knowledge of its underlying implementation. A Service Registry lists the available services. Behind services are the implementation black boxes i.e. components. Each service and component is configured via the Spring framework in XML “context” files. The Spring context file public-service-context.xml provides the configuration and binding of the Alfresco Repository Foundation Services. The Repository Foundation Services are the lowest level of public interface providing access to all Repository capabilities. Binding to this interface is possible via the Repository Service Registry, or via Spring dependency injection if the client is also Spring aware. Access to Foundation Services is limited to Repository clients who reside in the same process as the Repository. That is, the Foundation Services are an excellent API for clients who wish to embed the Repository. An important point to note is that the Foundation Services are where transaction and security policies are enforced. The policies themselves are declaratively specified and enforced via the injection of a transaction and security implementation into each service. Every service of Alfresco is transactional and secure. Other forms of API are provided too, however, all public entry points eventually go through this layer. Alfresco supports a common scheme for making extensions to the Repository i.e. configuring a component, adding a new component or service, or removing capabilities. Extensions are 26 Alfresco Enterprise Edition Version 3.2
  • 27. Getting Started encapsulated outside of the core Repository and plugged-in automatically. This means the core Repository can be upgraded to a newer version and extensions remain intact. Repository Foundation Services API The heart of the Alfresco Repository is responsible for the storage and retrieval of content. This is split into nodes, content and index information. Nodes provide meta-data and structure to content. A node may support properties (e.g. author) and relate to other nodes (e.g. represent folder hierarchies or annotations). Content is the actual information being recorded e.g. a Word document or XML fragment. Meta-data and content may be structured according to the rules defined in a Content Model. For example, the Alfresco Document Management application relies on a model that describes Folders and Files. Indexing information allows the retrieval of meta- data and content via many different lookup options. Repository storage and retrieval is provided by the following Foundation Services: • Node Service for managing meta-data i.e. nodes • Content Service for managing content • Search Service for performing queries By default, Alfresco has chosen to store meta-data in a database and content in a file system. Using a database immediately brings in the benefits of databases that have been developed over many years such as transaction support, scaling & administration capabilities. Content is stored in the file system to allow for very large content, random access, streaming and options for different storage devices. The Alfresco out-of-the-box implementations of the above services are built upon strong open source projects that already have many man-years of development effort and strong communities: Hibernate and Lucene. API Development Course 27
  • 28. Getting Started Apart from the strong Object/Relational mapping that Hibernate provides, it also brings pluggable caching support and SQL dialects. The first allows for tuning of the Alfresco meta-data store to provide optimum read and write performance in both single and clustered environments. The second allows for nearly any SQL database back-end by configuring just two properties; the Alfresco community has already confirmed working support for MySQL, Oracle, DB2, Sybase, SQL Server. By externalising the indexing of meta-data and content and using the Lucene engine as a basis, it is possible to perform complex queries which combine property, location, classification and full-text predicates in a single query against any content type. Multiple query languages are supported including Lucene's native language as well as XPath and a SQL-like language in the future. To ensure reliable operation, transactional support has been added to both Lucene and the content file store providing ACID operations across the complete store. Security is woven into each of the service layer ensuring illegal modifications are not permissible and hidden meta-data and content are not returned. Nearly all other Foundation services and clients rely upon these three core building blocks. Repository APIs The Alfresco Repository actually provides three APIs. We've already seen one - the Repository Foundation Services - a set of local Java Interfaces covering all capabilities which are ideal for clients who wish to embed the Repository. The two other APIs are: • JCR • Web Services JCR (Content Repository API for Java Technologies) is a standard Java API (as defined by JSR-170) for accessing Content Repositories. Alfresco provides support for level 1 and level 2 giving standardised read and write access. Supporting this API provides the following benefits: • No risk: The Alfresco Repository can be trialled and developed against, but swapped out with another JCR Repository if it does not fit requirements. • Familiarity: Developers who know JCR, know Alfresco. • Tools: Tools, Clients and other 3rd Party JCR solutions are immediately available to the Alfresco community. Alfresco JCR is implemented as a light facade on top of the Repository Foundation Services. So, although a familiar API is provided, it sits upon a fully transactional, secure and scalable Repository which supports many deployment options. Alfresco will continue investment in JCR by both broadening the compliance of the full specification as well driving forward JSR-283, the next version of the JCR. Web Services is the final API provided by the Alfresco Repository. This API supports remote access and bindings to any client environment, not just Java. For example, the Alfresco community is already using PHP, Ruby and Microsoft .NET. Numerous standards and integration efforts are focused around Web Services - SOA is now recognised as a way forward for integrating disparate systems including Content Management and building new enterprise-wide solutions. BPEL plays an important role in orchestrating all of these services. Alfresco fits neatly into this way of thinking. 28 Alfresco Enterprise Edition Version 3.2
  • 29. Getting Started Once again, the Repository Foundation Services serve as the base. Both the JCR and Web Services API eventually go through this layer meaning that all encapsulated content model logic and rules are honoured. Repository Server Protocols A Repository is useless if the content it manages cannot be accessed. To provide the widest possible range of access points, the Alfresco Repository supports a variety of communication protocols. These are: • CIFS (Common Internet File System) • WebDAV • FTP • NFS All of these protocols essentially expose Folders of Files and as such the Alfresco implementations map neatly onto Folder and File nodes held in the Repository as described by the Alfresco Document Management content model. WebDAV, FTP and NFS are well known protocols, but CIFS deserves some more attention. CIFS transforms the Alfresco Repository into a standard file system. Any tool that understands how to read and write to a file system, also knows how to directly read and write to the Alfresco Repository. On the surface, it would seem that a drive mapping to WebDAV provides an equivalent capability, but this isn't the case. CIFS projects an actual file system giving extra compatibility with the hosting operating system. For example, in Windows, it's possible to use Offline Synchronisation and Briefcase features against the Alfresco Repository providing native and well-known tools for offline Repository working. Many commercial CMS offerings do not provide this feature. In fact, Alfresco may have the only server-side Java implementation of the API Development Course 29
  • 30. Getting Started CIFS protocol having brought on board the engineers who spent 7 years developing such a capability. Like every other feature of the Repository, the protocol components are Spring configured and as with all other components may or may not be included in a deployment. Typically, they are enabled when the Repository is deployed as a server to provide access points for remote clients. The various Repository deployment options are explored later in this document. Protocol components are implemented against the Repository Foundation Services. This is important to note, as each protocol will honour the behaviour and content logic encapsulated behind the Foundation Services. In fact, it cannot be bypassed. Terminology Store Reference (StoreRef) A StoreRef is made up of a store protocol and a store id. 30 Alfresco Enterprise Edition Version 3.2
  • 31. Getting Started public static final String PROTOCOL_WORKSPACE = "workspace"; public static final String PROTOCOL_AVM = "avm"; public static final String URI_FILLER = "://"; The standard store used by the Web Client has the following StoreRef: workspace://SpacesStore Node Reference (NodeRef) A NodeRef is made up a store reference and a node id. private static final String URI_FILLER = "/"; The node id is a 16 byte (128 bit) A “Universally Unique Identifier” or UUID. Example NodeRef: workspace://SpacesStore/808b2b34-a99f-11db-b572-8337f65f7e0d Qualified Name (QName) A QName represents the qualified name of a Repository item. Each QName consists of a local name qualified by a namespace. API Development Course 31
  • 32. Getting Started Namespace scoped Name Format {URI}localname or prefix:localName Examples {http://www.alfresco.org/model/content/1.0}auditable or cm:auditable Node Browser The Node Browser is your friend! 32 Alfresco Enterprise Edition Version 3.2
  • 33. Developing against the Alfresco Repository Developing against the Alfresco Repository API Development Course 33
  • 34. Developing against the Alfresco Repository Spring Framework Introduction The Spring Framework is a full-stack Java/JEE application framework. Spring's main aim is to make J2EE easier to use and promote good programming practise. It does this by enabling a POJO-based programming model remaining faithful to the fundamental ideas of Expert One-on- One J2EE Design and Development. Spring is portable between application servers. Bean Factory A Spring BeanFactory is a generic factory that enables objects to be retrieved by name, and which can manage relationships between objects. Bean factories support two modes of object: • Singleton: in this case, there's one shared instance of the object with a particular name. • Prototype or non-singleton: in this case, each retrieval will result in the creation of an independent object. Beans are defined in an XML bean definition file that is loaded when a new Bean Factory is created. Bean Factory Example 1. Writing a simple JavaBean class Here's the simplest Java Bean you can get! package ex01_simplebean; public class Bean1 { } 2. Defining the Spring beans Two Spring beans are defined for the same class. bean1 is a singleton bean and multibean1 is a prototype bean (singleton="false"): <beans> <bean id="bean1" class="ex01_simplebean.Bean1" /> <bean id="multibean1" class="ex01_simplebean.Bean1" singleton="false" /> </beans> 3. Testing with a Main program a. Creating a new Spring Bean Factory The bean definition file is loaded into the Spring Bean Factory: ClassPathResource res = new ClassPathResource( "ex01_simplebean/ApplicationContext.xml"); XmlBeanFactory factory = new XmlBeanFactory(res); The following messages are written to the console: 15:13:26,515 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from class path resource [ex01_simplebean/ ApplicationContext.xml] 15:13:26,593 INFO [XmlBeanFactory] Creating shared instance of singleton bean 'bean1' b. Getting bean1 from the Bean Factory 34 Alfresco Enterprise Edition Version 3.2
  • 35. Developing against the Alfresco Repository We retrieve bean1 from the Bean Factory using the getBean() method: Bean1 bean1a = (Bean1) factory.getBean("bean1"); System.out.println("Retrieved Bean1: " + bean1a.toString()); Bean1 bean1b = (Bean1) factory.getBean("bean1"); System.out.println("Retrieved Bean1: " + bean1b.toString()); Each call retrieves the same bean (there is only one instance): Retrieved Bean1: ex01_simplebean.Bean1@471e30 Retrieved Bean1: ex01_simplebean.Bean1@471e30 c. Getting multibean1 from the Bean Factory Now we retrieve multibean1 from the Bean Factory. Bean1 bean1a = (Bean1) factory.getBean("multibean1"); System.out.println("Retrieved MultiBean1: " + bean1a.toString()); Bean1 bean1b = (Bean1) factory.getBean("multibean1"); System.out.println("Retrieved MultiBean1: " + bean1b.toString()); This time each call retrieves a new instance of the bean: Retrieved MultiBean1: ex01_simplebean.Bean1@10ef90c Retrieved MultiBean1: ex01_simplebean.Bean1@a32b Inversion of Control (IoC) Through its bean factory concept, Spring is an Inversion of Control container. Spring is most closely identified with a flavour of Inversion of Control known as Dependency Injection. The concept behind Inversion of Control is often expressed in the Hollywood Principle: “Don't call me, I'll call you.” IoC moves the responsibility for making things happen into the framework, and away from application code. Whereas your code calls a traditional class library, an IoC framework calls your code. Dependency Injection Dependency Injection is a form of IoC that removes explicit dependencies on container APIs. Ordinary Java methods are used to inject dependencies such as collaborating objects or configuration values into application object instances. The two major flavors of Dependency Injection are: • Setter Injection (injection via JavaBean setters) • Constructor Injection (injection via constructor arguments). Spring provides sophisticated support for both, and even allows you to mix the two when configuring the one object. Setter Injection Example 1. Writing a simple JavaBean class This simple JavaBean supports properties. The values of the properties are set by the Spring Bean Factory when the bean is instantiated. package ex02_setter; public class Bean1 { public void setString(String val) { m_strVal = val; } public String getString() { return m_strVal; } public void setInt(int val) { m_intVal = val; } public int getInt() { return m_intVal; } API Development Course 35
  • 36. Developing against the Alfresco Repository public void setList(List strings) { m_strings = strings; } public List getList() { return m_strings; } private String m_strVal; private int m_intVal; private List m_strings; } 2. Defining the Spring beans A single bean is defined with initial values for the properties that will be initialised via the “setter” methods on the JavaBean: <beans> <bean id="bean1" class="ex02_setter.Bean1"> <property name="string"> <value>a string</value> </property> <property name="int"> <value>125</value> </property> <property name="list"> <list> <value>item1</value> <value>item2</value> <value>item3</value> </list> </property> </bean> </beans> 3. Testing with a Main program We retrieve bean1 from the Bean Factory and print out the values of the properties: Bean1 bean1a = (Bean1) factory.getBean("bean1"); System.out.println("Retrieved Bean1: " + bean1a.toString()); String strVal = bean1a.getString(); System.out.println("String property: " + strVal); int intVal = bean1a.getInt(); System.out.println("Int property: " + intVal); List strings = bean1a.getList(); System.out.println("List property: " + strings); The properties have automatically been initialised by the Bean Factory: Retrieved Bean1: ex02_setter.Bean1@21b6d String property: a string Int property: 125 List property: [item1, item2, item3] Constructor Injection Example 1. Writing a simple JavaBean class This time the JavaBean has a constructor and some properties. The String property is passed to the constructor and the int property has a “setter” method. package ex03_constructor; public class Bean1 { public Bean1(String val) { m_strVal = val; } public String getString() { return m_strVal; } 36 Alfresco Enterprise Edition Version 3.2
  • 37. Developing against the Alfresco Repository public void setInt(int val) { m_intVal = val; } public int getInt() { return m_intVal; } private String m_strVal; private int m_intVal; } 2. Defining the Spring beans This time a bean is defined with a constructor argument. The String property will be initialised via the constructor and the int property via the “setter” method on the JavaBean: <beans> <bean id="bean1" class="ex03_constructor.Bean1"> <constructor-arg index="0"> <value>a string</value> </constructor-arg> <property name="int"> <value>125</value> </property> </bean> </beans> 3. Testing with a Main program We retrieve bean1 from the Bean Factory and print out the values of the properties: Bean1 bean1a = (Bean1) factory.getBean("bean1"); System.out.println("Retrieved Bean1: " + bean1a.toString()); String strVal = bean1a.getString(); System.out.println("String property: " + strVal); int intVal = bean1a.getInt(); System.out.println("Int property: " + intVal); The properties have automatically been initialised by the Bean Factory: Retrieved Bean1: ex03_constructor.Bean1@12152e6 String property: a string Int property: 125 Dependency Injection Example 1. Writing the JavaBean classes a. Two more simple JavaBean classes These two JavaBeans will be used as dependencies: package ex04_dependency; public class Bean2 { } package ex04_dependency; public class Bean3 { } b. Establish a constructor dependency The Bean1 class depends on the Bean2 class via the constructor: package ex04_dependency; API Development Course 37
  • 38. Developing against the Alfresco Repository public abstract class Bean1 { public Bean1(Bean2 bean2) { m_bean2 = bean2; } ... public Bean2 getBean2() { return m_bean2; } ... private Bean2 m_bean2; } c. Establish a setter dependency The Bean1 class depends on the Bean3 class via a property setter: public void setBean3(Bean3 bean3) { m_bean3 = bean3; } public Bean3 getBean3() { return m_bean3; } private Bean3 m_bean3; 2. Defining the Spring beans bean1 depends on bean2 and bean3. The Bean Factory will instantiate the bean2 and bean3 objects before “injecting” them into bean1 via the constructor property setter respectively: <beans> <bean id="bean1" class="ex04_dependency.Bean1"> <constructor-arg index="0"> <ref bean="bean2"/> </constructor-arg> <property name="bean3"> <ref bean="bean3"/> </property> </bean> <bean id="bean2" class="ex04_dependency.Bean2"/> <bean id="bean3" class="ex04_dependency.Bean3"/> </beans> 3. Testing with a Main program We retrieve bean1 from the Bean Factory and print out the dependencies: Bean1 bean1 = (Bean1) factory.getBean("bean1"); System.out.println("Retrieved Bean1: " + bean1.toString()); Bean2 bean2 = bean1.getBean2(); Bean3 bean3 = bean1.getBean3(); System.out.println("Retrieved Bean2 Dependency: " + bean2.toString()); System.out.println("Retrieved Bean3 Dependency: " + bean3.toString()); The dependencies have automatically been injected by the Bean Factory: Retrieved Bean1: ex04_dependency.Bean1$$EnhancerByCGLIB$$d8a83b@1cb25f1 Retrieved Bean2 Dependency: ex04_dependency.Bean2@2808b3 Retrieved Bean3 Dependency: ex04_dependency.Bean3@535b58 38 Alfresco Enterprise Edition Version 3.2
  • 39. Developing against the Alfresco Repository Application Context To start using Spring you either instantiate a Spring BeanFactory or an ApplicationContext. ApplicationContext is derived from BeanFactory and provides all of the BeanFactory funtionality and more including: • MessageSource, providing access to messages in, i18n-style • Access to resources, such as URLs and files • Event propagation to beans implementing the ApplicationListener interface • Loading of multiple (hierarchical) contexts, allowing each to be focused on one particular layer, for example the web layer of an application Web Application Context A Spring WebApplicationContext is just an ordinary ApplicationContext that has some extra features necessary for web applications. It is bound in the ServletContext and is created by a ContextLoaderListener. Context Loader Listener The Spring ContextLoaderListener is declared in WEB-INF/web.xml: <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> Spring contextConfigLocation Use the contextConfigLocation <context-param> to set which context files to load: <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:alfresco/web-client-application-context.xml classpath:web-services-application-context.xml classpath:alfresco/application-context.xml </param-value> <description>Spring config file locations</description> </context-param> API Development Course 39
  • 40. Developing against the Alfresco Repository Foundation Services API Introduction The Foundation 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 run 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. Access to Repository Foundation Services The Foundation Services API is 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 Spring configuration file public-services-context.xml • the Service Registry interface org.alfresco.service.ServiceRegistry There are three ways to access Foundation Services: 1. use Spring IoC to directly inject services into your code (If your layer is also Spring enabled); 2. use the Alfresco Service Registry; 3. manually access services via the Spring getBean() method. FirstFoundationClient walkthrough Before getting started, you should be familiar with the Introduction on page 34. The sample uses several of the key foundation services, including the ServiceRegistry, TransactionService, AuthenticationService, SearchService, NodeService and ContentService. After initialising the Spring Application Context and starting the repository in embedded mode, we will use the Spring getBean() method to access the ServiceRegistry. We will then use the ServiceRegistry to access the other foundation services. After authenticating to the repository using the AuthenticationService, we will search for the “Company Home” node using the SearchService. We will then create a new node with properties and add an aspect using the NodeService. Finally, we will write some content to the new node using the ContentService. The sample will be wrapped in a single user transaction with the help of the TransactionService. 1. Getting the ServiceRegistry The Service Registry maintains a list of available foundation services and some meta-data about each. In particular, the Service Registry provides access to each service interface. The registry is a service itself and is therefore accessed using either Spring IoC or the Spring getBean() method. The static variable SERVICE_REGISTRY found on the interface org.alfresco.service.ServiceRegistry provides the Spring Bean name to lookup by. The FirstFoundationClient sample uses the getBean() method on the Spring Application Context to retrieve the ServiceRegistry: ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); 40 Alfresco Enterprise Edition Version 3.2
  • 41. Developing against the Alfresco Repository 2. Using the TransactionService to run the example in a user transaction By default, all repository foundation services are transactional and each invocation of a service method is wrapped in its own transaction. These transactions are defined declaratively in Spring configuration files and not in your Java code. In most cases, declarative transactions are preferred to user transactions since they are less invasive. There are situations, however, when user transactions do need to be used explicitly in your code. The FirstFoundationClient uses a RetryingTransactionHelper to run the example as a unit of work inside a user transaction. The work is defined as an instance of the RetryingTransactionCallback class. The doInTransaction() method is then called to run the unit of work in a transaction. The RetryingTransactionHelper is obtained via the getRetryingTransactionHelper() method on the TransactionService. For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface TransactionService The TransactionService and RetryingTransactionHelper are presented in more detail in the section on Transactions. The following example runs the example work in a user transaction via the RetryingTransactionHelper: TransactionService transactionService = serviceRegistry.getTransactionService(); RetryingTransactionCallback<Object> exampleWork = new RetryingTransactionCallback<Object>() { public Object execute() throws Exception { doExample(serviceRegistry); return null; } }; transactionService. getRetryingTransactionHelper().doInTransaction(exampleWork); 3. Using the AuthenticationService for authentication API Development Course 41
  • 42. Developing against the Alfresco Repository Before making any call to the repository through the public Foundation Services API, a user must first be authenticated. This is done via the AuthenticationService by using the authenticate() method and providing a username and password. Once authenticated, a ticket can be requested using either the getNewTicket() or the getCurrentTicket() method. The ticket can then be used to re-validate the user using the validate() method. The AuthenticationService defines the API for managing authentication information against a username. For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface AuthenticationService In the example, the authenticate() method is used to authenticate as the “admin” user. The password must be passed as a character array. AuthenticationService authenticationService = serviceRegistry.getAuthenticationService(); authenticationService.authenticate("admin", "admin".toCharArray()); 4. Using the SearchService to locate the “Company Home” node The SearchService provides many methods for searching the Alfresco repository using any of the available query languages: Lucene, XPath or JCR-XPath. The Lucene query language allows you to run powerful searches, including full text searches on the content and node properties. To run a Lucene search using the query() method, you must specify the StoreRef of the store you wish to search, the query language (using one of the static attributes defined on the SearchService interface - LANGUAGE_LUCENE for example) and the query as a String. The parameters can either be passed directly to the query() method, or be defined on a new SearchParameters object which is then passed to the query() method. The query results are returned as a ResultSet object. 42 Alfresco Enterprise Edition Version 3.2
  • 43. Developing against the Alfresco Repository For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface SearchService The following example runs a Lucene query using the PATH syntax to locate the “Company Home” by it's absolute path. The getNodeRef(0) call is used to retrieve the first NodeRef from the ResultSet. In theory, the query should only return one result. SearchService searchService = serviceRegistry.getSearchService(); StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore"); ResultSet resultSet = searchService.query( storeRef, SearchService.LANGUAGE_LUCENE, "PATH:"/app:company_home""); NodeRef companyHome = resultSet.getNodeRef(0); For more information on using the SearchService and on query string syntax, see the Search page on the Alfresco Wiki. 5. Using the NodeService to create a node The NodeService provides methods for operations on nodes and stores. Stores are created with createStore(). Nodes are created with createNode() and deleted with deleteNode(). Properties are set with either setProperty() or setProperties(). Properties are removed with removeProperty(). Aspects are applied with addAspect() and removed with removeAspect(). Associations are created and removed with createAssociation() and removeAssociation(). Associations can be navigated with getSourceAssocs() or getTargetAssocs(). Child associations can be navigated with getChildAssocs() and getParentAssoc(). Almost all NodeService methods take a NodeRef as an argument. A NodeRef is obtained either by navigation or from the results of a search. Otherwise a new NodeRef object can be created from the node's unique UUID. API Development Course 43
  • 44. Developing against the Alfresco Repository For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: Interface NodeService a. Setting properties Properties are set on nodes using either the setProperty() or setProperties() methods. setProperty() allows a single property to be set, whilst setProperties() takes a Map of properties and sets all of the node's properties at once. Each property is identified by it's QName and it's value must be Serializable. public void setProperty( NodeRef nodeRef, QName qname, Serializable value) public void setProperties( NodeRef nodeRef, Map<QName, Serializable> properties) nodeRef NodeRef of the node to set the property on. 44 Alfresco Enterprise Edition Version 3.2
  • 45. Developing against the Alfresco Repository qname QName of the property to set. value Value of the property. The value must be Serializable. properties Map of all the properties of the node keyed by QName. The property QNames are usually defined as a static constants on the dictionary model interfaces. For example, the cm:name property is defined by the static constant ContentModel.PROP_NAME. The following example creates a Map containing the cm:name property that will be used in the next step: String name = "Foundation API sample (" + System.currentTimeMillis() + ")"; Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>(); contentProps.put(ContentModel.PROP_NAME, name); b. Creating a node Nodes are created using the createNode() method. A node is created as a child of a parent node. The child association name and child association type have to be supplied as QName objects, as well as the QName of the type of node to create and optionally a Map of properties to set on the newly created node. public ChildAssociationRef createNode( NodeRef parentRef, QName assocTypeQName, QName assocQName, QName nodeTypeQName, Map<QName, Serializable> properties) parentRef NodeRef of the parent node. The created node will be one of it's children. assocTypeQName QName of the type of association to create. This is used for verification against the data dictionary. assocQName QName of the association. nodeTypeQName QName of the node type. properties Optional Map of properties to set keyed by QName. The association and node type QName objects are usually defined as a static constants on the dictionary model interfaces. For example, the cm:contains association type is defined by the static constant ContentModel.ASSOC_CONTAINS and the cm:content node type is defined by the static constant ContentModel.TYPE_CONTENT. If a constant does not exist, a QName can be created using the QName.createQName() static method as in the example below. The createNode() method returns a ChildAssociationRef to the newly created child association. The NodeRef of the newly created node is obtained by calling the getChildRef() on the ChildAssociationRef object. API Development Course 45
  • 46. Developing against the Alfresco Repository The following example creates a new node of type cm:content, using the standard cm:contains child association. The Map created in the previous step sets the cm:name property on the newly created node. NodeService nodeService = serviceRegistry.getNodeService(); ChildAssociationRef association = nodeService.createNode(companyHome, ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_PREFIX, name), ContentModel.TYPE_CONTENT, contentProps); NodeRef content = association.getChildRef(); c. Adding an aspect Aspects are applied to nodes using the addAspect() method. The node is identified by it's NodeRef and the aspect by it's QName. The property values are provided as a Map. public void addAspect( NodeRef nodeRef, QName aspectTypeQName, Map<QName, Serializable> aspectProperties) nodeRef NodeRef of the node to apply the aspect to. aspectTypeQName QName of the aspect to apply. aspectProperties Map containing a minimum of the mandatory properties required for the aspect. The aspect QNames are usually defined as a static constants on the dictionary model interfaces. For example, the cm:titled aspect is defined by the static constant ContentModel.ASPECT_TITLED. The following example applies the cm:titled aspect and sets the cm:title and cm:description properties: Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(); titledProps.put(ContentModel.PROP_TITLE, name); titledProps.put(ContentModel.PROP_DESCRIPTION, name); nodeService.addAspect(content, ContentModel.ASPECT_TITLED, titledProps); 6. Using the ContentService to write content The ContentService provides methods for reading, writing and transforming content. In order to read or write content from and to a node, you must first obtain a ContentReader or a ContentWriter via the getReader() and getWriter() methods respectively. Methods can then be used on the ContentReader or ContentWriter to read and write content. Both the ContentReader and the ContentWriter implement the methods defined by the ContentAccessor interface. These methods allow you to get and set information about the content, for example to set the mime type, the encoding or to get the size. The actual content is stored on the cm:content property (ContentModel.PROP_CONTENT) of each node. When requesting a ContentReader or a ContentWriter, the NodeRef needs to be supplied along with the ContentModel.PROP_CONTENT QName. The ContentService is also used for transforming content. A suitable transformer can be obtained for a given transformation (defined by a source and target mime type) using 46 Alfresco Enterprise Edition Version 3.2
  • 47. Developing against the Alfresco Repository the getTransformer() and getImageTransformer() methods. The transformation can then be performed by calling transform directly on the content transformer. Otherwise, a transformation can be attempted from a source ContentReader object to target ContentWriter object by calling the transform() method on the ContentService. For more information, see Introduction on page 91. For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: • Interface ContentService • Interface ContentReader • Interface ContentWriter • Interface ContentAccessor The following example gets a ContentWriter to the newly created node. The property to be updated is defined by the QName ContentModel.PROP_CONTENT. The boolean true value is to request that the content is updated atomically when the content write stream is closed. The content mime type and encoding are set before writing the content with the putContent() method. ContentService contentService = serviceRegistry.getContentService(); ContentWriter writer = contentService.getWriter(content, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); String text = "The quick brown fox jumps over the lazy dog"; writer.putContent(text); API Development Course 47
  • 48. Developing against the Alfresco Repository Once completed, the newly created node may be viewed via the Web client. The web client will need to be re-started after executing the sample to see the changes in effect. Other Foundation Services FileFolderService The FileFolderService provides methods specific to manipulating Alfresco defined content files and folders. The methods can be more convenient and easier to use than the equivalent NodeService and ContentService methods. Certain methods, such as create(), return a FileInfo object. A NodeRef can then be retrieved using the FileInfo.getNodeRef() method. 48 Alfresco Enterprise Edition Version 3.2
  • 49. Developing against the Alfresco Repository For clarity, not all of the available methods are shown. For a complete description, please consult the Javadocs: • Interface FileFolderService • Interface FileInfo API Development Course 49
  • 50. Developing against the Alfresco Repository JCR API Introduction The JCR API (Java Content Repository) specifies a standard, implementation independent API to access content repositories in Java. It is defined by the Java Specification Request (JSR) 170 as part of the Java Community Process (JCP). The official JSR-170 Specification can be found on the JCP web site at the following address: http://jcp.org/en/jsr/detail?id=170 Alfresco implements the JCR API against its own scalable repository and is actively contributing to the next version of JCR defined by the Java Specification Request (JSR) 283. JCR Compliance Levels The JSR 170 specification defines two compliance levels and a set of additional optional features which repositories of either level may support. Level 1 provides for read functions and includes: • Retrieval and traversal of nodes and properties • Reading the values of properties • Transient namespace remapping • Export to XML/SAX • Query facility with XPath syntax • Discovery of available node types • Discovery of access control permissions Level 2 adds additional write functions: • Adding and removing nodes and properties • Writing the values of properties • Persistent namespace changes • Import from XML/SAX • Assigning node types to nodes Optionally, any combination of the following features may be added to an implementation of either level: • Transactions • Versioning • Observation (Events) • Locking • SQL syntax for query JCR Repository Model Like the Alfresco repository, a JCR repository consists of one or more workspaces, each of which contains a tree of items. An item is either a node or a property. Each node may have zero or more child nodes and zero or more child properties. There is a single root node per workspace, which has no parent. Unlike the Alfresco repository, all other nodes have only one parent. Properties have one parent (a node) and cannot have children; they are the leaves of the tree. All of the actual content in the repository is stored within the values of the properties. 50 Alfresco Enterprise Edition Version 3.2
  • 51. Developing against the Alfresco Repository Any item in the tree hierarchy can be identified by either an absolute or a relative path using a Unix style path syntax. The path / refers to the root node of a workspace and the path / app:company_home refers to the “Company Home” space in the standard Alfresco SpacesStore workspace. The special paths “.” and “..” (meaning respectively, “this” and “parent”) are also supported. FirstJCRClient Walkthrough Before getting started, you should be familiar with the Introduction on page 34. The sample uses several of the basic JCR APIs, including Repository, Session and Node. After initialising the Spring Application Context and starting the repository in embedded mode, we will use the Spring getBean() method to access the JCR.Repository. After logging into the JCR repository, we will navigate to the “Company Home” node. We will then create a new node with properties, add an aspect and write some content. Finally, we will mix the JCR API calls with the Alfresco Foundation Services API calls to set the content mime type. The sample is wrapped by an implicit JCR transaction. 1. Getting the JCR.Repository The JCR repository as a whole is represented by a Repository object. JSR-170 does not dictate how to obtain the Repository object. In Alfresco, the JSR repository is a Spring bean called JCR.Repository. The JCR.Repository bean is defined in jcr-api-context.xml. It has one configuration parameter; the default workspace name. This is used when a JCR client performs a login without specifying the workspace. The default workspace is SpacesStore, the same one used by the Alfresco Web Client. <bean id="JCR.Repository" class="org.alfresco.jcr.repository.RepositoryImpl" init-method="init"> <property name="serviceRegistry"> <ref bean="ServiceRegistry"/> </property> <property name="importerComponent"> <ref bean="importerComponent"/> </property> <property name="defaultWorkspace"> <value>SpacesStore</value> </property> </bean> The following example uses the Spring getBean() method to access the JCR Repository: ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alfresco/application- context.xml"); Repository repository = (Repository)context.getBean("JCR.Repository"); 2. Logging into the repository (creating a Session) A client connects to the repository by calling the login() method on the Repository object. The client must supply a Credentials object and optionally a workspace name. Behind the scenes, Alfresco uses the authentication system of the Alfresco repository which by default is Alfresco's own, but it could also be NTLM, LDAP or your own depending on how the repository has been configured. If a workspace is not provided, the default as defined earlier will be used. The Session returned from login is tied to the workspace and allows read and write operations upon that workspace. By default, the Session is also backed by a transaction. Work performed API Development Course 51