and
      Florian Müller, Software Architect
Agenda


•  A quick CMIS tour
•  Introduction to Apache Chemistry
•  OpenCMIS demos
•  Outlook: CMIS, Apache Chemistry and Alfresco



•  Tech Talk: Alfresco CMIS
  Online webinar, Wednesday, 3 August 2011
Content Management Interoperability Services
    consumer


                   Client



                 read   write

                 Services
               Domain Model
    provider




               Vendor Mapping

                                CMIS lets you read, search, write, update,
                  Content
                                delete, version, control, …
                 Repository     content and metadata!
CMIS Use Cases


                                Content
           Client                             Client
                               Repository



         Content                Content      Content
                                               Content
        Repository             Repository   Repository
                                                 Content
                                              Repository
                                                Repository


  •    Collaborative Content Creation
  •    Portals
  •    Client Application Integration
  •    Mashup
CMIS Base Types

	
  	
  
           Document                      Folder
           •  Content                    •  Container
           •  Renditions                 •  Hierarchy
           •  Version History            •  Filing


                                 Described by
                                Type Definitions

           Relationship                  Policy
           •  Source Object              •  Target Object
           •  Target Object
Type Definitions

              Object                     Property
              •  Type Id                 •  Property Id
              •  Parent                  •  Display Name
              •  Display Name
                                   *     •  Type
              •  Queryable               •  Required
              •  Controllable            •  Default Value
                                         •  …



 Document           Folder             Relationship         Policy
 •  Versionable                        •  Source Types
 •  Allow Content                      •  Target Types


                             Custom Type
Base Properties

All objects                                      Documents
String!       cmis:name  !                       Boolean!     cmis:isImmutable  !
ID!           cmis:objectId!                     Boolean!     cmis:isLatestVersion!
ID!           cmis:baseTypeId  !                 Boolean!     cmis:isMajorVersion!
ID!           cmis:objectTypeId   !              Boolean!     cmis:isLatestMajorVersion!
String!       cmis:createdBy    !                String!      cmis:versionLabel!
DateTime!     cmis:creationDate!                 ID!          cmis:versionSeriesId !
String!       cmis:lastModifiedBy !              Boolean!     cmis:isVersionSeriesCheckedOut !
DateTime!     cmis:lastModificationDate!         String!      cmis:versionSeriesCheckedOutBy !
String!       cmis:changetoken!                  ID!          cmis:versionSeriesCheckedOutId !
                                                 String!      cmis:checkinComment!
Folders                                          Integer!     cmis:contentStreamLength!
ID!           cmis:parentId!                     String!      cmis:contentStreamMimeType !
String!       cmis:path  !                       String!      cmis:contentStreamFileName   !
ID (multi)!   cmis:allowedChildObjectTypeIds !   ID!          cmis:contentStreamId  !

Relationships                                    Policies
ID!           cmis:sourceId  !                   String!    cmis:policyText   !
ID!           cmis:targetId   !
Content Streams



      Document                 *   Rendition
      •  Mime Type                 •  Kind
      •  Length                    •  Mime Type




              Content Stream
              •  Stream Id

                * Maximum length is repository specific
Access Control



                               ACL
       Object
                               ACE
                               •  Principal
                               •  Permissions
                               •  Direct



       Permissions
       cmis:read
       cmis:write
       cmis:all
       <repository specific>
Document Versioning

                    Document
                                          Repository Vendor May Support
                      V1                  •  Version Specific Folder Filing
                     Minor                •  Query All Versions
                                          •  Create Minor, Major, PWCs
   Version Series




                      V2       checkout
                     Major

                                              PWC

                      V3
                               checkin
                     Major
Policies


 Repository specific Policies



  Retention       Security      …


                                                         Client
                                          ly
                                    app


                Document




                                    * Note: Optional Capability
Change Log


                 Change Events


  Repo            Create   Update   Delete                  Client
          logs                                discover



   Change Event:
   •  Object Id
   •  Change Time
   •  Change Type – created, updated, deleted, security
   •  Properties – for updated events


                                      * Note: Optional Capability
CMIS Query Language

•  SELECT and FROM clauses
   o    Identify which properties from which types to return



•  WHERE clause
   o    Restrict returned rows to those that meet all constraints
   o    Predicates: comparison, in, like, null, any, is null
   o    Function Predicates: contains(), in_folder(), in_tree()
   o    Operators: and, or, not



•  ORDER BY clause
   o    Order results by one or more columns



•  Each Type is projected as a Table
Do You Understand These Queries?

SELECT cmis:name
FROM   cmis:document
WHERE contains('alfresco')



             SELECT     cmis:name, cmis:lastModificationDate
             FROM       cmis:document
             WHERE      cmis:lastModifiedBy = 'admin'
             ORDER BY   cmis:lastModificationDate DESC



    SELECT   cmis:name, cmis:contentStreamLength
    FROM     cmis:document
    WHERE    IN_TREE('<folderObjectId>')
             AND cmis:contentStreamLength > 100000
    ORDER BY cmis:contentStreamLength
