OpenCMIS Cookbook

Find and share OpenCMIS best practices here.

CMIS Client

Connecting to a CMIS repository

Connecting to a CMIS repository by AtomPub

// Default factory implementation of client runtime.
SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
Map<String, String> parameter = new HashMap<String, String>();

// User credentials.
parameter.put(SessionParameter.USER, "user");
parameter.put(SessionParameter.PASSWORD, "password");

// Connection settings.
parameter.put(SessionParameter.ATOMPUB_URL, "http://localhost:8080/alfresco/service/cmis"); // URL to your CMIS server.
// parameter.put(SessionParameter.REPOSITORY_ID, "myRepository"); // Only necessary if there are more than one repository.
parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());

// Session locale.
parameter.put(SessionParameter.LOCALE_ISO3166_COUNTRY, "");
parameter.put(SessionParameter.LOCALE_ISO639_LANGUAGE, "en");
parameter.put(SessionParameter.LOCALE_VARIANT, "US");

// Create session.
Session session = null;
try {
	// This supposes only one repository is available at the URL.
	Repository soleRepository = sessionFactory.getRepositories(parameter).get(0);
	session = soleRepository.createSession();
}
catch(CmisConnectionException e) { 
	// The server is unreachable
}
catch(CmisRuntimeException e) {
	// The user/password have probably been rejected by the server.
}

Using Cookies

Some repositories are sending HTTP cookies to maintain state (although CMIS is stateless) or accelerate authentication for subsequent calls. OpenCMIS ignores these cookies by default. The following code snippet activates cookies for your application and OpenCMIS. See this page for details.

CookieManager cm = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cm);

Understanding the client side cache

Client side caching is turned on by default. That is, getObject() will first look into the session cache if the object already exists there. If this is the case, it returns the object without talking to the repository. So it might return stale objects.

There are multiple ways to deal with that:

  • Refresh the object data that is returned from getObject().
    CmisObject object = session.getObject(id);
    	
    object.refresh(); // contacts the repository and refreshes the object
    	         
    object.refreshIfOld(60 * 1000); // ... or refreshes the object only if the data is older than a minute	        
    
  • Turn off the session cache completely.
    session.getDefaultContext().setCacheEnabled(false);
    
  • Turn off caching for this getObject() call.
    OperationContext oc = session.createOperationContext();
    oc.setCacheEnabled(false);
            
    CmisObject object = session.getObject(id, oc);
    
  • Clear the session cache (not recommended).
    session.clear();
    

Getting the id of an object from its path

String path = "/User Homes/customer1/document.odt"
CmisObject object = getSession().getObjectByPath(path);
String id = object.getId();

Reading a file

CmisObject object = getSession().getObject(session.createObjectId(fileId));
Document document = (Document)object;
String filename = document.getName();
InputStream stream = document.getContentStream().getStream();

Showing a folder's items, with results paging

int maxItemsPerPage = 5;
int skipCount = 10;

CmisObject object = session.getObject(session.createObjectId(folderId));
Folder folder = (Folder)object;
OperationContext operationContext = session.createOperationContext();
operationContext.setMaxItemsPerPage(maxItemsPerPage);

ItemIterable<CmisObject> children = folder.getChildren(operationContext);
ItemIterable<CmisObject> page = children.skipTo(skipCount).getPage();

Iterator<CmisObject> pageItems = page.iterator();
while(pageItems.hasNext()) {
       CmisObject item = pageItems.next();
       // Do something with the item.
}

Retrieving Document objects from query results

String myType = "my:documentType";
String queryString = "SELECT * FROM " + myType;

// get the query name of cmis:objectId
ObjectType type = session.getTypeDefinition(myType);
PropertyDefinition<?> objectIdPropDef = type.getPropertyDefinitions().get(PropertyIds.OBJECT_ID);
String objectIdQueryName = objectIdPropDef.getQueryName();

// execute query
ItemIterable<QueryResult> results = session.query(queryString, false);

for (QueryResult qResult : results) {
   String objectId = qResult.getPropertyValueByQueryName(objectIdQueryName);
 
   Document doc = (Document) session.getObject(session.createObjectId(objectId));
}

Connecting from a .Net client via the Web Services binding

This is a very simple C# example that demonstrates how to connect to an OpenCMIS server via the Web Services binding. Please note that .Net only allows UsernameTokens over HTTPS.

using System;
using System.ServiceModel;
using OpenCMISClient.OpenCMISServer;
using System.Net;

