Return-Path: X-Original-To: apmail-chemistry-commits-archive@www.apache.org Delivered-To: apmail-chemistry-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ABA098392 for ; Tue, 16 Aug 2011 14:35:53 +0000 (UTC) Received: (qmail 5745 invoked by uid 500); 16 Aug 2011 14:35:53 -0000 Delivered-To: apmail-chemistry-commits-archive@chemistry.apache.org Received: (qmail 5692 invoked by uid 500); 16 Aug 2011 14:35:52 -0000 Mailing-List: contact commits-help@chemistry.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@chemistry.apache.org Delivered-To: mailing list commits@chemistry.apache.org Received: (qmail 5673 invoked by uid 99); 16 Aug 2011 14:35:52 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Aug 2011 14:35:52 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Aug 2011 14:35:47 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id D6BF723889B1; Tue, 16 Aug 2011 14:35:26 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1158293 - /chemistry/site/trunk/content/java/developing/guide.mdtext Date: Tue, 16 Aug 2011 14:35:26 -0000 To: commits@chemistry.apache.org From: sfermigier@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110816143526.D6BF723889B1@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sfermigier Date: Tue Aug 16 14:35:26 2011 New Revision: 1158293 URL: http://svn.apache.org/viewvc?rev=1158293&view=rev Log: CMS commit to chemistry by sfermigier Modified: chemistry/site/trunk/content/java/developing/guide.mdtext Modified: chemistry/site/trunk/content/java/developing/guide.mdtext URL: http://svn.apache.org/viewvc/chemistry/site/trunk/content/java/developing/guide.mdtext?rev=1158293&r1=1158292&r2=1158293&view=diff ============================================================================== --- chemistry/site/trunk/content/java/developing/guide.mdtext (original) +++ chemistry/site/trunk/content/java/developing/guide.mdtext Tue Aug 16 14:35:26 2011 @@ -16,13 +16,16 @@ Notice: Licensed to the Apache Softwa specific language governing permissions and limitations under the License. -#OpenCMIS Client API Developer's Guide -##Audience +# OpenCMIS Client API Developer's Guide + +## Audience This guide is for software engineers who want to use the Apache Chemistry OpenCMIS client to access CMIS-compliant content repositories from java code. The examples included in the guide assume the code is running in a standalone Java application, but the OpenCMIS client can be used by on any Java platform, such as Web applications and phone apps. -###How to use this guide + +### How to use this guide + The guide is divided into 5 parts :- 1. *The Basics* - A brief introduction to CMIS and a practical "hello world" sample. Read this section to find out how to build, install and run a sample OpenCMIS application using Apache Chemistry. @@ -31,17 +34,21 @@ The guide is divided into 5 parts :- 1. *OpenCMIS bindings* - the 2 CMIS 1.0 bindings, and when and how to use them. 1. *Troubleshooting* - common pitfalls you may encounter when using OpenCMIS. -###Assumptions +### Assumptions + The guide assumes you are using the Eclipse IDE for code development, and have Maven and SVN installed. * You can download and install Eclipse [here](http://www.eclipse.org/downloads/). * You can download and install Maven [here](http://maven.apache.org/download.html). * You can download and install SVN for your platform [here](http://subversion.apache.org/packages.html). -##The basics +## The basics + This section gives a high-level overview of the OpenCMIS library, and introduces a supplied "Hello World" sample to get an OpenCMIS client up and running against a repository and accessing CMIS objects. -###What is OpenCMIS? + +### What is OpenCMIS? + CMIS (Content Management Interoperability Services) is a vendor-neutral [OASIS Web services interface specification](http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=cmis) that enables interoperability between Enterprise Content Management (ECM) systems. CMIS allows rich information to be shared across Internet protocols in vendor-neutral formats, @@ -54,7 +61,9 @@ The OpenCMIS Client API is a Java client OpenCMIS Client API [here](http://chemistry.apache.org/java/0.4.0/maven/apidocs/org/apache/chemistry/opencmis/client/api/package-summary.html). CMIS defines a domain model that describes a vendor-neutral ECM repository and its contents, a set of services to work with the repository and its content, and a set of bindings which a client uses to access the services. -####The CMIS Domain Model + +#### The CMIS Domain Model + CMIS defines a domain model. A client will access a CMIS service endpoint described by a URL. A service endpoint must have at least one repository. A repository is a data store and contains content. Each item of content is an object such as a folder, or a document. A repository is identified by its ID, and has a set of capabilities which describe what optional CMIS functionality the repository supports. @@ -81,15 +90,19 @@ A policy object can not be deleted if it There can be other object types in the repository, defined in a repository as subtypes of these base types. CMIS services are provided for the discovery of object-types that are defined in a repository, but for the moment folders and documents are the main objects you will be concerned with for the first 2 parts of this document. -####CMIS Services + +#### CMIS Services + The CMIS specification describes a set of services that act on repositories. The OpenCMIS client API uses these services, but by using a client binding, presents the user of the API a simple set of classes rather than the services described by CMIS. If you want to access a CMIS repository at the service level, you can do that by using the [OpenCMIS client bindings layer](http://chemistry.apache.org/java/developing/client/dev-client-bindings.html) directly. + The CMIS services are:- * *Repository services* - let you discover available repositories, get the capabilities of these repositories, and provide basic Data Dictionary information of what types are available in the repository. * *Navigation services* - let you navigate the repository by accessing the folder tree and traversing the folder/child hierarchy. You can use these services to get both children and parents of an object. -* *Object services* - provide the basic CRUD (Create, Read, Update, Delete) and Control services on any object, including document, folder, policy, and relationship objects. For document objects, this includes setting and getting of properties, policies, and content streams. Object services retrieve objects by path or object ID. Applications may also discover what actions users are allowed to perform. +* *Object services* - provide the basic CRUD (Create, Read, Update, Delete) and Control services on any object, including document, folder, policy, and relationship objects. For document objects, this + includes setting and getting of properties, policies, and content streams. Object services retrieve objects by path or object ID. Applications may also discover what actions users are allowed to perform. * *Multi-filing services* - let you establish the hierarchy by adding or removing an object to or from a folder. * *Discovery services* - provide Query and Change services, and a means of paging the results of the query. * *Change services* - let you discover what content has changed since the last time checked, as specified by a special token. You can use Change services for external search indexing and replication services. @@ -98,17 +111,21 @@ The CMIS services are:- * *Policy services* - apply policies on document objects. Policies are free-form objects and can be used by implementations for security, record, or control policies. * *ACL services* - let you create, manage, and access Access Control Lists to control who can perform certain operations on an object. -####CMIS Bindings +#### CMIS Bindings + How does an OpenCMIS client communicate over the wire with a CMIS service endpoint? A CMIS repository can communicate over two protocols, SOAP and [AtomPub](http://tools.ietf.org/html/rfc5023), and provide two corresponding bindings, a web services binding, and an AtomPub binding. A CMIS service endpoint will provide a URL for both types of binding, and in OpenCMIS you specify the binding type when calling the `getRepositories()` method on the [`SessionFactory`](http://chemistry.apache.org/java/0.4.0/maven/apidocs/org/apache/chemistry/opencmis/client/api/SessionFactory.html) object. -####The OpenCMIS Workbench + +#### The OpenCMIS Workbench + The workbench is a GUI repository browser that lets you quickly view the contents of a repository, create documents and folders, look at metadata, and perform queries. It's really useful for debugging your applications, and for quickly testing out queries before you commit them to code. You can download the latest version [here](http://chemistry.apache.org/java/developing/tools/dev-tools-workbench.html). The workbench is a Java Swing application, and comes with both Windows and UNIX starter scripts. -###Hello World + +### Hello World You can download, install, and test the Apache Chemistry client code using the `Hello World` sample. On a command line, type the following command :- :::text @@ -159,9 +176,12 @@ You can run the `main` method in the `He Once you have successfully run the `Hello World` sample, you can start to get familiar with the core parts of the OpenCMIS API in the next section. -##Getting Started with OpenCMIS + +## Getting Started with OpenCMIS + This section introduces the most commonly used parts of the OpenCMIS client API. The code snippets are taken from the GettingStarted sample class supplied with Apache chemistry. -###Installing the getting started sample + +### Installing the getting started sample On a command line, type the following command :- :::text @@ -208,7 +228,8 @@ Note that:- "http://repo.opencmis.org/inmemory/atom/"); parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value()); -####Connecting to a repository by id +#### Connecting to a repository by id + In a production environment, the client code will probably know the ID of the repository that it wants to connect to. The following code snippet shows how to connect to a repository using its ID. @@ -218,7 +239,8 @@ The following code snippet shows how to That's it. Any work you want to do against the repository uses this session. -####Connecting to one of a list of repositories +#### Connecting to one of a list of repositories + The CMIS specification allows a CMIS service endpoint to advertise one or more repositories, so this code snippet retrieves a list of repositories. In this case there the code chooses the first repository in list:- @@ -242,7 +264,8 @@ Now you can create your session with the That's it. Any work you want to do against the repository uses this session. -###Working with Folders and Documents +### Working with Folders and Documents + Of the four base objects described by the CMIS domain model, the most commonly used are the folder and the document. A folder is a container for other objects. Folders exist in a hierarchical structure as you would expect, but @@ -251,7 +274,9 @@ CMIS uses the terminology multifiling an capabilities. The Document is the only object that can have content, described by a content stream, and has properties such as the author and modification date. -####Finding the contents of the root folder + +#### Finding the contents of the root folder + Now you have a session you can start examining the repository. All CMIS repositories have a root folder, which is the single top level folder in the hierarchy. To list the objects in the root folder of your repository you use the `getRootFolder()` method on the session. @@ -263,7 +288,8 @@ To list the objects in the root folder o System.out.println(o.getName() + " which is of type " + o.getType().getDisplayName()); } -####Creating a folder object +#### Creating a folder object + To create a folder, you use the `createFolder()` method on the parent folder. As with most CMIS methods, it takes a map of properties which define the Object to be created. In this code snippet a folder with the name `ADGNewFolder` is created in the root folder:- @@ -285,7 +311,8 @@ In this code snippet a folder with the n Note that the properties set for in the above code snippet are the minimum set of name and object type id. There are many other properties you can set on creation, depending on the object type. -####Creating a a simple document object +#### Creating a a simple document object + Document objects describe entities in the CMIS repository. A document object with content contains a content stream that is the actual file contents, and a mimetype for the content stream. So, to create a document Object, first you need a content stream @@ -322,7 +349,8 @@ Note the following points :- * Each version of a document object has its own object ID. * You can create a document without an associated content stream, by passing null as the contentStream Parameter. -####Reading the contents of a document object +#### Reading the contents of a document object + You can retrieve a CMIS object by path, or by using the object ID. The following code snippet retrieves the newly created object using the object ID:- @@ -381,7 +409,9 @@ Note the following points :- class does not have a `getPath()` method, since multifiling means a document can have more than one parent folder. It does implement the `getPaths()` method from the [`FileableCmisObject`](http://chemistry.apache.org/java/0.4.0/maven/apidocs/org/apache/chemistry/opencmis/client/api/FileableCmisObject.html) interface. This returns a list of the current paths to the document object. -####Updating a document. + +#### Updating a document. + You can update the properties of a document object, and you update the contents of the document by overwriting the document's content stream with a new content stream. Note that the object ID returned when updating a document is not guaranteed to remain the same, some repository implementations return the same object ID, and some may not. @@ -432,7 +462,8 @@ You must set the overwrite flag if the d Note that this code snippet will not work for repositories that require a checkout to set a content stream. For more information on checkout see the versioning section in this guide. -####Deleting a document +#### Deleting a document + You can delete any CMIS object using the `delete` method. The following code snippet lists the contents of the test folder before and after a delete of one of the two documents in the folder. @@ -453,7 +484,8 @@ in the folder. Note that the `allVersions` flag is set to `true`. If you set it to false then the delete will be of this version only. -####Deleting a folder tree +#### Deleting a folder tree + You can delete a folder and all its contents using just one method. The following code snippet creates a new folder tree and then deletes it, ignoring any failures to delete individual objects, and deleting all versions of any documents in the tree. @@ -480,7 +512,8 @@ which, depending on the repository desig an exception is raised. Some repository implementations will attempt the delete transactionally, so if it fails, no objects are deleted. In other repositories a failed delete may have deleted some, but not all, objects in the tree. -####Navigating through a folder tree +#### Navigating through a folder tree + CMIS provides several concepts for navigating through the tree of objects in the repository. For any folder, you can get its children, get its descendants, and get the folder tree. The getting started sample application sets up a tree in the repository that looks like this:- @@ -584,7 +617,8 @@ Note that `getDescendants` and `getFolde objects. -###Object Types +### Object Types + CMIS Objects have an object type. There are four base types, two of which *must* be supported by a repository * `cmis:document` @@ -653,8 +687,10 @@ The following lines are typical output f You will see that, not surprisingly, doc has a type of `Document`, which is a base type, so has no parent. Depending on the repository you are running this code against, there may be a number of children of the `Document` type, which are types derived from this base type. -###CMIS Properties -####Displaying the properties of an Object +### CMIS Properties + +#### Displaying the properties of an Object + All objects of the CMIS base types implement the interface [`CmisObjectProperties`](http://chemistry.apache.org/java/0.4.0/maven/apidocs/org/apache/chemistry/opencmis/client/api/CmisObjectProperties.html) which provides accessors to CMIS object properties. The following code snippet uses the `getProperties()` method to print out all the available properties on a newly created Document object, doc. @@ -717,7 +753,8 @@ such as `GregorianCalendar`. The followi + sdf.format(calendar.getTime()) ); -####Getting a property value by Id +#### Getting a property value by Id + You can get the value of any property using the `getPropertyValue()` method. This is particularly useful for retrieving properties that are not part of the CMIS specification. The following code snippet takes a property, finds the Id from the property definition, and gets the @@ -731,7 +768,8 @@ property's value using the `queryName`:- + " (by getPropertValue()) is " + doc.getPropertyValue(someProperty.getId())); -####Getting a property value by query name +#### Getting a property value by query name + Given a query result, you can always use the `queryName` to get a property value. The following code snippet performs a query and gets a property's value using the `queryName`:- @@ -743,13 +781,16 @@ The following code snippet performs a qu + item.getPropertyByQueryName("cmis:createdBy").getFirstValue()); } -###Working with CMIS Queries +### Working with CMIS Queries + CMIS provides a type-based query service for discovering objects that match specified criteria. To allow this, CMIS provides a relational view of the CMIS data model. Through this relational view, queries may be performed using a simplified SQL SELECT statement. The query language is based on a subset of the SQL-92 grammar, with some extensions to enhance filtering capability for the CMIS data model. You can see an explanation of relational view and the full query language grammar in the [CMIS Specification](http://docs.oasis-open.org/cmis/CMIS/v1.0/os/cmis-spec-v1.0.html#_Toc243905420). -#####A Simple Query + +##### A Simple Query + Let's look at a query that will find all document objects that have a name that starts with the string `test`:- :::sql @@ -795,8 +836,10 @@ Let's look at the code required for this So, you make query on the session object, and the results set is returned. You can iterate through each row of the results set to see the search results. Note that each row of the results set includes values for every column in the table in this particular query. This code snippet just displays a subset of them. -##OpenCMIS programming patterns -###Exceptions + +## OpenCMIS programming patterns +### Exceptions + If something goes wrong in an OpenCMIS method, an exception will be thrown. All OpenCMIS exceptions extend [`CmisBaseException`](http://chemistry.apache.org/java/0.4.0/maven/apidocs/org/apache/chemistry/opencmis/commons/exceptions/package-tree.html) @@ -845,7 +888,9 @@ The output from this snippet looks like :::text server error page : - Apache Chemistry OpenCMIS - objectNotFound error

HTTP Status 404 - objectNotFound

unknown type id: cmis:badtype


+    Apache Chemistry OpenCMIS - objectNotFound error
+    

HTTP Status 404 - objectNotFound

+ unknown type id: cmis:badtype


     org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException: unknown type id: cmis:badtype
         at org.apache.chemistry.opencmis.inmemory.server.InMemoryRepositoryServiceImpl.getTypeDefinition(InMemoryRepositoryServiceImpl.java:110)
         at org.apache.chemistry.opencmis.inmemory.server.InMemoryService.getTypeDefinition(InMemoryService.java:110)