CMIS Services

Browse                      Inspect                       Act

Repository                  Object                        Object
-  Get Server Information   - Read Content                - Write Content
-  Get Type Definitions     - Get Properties              - Set Properties
                            - Get ACLs                    - Create Folder / Doc /
                            - Get Allowable Actions       Relation
                                                          - Delete
                                                          -  Move
                                                          -  Set ACLs
Navigation                  Versioning
- Walk Folder / Doc         -  Walk Version History
Hierarchy
- Get Checked-out
                                                          Versioning
                                                          - Check-out / In
                            Relationship                  - Cancel Check-out
                            -  Traverse Relationship(s)   - Delete Version(s)

Discovery
- Issue Query
- Get Change Log            Policy                        Policy
                            -  Get Applied Policies       - Apply / Remove
CMIS Cheat Sheet




http://cmis.alfresco.com/cmis-cheatsheet.pdf
CMIS Bindings


•  CMIS 1.0 defines two bindings:
  o    AtomPub binding
  o    Web Services binding


•  CMIS 1.1 will add a new binding:
  o    Browser binding (JSON)



•  Don’t bother …
  There are Open Source libraries for that
Apache Chemistry
                          TM




  Open Source implementations of


•  Apache Chemistry is the umbrella project for all CMIS
  related projects within the Apache Software Foundation.

•  Apache Chemistry provides libraries and frameworks for
  Java, Python, PHP and .NET.

•  Website: http://chemistry.apache.org
Main Objective


 Developers should focus on the CMIS domain model!

•  Decreased learning curve: Developers can learn just
  the CMIS domain model and ignore the transport details
  of all the binding implementations.

•  Rapid start. From download to listing the first folder in
  minutes.

•  Be compliant. Chemistry libraries have been tested
  against many, many repositories.
Apache Chemistry


                                Application

              Libraries                 Apache Chemistry
       (ORM, connection pools, etc.)



         ODBC / JDBC                      CMIS Bindings

                                          CMIS Domain
                  SQL
                                            Model

          Relational DB                 Content Repository
Subprojects

•  OpenCMIS (Java, server and client)
   o    very mature
   o    well tested against all major servers


•  cmislib (Python, client)
   o    mature
   o    well tested against most major servers


•  phpclient (PHP, client)
   o    basic specification coverage
   o    used in a few production systems


•  DotCMIS (.NET, client)
   o    an OpenCMIS port (same architecture, similar API)
   o    works against all tested servers but needs more testing
History

May 2009:        Started as an incubator project by
                 Nuxeo and Day (now Adobe)

February 2010:   Metaversant contributed cmislib

February 2010:   Alfresco, OpenText and SAP contributed
                 OpenCMIS

May 2010:        Alfresco contributed phpclient

January 2011:    Alfresco contributed DotCMIS

February 2011:   Graduated to a top level project
OpenCMIS

OpenCMIS consists of a collection of Java libraries,
  frameworks and tools:


•  Client library
•  Server framework
•  Two test repositories (InMemory and FileShare)
•  CMIS Browser (web application, AtomPub only)
•  CMIS Workbench (desktop application for developers)
•  FIT and TCK
Get hold of OpenCMIS

OpenCMIS is available

•  as source code:
  https://svn.apache.org/repos/asf/chemistry/opencmis/trunk/


•  as release package with all dependencies:
  http://chemistry.apache.org/java/download.html


•  via Maven:
  http://chemistry.apache.org/java/developing/dev-use-with-maven.html


•  Last released version is 0.4.0
OpenCMIS Architecture
OpenCMIS Client Library


•  Client API
  o    OO API
                                        You want this API!
  o    Easy to use
  o    Build-in caching


•  Client Binding API
  o    Low-level
  o    Very close to the CMIS specification
  o    More control, less comfort
OpenCMIS Client Interfaces
                                                                                            «loads»




                                                                                                        ObjectId




                                                                                                                                                                              0..n
                               RepositoryInfo                      Rendition         AllowableActions                                       ACL                         PropertyData


                                                                 0..n      0..n
                                                                                                                                             0..n                                           «loads»
                                                                                                                                            ACE

                       Repository                         QueryResult                                  CmisObject                                                         Property
                                                                                                                                      target                 0..n
                                                                                                                                   source


                 «loads»                             «loads»                                      FileableCmisObject
                                 «creates»




SessionFactory         «creates»                Session                           Folder               Document                  Policy               Relationship     0..n
                                                                                                                                                                       0..n

                                                                                                                                          0..n
                                     «loads»

                                                                                                          ContentStream

                       ChangeEvents




                              0..n                                             FolderType             DocumentType           PolicyType             RelationshipType

                           ChangeEvent




                                                                                                                    ObjectType                                         PropertyDefinition
                                                                                                                                                               9..n

                                                                                                                   1        0..n