namespace OpenCMISClient
{
    class CMISClientDemo
    {
        public void DoStuff()
        {
            try
            {
                // uncomment the next line if you are using a self signed SSL certificate 
                // ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

                // get hold of the services
                RepositoryServicePortClient repService = GetRepositoryService("https://localhost:8443/opencmis/services/RepositoryService?wsdl", "test", "test");
                NavigationServicePortClient navService = GetNavigationService("https://localhost:8443/opencmis/services/NavigationService?wsdl", "test", "test");
                ObjectServicePortClient objService = GetObjectService("https://localhost:8443/opencmis/services/ObjectService?wsdl", "test", "test");

                // get the list of repositories
                cmisRepositoryEntryType[] repositoryEntries = repService.getRepositories(null);
                foreach (cmisRepositoryEntryType repositoryEntry in repositoryEntries)
                {
                    Console.WriteLine("Repository: " + repositoryEntry.repositoryName + " (" + repositoryEntry.repositoryId + ")");

                    // get repository info
                    cmisRepositoryInfoType repositoryInfo = repService.getRepositoryInfo(repositoryEntry.repositoryId, null);
                    Console.WriteLine("  Info:");
                    Console.WriteLine("    Description: " + repositoryInfo.repositoryDescription);
                    Console.WriteLine("    Product:     " + repositoryInfo.vendorName + " / " + repositoryInfo.productName + " " + repositoryInfo.productVersion);

                    // get all base types of the repository
                    cmisTypeDefinitionListType typeList = repService.getTypeChildren(repositoryInfo.repositoryId, null, true, null, null, null);
                    Console.WriteLine("  Types:");
                    foreach (cmisTypeDefinitionType type in typeList.types)
                    {
                        Console.WriteLine("    " + type.displayName + " (" + type.id + ")");
                    }

                    // get all root folder children
                    cmisObjectInFolderListType children = navService.getChildren(repositoryInfo.repositoryId, repositoryInfo.rootFolderId, null, null, true, null, null, false, null, null, null);
                    Console.WriteLine("  Root folder:");
                    foreach (cmisObjectInFolderType objInFolder in children.objects)
                    {
                        cmisObjectType obj = objInFolder.@object;
                        String objId = GetIdPropertyValue(obj.properties, "cmis:objectId");
                        Console.WriteLine("    Name: " + GetStringPropertyValue(obj.properties, "cmis:name") + " (" + objId + ")");
                        Console.WriteLine("      Type:          " + GetIdPropertyValue(obj.properties, "cmis:baseTypeId"));
                        Console.WriteLine("      Created by:    " + GetStringPropertyValue(obj.properties, "cmis:createdBy"));
                        Console.WriteLine("      Creation date: " + GetDateTimePropertyValue(obj.properties, "cmis:creationDate"));

                        // if it is a document, get the size and the content
                        String baseType = GetIdPropertyValue(obj.properties, "cmis:baseTypeId");
                        if ("cmis:document".Equals(baseType))
                        {
                            // get the size
                            Int64? size = GetIntegerPropertyValue(obj.properties, "cmis:contentStreamLength");
                            Console.WriteLine("      Size:          " + size);

                            // get the content
                            cmisContentStreamType content = objService.getContentStream(repositoryInfo.repositoryId, objId, null, null, null, null);
                            Console.WriteLine("      MIME type:     " + content.mimeType);

                            // get the "stream"
                            byte[] bytes = content.stream; // really streaming requires some more work
                            Console.WriteLine("      Stream:        " + (bytes.Length == size ? "ok" : "mismatch"));
                        }
                    }

                }
            }
            catch (FaultException<cmisFaultType> fe)
            {
                Console.WriteLine("CMIS Exception: " + fe.Detail.message);
                Console.WriteLine("Type: " + fe.Detail.type);
                Console.WriteLine("Code: " + fe.Detail.code);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.Message);
                Console.WriteLine(e.StackTrace);
            }

            Console.ReadKey();
        }

        public RepositoryServicePortClient GetRepositoryService(String wsdlUrl, String user, String password)
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.MessageEncoding = WSMessageEncoding.Mtom;
            binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;

            RepositoryServicePortClient service = new RepositoryServicePortClient(binding, new EndpointAddress(wsdlUrl));

            service.ClientCredentials.UserName.UserName = user;
            service.ClientCredentials.UserName.Password = password;

            return service;
        }

        public NavigationServicePortClient GetNavigationService(String wsdlUrl, String user, String password)
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.MessageEncoding = WSMessageEncoding.Mtom;
            binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;

            NavigationServicePortClient service = new NavigationServicePortClient(binding, new EndpointAddress(wsdlUrl));

            service.ClientCredentials.UserName.UserName = user;
            service.ClientCredentials.UserName.Password = password;

            return service;
        }


        public ObjectServicePortClient GetObjectService(String wsdlUrl, String user, String password)
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.MessageEncoding = WSMessageEncoding.Mtom;
            binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential;
            binding.TransferMode = TransferMode.Streamed;

            ObjectServicePortClient service = new ObjectServicePortClient(binding, new EndpointAddress(wsdlUrl));

            service.ClientCredentials.UserName.UserName = user;
            service.ClientCredentials.UserName.Password = password;

            return service;
        }

        public String GetStringPropertyValue(cmisPropertiesType properties, String id)
        {
            String result = null;

            foreach (cmisProperty property in properties.Items)
            {
                if (property.propertyDefinitionId.Equals(id))
                {
                    if (property is cmisPropertyString)
                    {
                        result = ((cmisPropertyString)property).value[0];
                    }
                    break;
                }
            }

            return result;
        }

        public String GetIdPropertyValue(cmisPropertiesType properties, String id)
        {
            String result = null;

            foreach (cmisProperty property in properties.Items)
            {
                if (property.propertyDefinitionId.Equals(id))
                {
                    if (property is cmisPropertyId)
                    {
                        result = ((cmisPropertyId)property).value[0];
                    }
                    break;
                }
            }

            return result;
        }

        public Int64? GetIntegerPropertyValue(cmisPropertiesType properties, String id)
        {
            Int64? result = null;

            foreach (cmisProperty property in properties.Items)
            {
                if (property.propertyDefinitionId.Equals(id))
                {
                    if (property is cmisPropertyInteger)
                    {
                        result = Int64.Parse(((cmisPropertyInteger)property).value[0]);
                    }
                    break;
                }
            }

            return result;
        }

        public DateTime? GetDateTimePropertyValue(cmisPropertiesType properties, String id)
        {
            DateTime? result = null;

            foreach (cmisProperty property in properties.Items)
            {
                if (property.propertyDefinitionId.Equals(id))
                {
                    if (property is cmisPropertyDateTime)
                    {
                        result = ((cmisPropertyDateTime)property).value[0];
                    }
                    break;
                }
            }

            return result;
        }
    }
}

Reading metadata and content from a CMIS repository

TODO

Creating and updating CMIS objects

TODO

Using the query parser

TODO

CMIS Server

TODO