OpenCMIS Main Client Interfaces

 AllowableActions              ObjectId                             ACL


                                                                    0..n
                                                                    ACE


    Rendition                 CmisObject                         Property
                    0..n                                 0..n


                           FileableCmisObject




                Folder         Document         Policy          Relationship




                             ContentStream
Aspects, Aspects, Aspects

•  CMIS 1.0 has no native support for aspects

•  Secondary types (= aspects) will be in CMIS 1.1

•  Alfresco provides read and write access to aspects and
  aspect properties through CMIS extensions

•  Theoretically, every CMIS client can read and write
  aspects but that is rather troublesome
Alfresco OpenCMIS Extension

•  The Alfresco OpenCMIS Extension transparently adds
  aspect support to OpenCMIS

•  Hosted on Apache Extras (Google Code),
  Apache license:
  http://apache-extras.org/p/alfresco-opencmis-extension

•  See the project page for setup instructions.
  It’s really simple.
OpenCMIS Sessions

•  CMIS is stateless!

•  OpenCMIS introduces a session concept to support caching
   o    It’s all about performance
   o    Reduce the number of calls to the repository

•  OpenCMIS caches:
   o    Repository infos
   o    Type definitions
   o    AtomPub links
   o    CMIS objects
Connect to a repository – Variant 1

// set up session parameters
Map<String, String> parameter = new HashMap<String, String>();

parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
parameter.put(SessionParameter.ATOMPUB_URL,
                                  "http://cmis.alfresco.com/service/cmis");
parameter.put(SessionParameter.REPOSITORY_ID,
                                  "84ccfe80-b325-4d79-ab4d-080a4bdd045b");

parameter.put(SessionParameter.USER, "admin");
parameter.put(SessionParameter.PASSWORD, "admin");



// create the session
SessionFactory factory = SessionFactoryImpl.newInstance();
Session session = factory.createSession(parameter);
Connect to a repository – Variant 2

// set up session parameters
Map<String, String> parameter = new HashMap<String, String>();

parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
parameter.put(SessionParameter.ATOMPUB_URL,
                                  "http://cmis.alfresco.com/service/cmis");
parameter.put(SessionParameter.REPOSITORY_ID,
                                  "84ccfe80-b325-4d79-ab4d-080a4bdd045b");

parameter.put(SessionParameter.USER, "admin");
parameter.put(SessionParameter.PASSWORD, "admin");



// get the list of repositories and choose the first one
SessionFactory factory = SessionFactoryImpl.newInstance();

List<Repository> repositories = factory.getRepositories(parameter);
Session session = repositories.get(0).createSession();
Using the Session

RepositoryInfo ri = session.getRepositoryInfo();
String id = ri.getId();
String name = ri.getName();



CmisObject object1 = session.getObject("1234567890");!
CmisObject object2 = session.getObjectByPath("/my/path/doc");!



Folder rootFolder = session.getRootFolder();!
String rootFolderId = rootFolder.getId();!
!
for(CmisObject object: rootFolder.getChildren()) {!
    String name = object.getName();!

     if(object instanceof Document) {!
         Document doc = (Document) object;!
         long size = doc.getContentStreamLength();    !
     }!
}!
CMIS Workbench



 Live samples with the CMIS Workbench
 …
Navigation

import   org.apache.chemistry.opencmis.commons.*;
import   org.apache.chemistry.opencmis.commons.data.*;
import   org.apache.chemistry.opencmis.commons.enums.*;
import   org.apache.chemistry.opencmis.client.api.*;

// get root folder
Folder root = session.getRootFolder();
String rootFolderName = root.getName();

println "Root folder: ${rootFolderName}n"

// print root folder children
for(CmisObject object: root.getChildren()) {

    String name = object.getName();
    String typeId = object.getType().getId();
    String path = object.getPaths().get(0);

    println "${name} t${typeId} t(${path})"


    // get parents
    /*
    for(CmisObject parent: object.getParents()) {
        String parentName = parent.getName();
        println " Parent: ${parentName}"
    }
    */
}
Paging

import org.apache.chemistry.opencmis.commons.*;!
import org.apache.chemistry.opencmis.commons.data.*;!
import org.apache.chemistry.opencmis.commons.enums.*;!
import org.apache.chemistry.opencmis.client.api.*;!
!
Folder root = session.getRootFolder();!
!
printList( root.getChildren() )!
!
//printList( root.getChildren().getPage(3) )!
!
//printList( root.getChildren().skipTo(2) )!
!
//printList( root.getChildren().skipTo(2).getPage(3) )!
!
!
!
void printList(ItemIterable<CmisObject> list) {!
    list.each { println "${it.name} t${it.type.id}" }!
    !
    long numItems = list.getTotalNumItems();!
    boolean hasMore = list.getHasMoreItems();!
    !
    println "--------------------------------------"!
    println "Total number: ${numItems}"!
    println "Has more: ${hasMore}" !
    println "--------------------------------------"!
}!
Properties

import   org.apache.chemistry.opencmis.commons.*;
import   org.apache.chemistry.opencmis.commons.data.*;
import   org.apache.chemistry.opencmis.commons.enums.*;
import   org.apache.chemistry.opencmis.client.api.*;

CmisObject object = session.getObjectByPath("/User Homes/florian/Test Folder/MyText");



for(Property<?> property: object.getProperties()) {

    String propId           =   property.getId();
    String displayName      =   property.getDefinition().getDisplayName();
    String queryName        =   property.getDefinition().getQueryName();
    PropertyType datatype   =   property.getType();
    Object value            =   property.getFirstValue();

    println   "${displayName}: ${value}"
    println   " Data type: ${datatype}"
    println   " Id:          ${propId}"
    println   " Query name: ${queryName}"
    println   ""
}
Content

import org.apache.chemistry.opencmis.commons.*;!
import org.apache.chemistry.opencmis.commons.data.*;!
import org.apache.chemistry.opencmis.commons.enums.*;!
import org.apache.chemistry.opencmis.client.api.*;!
!
CmisObject object = session.getObjectByPath("/User Homes/florian/Test Folder/MyText");!
!
if(!(object instanceof Document)) {!
    throw new Exception("Not a document!");!
}!
!
Document doc = (Document) object;!
!
ContentStream content = doc.getContentStream();!
!
if(content == null) {!
    throw new Exception("Document has no content!");!
}!
!
String filename = content.getFileName();!
String mimeType = content.getMimeType();!
long length = content.getLength();!
InputStream stream = content.getStream();!
!
println "File:       ${filename}"!
println "MIME Type: ${mimeType}"!
println "Size:       ${length} bytes"!
println "Has stream: " + (stream != null)!
!
Query

import   org.apache.chemistry.opencmis.commons.*
import   org.apache.chemistry.opencmis.commons.data.*
import   org.apache.chemistry.opencmis.commons.enums.*
import   org.apache.chemistry.opencmis.client.api.*

String cql = "SELECT cmis:objectId, cmis:name, cmis:contentStreamLength FROM cmis:document";

ItemIterable<QueryResult> results = session.query(cql, false);

//ItemIterable<QueryResult> results = session.query(cql, false).getPage(10);
//ItemIterable<QueryResult> results = session.query(cql, false).skipTo(10).getPage(10);

for(QueryResult hit: results) {
    for(PropertyData<?> property: hit.getProperties()) {

          String queryName = property.getQueryName();
          Object value = property.getFirstValue();

          println "${queryName}: ${value}"
    }

    println "--------------------------------------"
}
Folders

import org.apache.chemistry.opencmis.commons.*;!
import org.apache.chemistry.opencmis.commons.data.*;!
import org.apache.chemistry.opencmis.commons.enums.*;!
import org.apache.chemistry.opencmis.client.api.*;!
!
Folder root = session.getRootFolder();!
!
// create a new folder!
Map<String, Object> properties = new HashMap<String, Object>();!
properties.put("cmis:objectTypeId", "cmis:folder");!
properties.put("cmis:name", "a new folder");!
!
Folder newFolder = root.createFolder(properties);!
!
printProperties(newFolder);!
!
!
// update properties!
Map<String, Object> updateproperties = new HashMap<String, Object>();!
updateproperties.put("cmis:name", "renamed folder");!
!
newFolder.updateProperties(updateproperties);!
!
newFolder.refresh();!
printProperties(newFolder);!
!
!
// delete folder!
newFolder.deleteTree(true, UnfileObject.DELETE, true);!
!
Documents

import   org.apache.chemistry.opencmis.commons.*;
import   org.apache.chemistry.opencmis.commons.data.*;
import   org.apache.chemistry.opencmis.commons.enums.*;
import   org.apache.chemistry.opencmis.commons.impl.dataobjects.*;
import   org.apache.chemistry.opencmis.client.api.*;

Folder root = session.getRootFolder();

// create a new document
String name = "myNewDocument.txt";

Map<String, Object> properties = new HashMap<String, Object>();
properties.put("cmis:objectTypeId", "cmis:document");
properties.put("cmis:name", name);

byte[] content = "Hello World!".getBytes();
InputStream stream = new ByteArrayInputStream(content);
ContentStream contentStream = new ContentStreamImpl(name, content.length, "text/plain", stream);

Document newDoc = root.createDocument(properties, contentStream, VersioningState.MAJOR);


printProperties(newDoc);



// delete document
newDoc.delete(true);



void printProperties(CmisObject object) {
    object.properties.each { println "${it.id}: ${it.firstValue}" }
    println "--------------------------------------"
}
CMIS Outlook

•  The CMIS TC is working on CMIS 1.1

•  CMIS 1.1 adds new features
   o    Type mutability
   o    Browser Binding
   o    Secondary Types
   o    …


•  Release date: 2012???

•  Will it be backwards compatible?
   o    We don’t know yet.
   o    Apache Chemistry will hide binding changes.
Apache Chemistry Outlook



•  Tests and documentation…
  o    Make sure it works with as many CMIS servers and
       clients as possible
  o    Make the usage of Apache Chemistry as simple as possible




•  Apache Chemistry sandboxes
  o    Implementations of CMIS 1.1 features
  o    Feedback for the CMIS TC
Alfresco CMIS Outlook

•  Alfresco 4.x
   o    Switch to the OpenCMIS server framework
   o    Many improvements: speed, memory consumption, compliance
   o    OpenCMIS client libraries are embedded and available in Web Scripts
   o    Have a look: http://cmis.alfresco.com




•  Tech Talk: Alfresco CMIS
  Online webinar, Wednesday, 3 August 2011
   o  Alfresco CMIS mapping
   o  CMIS changes in Alfresco 4.x
   o  CMIS 1.1 browser binding (JSON)
   o  Performance optimization
   o  Whatever you want to talk about…
Questions

Apache Chemistry: The Alfresco Open Source Implementation of CMIS

  • 1.
    and Florian Müller, Software Architect
  • 2.
    Agenda •  A quickCMIS tour •  Introduction to Apache Chemistry •  OpenCMIS demos •  Outlook: CMIS, Apache Chemistry and Alfresco •  Tech Talk: Alfresco CMIS Online webinar, Wednesday, 3 August 2011
  • 3.
    Content Management InteroperabilityServices consumer Client read write Services Domain Model provider Vendor Mapping CMIS lets you read, search, write, update, Content delete, version, control, … Repository content and metadata!
  • 4.
    CMIS Use Cases Content Client Client Repository Content Content Content Content Repository Repository Repository Content Repository Repository •  Collaborative Content Creation •  Portals •  Client Application Integration •  Mashup
  • 5.
    CMIS Base Types     Document Folder •  Content •  Container •  Renditions •  Hierarchy •  Version History •  Filing Described by Type Definitions Relationship Policy •  Source Object •  Target Object •  Target Object
  • 6.
    Type Definitions Object Property •  Type Id •  Property Id •  Parent •  Display Name •  Display Name * •  Type •  Queryable •  Required •  Controllable •  Default Value •  … Document Folder Relationship Policy •  Versionable •  Source Types •  Allow Content •  Target Types Custom Type
  • 7.
    Base Properties All objects Documents String! cmis:name  ! Boolean! cmis:isImmutable  ! ID! cmis:objectId! Boolean! cmis:isLatestVersion! ID! cmis:baseTypeId  ! Boolean! cmis:isMajorVersion! ID! cmis:objectTypeId   ! Boolean! cmis:isLatestMajorVersion! String! cmis:createdBy    ! String! cmis:versionLabel! DateTime! cmis:creationDate! ID! cmis:versionSeriesId ! String! cmis:lastModifiedBy ! Boolean! cmis:isVersionSeriesCheckedOut ! DateTime! cmis:lastModificationDate! String! cmis:versionSeriesCheckedOutBy ! String! cmis:changetoken! ID! cmis:versionSeriesCheckedOutId ! String! cmis:checkinComment! Folders Integer! cmis:contentStreamLength! ID! cmis:parentId! String! cmis:contentStreamMimeType ! String! cmis:path  ! String! cmis:contentStreamFileName   ! ID (multi)! cmis:allowedChildObjectTypeIds ! ID! cmis:contentStreamId  ! Relationships Policies ID! cmis:sourceId  ! String! cmis:policyText   ! ID! cmis:targetId   !
  • 8.
    Content Streams Document * Rendition •  Mime Type •  Kind •  Length •  Mime Type Content Stream •  Stream Id * Maximum length is repository specific
  • 9.
    Access Control ACL Object ACE •  Principal •  Permissions •  Direct Permissions cmis:read cmis:write cmis:all <repository specific>
  • 10.
    Document Versioning Document Repository Vendor May Support V1 •  Version Specific Folder Filing Minor •  Query All Versions •  Create Minor, Major, PWCs Version Series V2 checkout Major PWC V3 checkin Major
  • 11.
    Policies Repository specificPolicies Retention Security … Client ly app Document * Note: Optional Capability
  • 12.
    Change Log Change Events Repo Create Update Delete Client logs discover Change Event: •  Object Id •  Change Time •  Change Type – created, updated, deleted, security •  Properties – for updated events * Note: Optional Capability
  • 13.
    CMIS Query Language • SELECT and FROM clauses o  Identify which properties from which types to return •  WHERE clause o  Restrict returned rows to those that meet all constraints o  Predicates: comparison, in, like, null, any, is null o  Function Predicates: contains(), in_folder(), in_tree() o  Operators: and, or, not •  ORDER BY clause o  Order results by one or more columns •  Each Type is projected as a Table
  • 14.
    Do You UnderstandThese Queries? SELECT cmis:name FROM cmis:document WHERE contains('alfresco') SELECT cmis:name, cmis:lastModificationDate FROM cmis:document WHERE cmis:lastModifiedBy = 'admin' ORDER BY cmis:lastModificationDate DESC SELECT cmis:name, cmis:contentStreamLength FROM cmis:document WHERE IN_TREE('<folderObjectId>') AND cmis:contentStreamLength > 100000 ORDER BY cmis:contentStreamLength
  • 15.
    CMIS Services Browse Inspect Act Repository Object Object -  Get Server Information - Read Content - Write Content -  Get Type Definitions - Get Properties - Set Properties - Get ACLs - Create Folder / Doc / - Get Allowable Actions Relation - Delete -  Move -  Set ACLs Navigation Versioning - Walk Folder / Doc -  Walk Version History Hierarchy - Get Checked-out Versioning - Check-out / In Relationship - Cancel Check-out -  Traverse Relationship(s) - Delete Version(s) Discovery - Issue Query - Get Change Log Policy Policy -  Get Applied Policies - Apply / Remove
  • 16.
  • 17.
    CMIS Bindings •  CMIS1.0 defines two bindings: o  AtomPub binding o  Web Services binding •  CMIS 1.1 will add a new binding: o  Browser binding (JSON) •  Don’t bother … There are Open Source libraries for that
  • 18.
    Apache Chemistry TM Open Source implementations of •  Apache Chemistry is the umbrella project for all CMIS related projects within the Apache Software Foundation. •  Apache Chemistry provides libraries and frameworks for Java, Python, PHP and .NET. •  Website: http://chemistry.apache.org
  • 19.
    Main Objective Developersshould focus on the CMIS domain model! •  Decreased learning curve: Developers can learn just the CMIS domain model and ignore the transport details of all the binding implementations. •  Rapid start. From download to listing the first folder in minutes. •  Be compliant. Chemistry libraries have been tested against many, many repositories.
  • 20.
    Apache Chemistry Application Libraries Apache Chemistry (ORM, connection pools, etc.) ODBC / JDBC CMIS Bindings CMIS Domain SQL Model Relational DB Content Repository
  • 21.
    Subprojects •  OpenCMIS (Java,server and client) o  very mature o  well tested against all major servers •  cmislib (Python, client) o  mature o  well tested against most major servers •  phpclient (PHP, client) o  basic specification coverage o  used in a few production systems •  DotCMIS (.NET, client) o  an OpenCMIS port (same architecture, similar API) o  works against all tested servers but needs more testing
  • 22.
    History May 2009: Started as an incubator project by Nuxeo and Day (now Adobe) February 2010: Metaversant contributed cmislib February 2010: Alfresco, OpenText and SAP contributed OpenCMIS May 2010: Alfresco contributed phpclient January 2011: Alfresco contributed DotCMIS February 2011: Graduated to a top level project
  • 23.
    OpenCMIS OpenCMIS consists ofa collection of Java libraries, frameworks and tools: •  Client library •  Server framework •  Two test repositories (InMemory and FileShare) •  CMIS Browser (web application, AtomPub only) •  CMIS Workbench (desktop application for developers) •  FIT and TCK
  • 24.
    Get hold ofOpenCMIS OpenCMIS is available •  as source code: https://svn.apache.org/repos/asf/chemistry/opencmis/trunk/ •  as release package with all dependencies: http://chemistry.apache.org/java/download.html •  via Maven: http://chemistry.apache.org/java/developing/dev-use-with-maven.html •  Last released version is 0.4.0
  • 25.
  • 26.
    OpenCMIS Client Library • Client API o  OO API You want this API! o  Easy to use o  Build-in caching •  Client Binding API o  Low-level o  Very close to the CMIS specification o  More control, less comfort
  • 27.
    OpenCMIS Client Interfaces «loads» ObjectId 0..n RepositoryInfo Rendition AllowableActions ACL PropertyData 0..n 0..n 0..n «loads» ACE Repository QueryResult CmisObject Property target 0..n source «loads» «loads» FileableCmisObject «creates» SessionFactory «creates» Session Folder Document Policy Relationship 0..n 0..n 0..n «loads» ContentStream ChangeEvents 0..n FolderType DocumentType PolicyType RelationshipType ChangeEvent ObjectType PropertyDefinition 9..n 1 0..n
  • 28.
    OpenCMIS Main ClientInterfaces AllowableActions ObjectId ACL 0..n ACE Rendition CmisObject Property 0..n 0..n FileableCmisObject Folder Document Policy Relationship ContentStream
  • 29.
    Aspects, Aspects, Aspects • CMIS 1.0 has no native support for aspects •  Secondary types (= aspects) will be in CMIS 1.1 •  Alfresco provides read and write access to aspects and aspect properties through CMIS extensions •  Theoretically, every CMIS client can read and write aspects but that is rather troublesome
  • 30.
    Alfresco OpenCMIS Extension • The Alfresco OpenCMIS Extension transparently adds aspect support to OpenCMIS •  Hosted on Apache Extras (Google Code), Apache license: http://apache-extras.org/p/alfresco-opencmis-extension •  See the project page for setup instructions. It’s really simple.
  • 31.
    OpenCMIS Sessions •  CMISis stateless! •  OpenCMIS introduces a session concept to support caching o  It’s all about performance o  Reduce the number of calls to the repository •  OpenCMIS caches: o  Repository infos o  Type definitions o  AtomPub links o  CMIS objects
  • 32.
    Connect to arepository – Variant 1 // set up session parameters Map<String, String> parameter = new HashMap<String, String>(); parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value()); parameter.put(SessionParameter.ATOMPUB_URL, "http://cmis.alfresco.com/service/cmis"); parameter.put(SessionParameter.REPOSITORY_ID, "84ccfe80-b325-4d79-ab4d-080a4bdd045b"); parameter.put(SessionParameter.USER, "admin"); parameter.put(SessionParameter.PASSWORD, "admin"); // create the session SessionFactory factory = SessionFactoryImpl.newInstance(); Session session = factory.createSession(parameter);
  • 33.
    Connect to arepository – Variant 2 // set up session parameters Map<String, String> parameter = new HashMap<String, String>(); parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value()); parameter.put(SessionParameter.ATOMPUB_URL, "http://cmis.alfresco.com/service/cmis"); parameter.put(SessionParameter.REPOSITORY_ID, "84ccfe80-b325-4d79-ab4d-080a4bdd045b"); parameter.put(SessionParameter.USER, "admin"); parameter.put(SessionParameter.PASSWORD, "admin"); // get the list of repositories and choose the first one SessionFactory factory = SessionFactoryImpl.newInstance(); List<Repository> repositories = factory.getRepositories(parameter); Session session = repositories.get(0).createSession();
  • 34.
    Using the Session RepositoryInfori = session.getRepositoryInfo(); String id = ri.getId(); String name = ri.getName(); CmisObject object1 = session.getObject("1234567890");! CmisObject object2 = session.getObjectByPath("/my/path/doc");! Folder rootFolder = session.getRootFolder();! String rootFolderId = rootFolder.getId();! ! for(CmisObject object: rootFolder.getChildren()) {! String name = object.getName();! if(object instanceof Document) {! Document doc = (Document) object;! long size = doc.getContentStreamLength(); ! }! }!
  • 35.
    CMIS Workbench Livesamples with the CMIS Workbench …
  • 36.
    Navigation import org.apache.chemistry.opencmis.commons.*; import org.apache.chemistry.opencmis.commons.data.*; import org.apache.chemistry.opencmis.commons.enums.*; import org.apache.chemistry.opencmis.client.api.*; // get root folder Folder root = session.getRootFolder(); String rootFolderName = root.getName(); println "Root folder: ${rootFolderName}n" // print root folder children for(CmisObject object: root.getChildren()) { String name = object.getName(); String typeId = object.getType().getId(); String path = object.getPaths().get(0); println "${name} t${typeId} t(${path})" // get parents /* for(CmisObject parent: object.getParents()) { String parentName = parent.getName(); println " Parent: ${parentName}" } */ }
  • 37.
    Paging import org.apache.chemistry.opencmis.commons.*;! import org.apache.chemistry.opencmis.commons.data.*;! importorg.apache.chemistry.opencmis.commons.enums.*;! import org.apache.chemistry.opencmis.client.api.*;! ! Folder root = session.getRootFolder();! ! printList( root.getChildren() )! ! //printList( root.getChildren().getPage(3) )! ! //printList( root.getChildren().skipTo(2) )! ! //printList( root.getChildren().skipTo(2).getPage(3) )! ! ! ! void printList(ItemIterable<CmisObject> list) {! list.each { println "${it.name} t${it.type.id}" }! ! long numItems = list.getTotalNumItems();! boolean hasMore = list.getHasMoreItems();! ! println "--------------------------------------"! println "Total number: ${numItems}"! println "Has more: ${hasMore}" ! println "--------------------------------------"! }!
  • 38.
    Properties import org.apache.chemistry.opencmis.commons.*; import org.apache.chemistry.opencmis.commons.data.*; import org.apache.chemistry.opencmis.commons.enums.*; import org.apache.chemistry.opencmis.client.api.*; CmisObject object = session.getObjectByPath("/User Homes/florian/Test Folder/MyText"); for(Property<?> property: object.getProperties()) { String propId = property.getId(); String displayName = property.getDefinition().getDisplayName(); String queryName = property.getDefinition().getQueryName(); PropertyType datatype = property.getType(); Object value = property.getFirstValue(); println "${displayName}: ${value}" println " Data type: ${datatype}" println " Id: ${propId}" println " Query name: ${queryName}" println "" }
  • 39.
    Content import org.apache.chemistry.opencmis.commons.*;! import org.apache.chemistry.opencmis.commons.data.*;! importorg.apache.chemistry.opencmis.commons.enums.*;! import org.apache.chemistry.opencmis.client.api.*;! ! CmisObject object = session.getObjectByPath("/User Homes/florian/Test Folder/MyText");! ! if(!(object instanceof Document)) {! throw new Exception("Not a document!");! }! ! Document doc = (Document) object;! ! ContentStream content = doc.getContentStream();! ! if(content == null) {! throw new Exception("Document has no content!");! }! ! String filename = content.getFileName();! String mimeType = content.getMimeType();! long length = content.getLength();! InputStream stream = content.getStream();! ! println "File: ${filename}"! println "MIME Type: ${mimeType}"! println "Size: ${length} bytes"! println "Has stream: " + (stream != null)! !
  • 40.
    Query import org.apache.chemistry.opencmis.commons.* import org.apache.chemistry.opencmis.commons.data.* import org.apache.chemistry.opencmis.commons.enums.* import org.apache.chemistry.opencmis.client.api.* String cql = "SELECT cmis:objectId, cmis:name, cmis:contentStreamLength FROM cmis:document"; ItemIterable<QueryResult> results = session.query(cql, false); //ItemIterable<QueryResult> results = session.query(cql, false).getPage(10); //ItemIterable<QueryResult> results = session.query(cql, false).skipTo(10).getPage(10); for(QueryResult hit: results) { for(PropertyData<?> property: hit.getProperties()) { String queryName = property.getQueryName(); Object value = property.getFirstValue(); println "${queryName}: ${value}" } println "--------------------------------------" }
  • 41.
    Folders import org.apache.chemistry.opencmis.commons.*;! import org.apache.chemistry.opencmis.commons.data.*;! importorg.apache.chemistry.opencmis.commons.enums.*;! import org.apache.chemistry.opencmis.client.api.*;! ! Folder root = session.getRootFolder();! ! // create a new folder! Map<String, Object> properties = new HashMap<String, Object>();! properties.put("cmis:objectTypeId", "cmis:folder");! properties.put("cmis:name", "a new folder");! ! Folder newFolder = root.createFolder(properties);! ! printProperties(newFolder);! ! ! // update properties! Map<String, Object> updateproperties = new HashMap<String, Object>();! updateproperties.put("cmis:name", "renamed folder");! ! newFolder.updateProperties(updateproperties);! ! newFolder.refresh();! printProperties(newFolder);! ! ! // delete folder! newFolder.deleteTree(true, UnfileObject.DELETE, true);! !
  • 42.
    Documents import org.apache.chemistry.opencmis.commons.*; import org.apache.chemistry.opencmis.commons.data.*; import org.apache.chemistry.opencmis.commons.enums.*; import org.apache.chemistry.opencmis.commons.impl.dataobjects.*; import org.apache.chemistry.opencmis.client.api.*; Folder root = session.getRootFolder(); // create a new document String name = "myNewDocument.txt"; Map<String, Object> properties = new HashMap<String, Object>(); properties.put("cmis:objectTypeId", "cmis:document"); properties.put("cmis:name", name); byte[] content = "Hello World!".getBytes(); InputStream stream = new ByteArrayInputStream(content); ContentStream contentStream = new ContentStreamImpl(name, content.length, "text/plain", stream); Document newDoc = root.createDocument(properties, contentStream, VersioningState.MAJOR); printProperties(newDoc); // delete document newDoc.delete(true); void printProperties(CmisObject object) { object.properties.each { println "${it.id}: ${it.firstValue}" } println "--------------------------------------" }
  • 43.
    CMIS Outlook •  TheCMIS TC is working on CMIS 1.1 •  CMIS 1.1 adds new features o  Type mutability o  Browser Binding o  Secondary Types o  … •  Release date: 2012??? •  Will it be backwards compatible? o  We don’t know yet. o  Apache Chemistry will hide binding changes.
  • 44.
    Apache Chemistry Outlook • Tests and documentation… o  Make sure it works with as many CMIS servers and clients as possible o  Make the usage of Apache Chemistry as simple as possible •  Apache Chemistry sandboxes o  Implementations of CMIS 1.1 features o  Feedback for the CMIS TC
  • 45.
    Alfresco CMIS Outlook • Alfresco 4.x o  Switch to the OpenCMIS server framework o  Many improvements: speed, memory consumption, compliance o  OpenCMIS client libraries are embedded and available in Web Scripts o  Have a look: http://cmis.alfresco.com •  Tech Talk: Alfresco CMIS Online webinar, Wednesday, 3 August 2011 o  Alfresco CMIS mapping o  CMIS changes in Alfresco 4.x o  CMIS 1.1 browser binding (JSON) o  Performance optimization o  Whatever you want to talk about…
  • 46.