CHEM100 - a Clojure Wrapper for the CMIS Client API
CHEM100 is a Clojure wrapper for the Apache Chemistry Client API. The name is a knock-off from Chemistry classes in college. The "100" refers to the 1.00 version of the CMIS Specification. Currently, there is CMIS for Java, Python, PHP, .Net and Objective-C. The marriage of a REPL (Read Evaluate Print Loop) and the CMIS API is a natural fit for live coding and interacting with a Content Management System (CMS).
Work in Progress
This API is very much a work in progress. I started working on this while working through the CMIS and Apache Chemistry in Action book. So, the amount of the wrapper that is completed varies based on the book and my own uses. However, it is possible to use the API with the current code. There are examples in Midje unit tests.
With Lisp, pretty much any IDE will work, however, the level of integration with the REPL and the IDE varies. With LightTable, the integration is almost seamless. It is possible to use Eclipse, IntelliJ, Emacs and even Vi to work with Clojure and the CHEM100 Wrapper, using Light Table makes it a lot easier to install and very little configuration is required.
Start by cloning this project, then install LightTable. Once Light Table is running, select the 'View' Menu Item and then select 'Workspace'. From there you can select the cloned version of CHEM100 using the right-click.
Connecting to a CHEM100 REPL
A quick word of warning, anything in these files can be executed or an entire file can be executed. If there is a connection to a Repository and a delete, it is entirely possible to delete entire trees of folders. So with great power, comes great responsibility.
The LightTable IDE can connect up to a running REPL or you can have it start one. From then on, the code/commands are sent to the REPL, executed and the response returned. To execute a single form, put your cursor anywhere in the form and hit <CTRL-ENTER>. Beware, if you select <SHIFT-CTRL-ENTER> then the entire file is processed.
The easiest way to create/connect to a REPL is to put your cursor in the first line of the demo001.clj file:
And press <CTRL-ENTER>. If you watch the bottom of the screen, you will see Light Table create and connect to a REPL. From then on you can work your way down the file, pressing <CTRL-ENTER> on each line of code.
(+ 3 4) and then <CTRL-ENTER>
What Light Table will show you at the end of the line/form, is the result of processing the form (i.e. 7).
This file contains some sample CHEM100 code, not worth dwelling on.
There are several advantages to using Clojure. First, it is a Lisp and of course it has a REPL. This gives us a shell out of the box. And while there are many Lisps available, Clojure interops with Java, which enables the devloper to rs-use all the existing Java Libraries. Some would say, "a better java than java". The other reason for Clojure is wrapping the CMIS API is almost trivial. There are a few "gotchas" when trying to create the parameters necessary to talk to the CMIS API, but nothing too difficult so far.
However, I admit, the most an important reason to use Clojure is that it is FUN. And it is amazing to execute code in the REPL and to see the effects inside of a CMS.
Clojure has a highly active group of supporters.
For the Developer, the next steps are dependent on how familiar you are with Clojure and Lisp's in general. There is good support for Clojure in Eclipse, IntelliJ, Vim and of course Emacs. Over time, I am adding Unit Tests using Midje. I am trying to include tests for each function. For my testing, I have been using the "inmemory-cmis server", which is comes with the book "CMIS and Apache Chemistry in Action", which I recommend. And since I will be running my tests against the supplied Content Model/Content, it would make sense to have it handy. However, you don't have to have it available. In fact, all you need is CHEM100 and a Clojure REPL to get started.
A lot of the CMIS API functionality is in the Session Object. It is a very large object with a lot of methods. I have broken that up into individual Clojure Namespaces. And while this isn't absolutely necessary, it does present a more cohesive view of the API. The other option was to create a single namespace with all the functions in it.
So, most of the Namespaces correspond to logical groups of the Session Object methods. Some are artifacts of my development process. I started with running all my tests in core.clj, I am in the process of moving all of those to the Midje Unit Tests. So, eventually, core.clj will probably go away. The "demo" namespace is the home of an interactive Demo I am creating, so it has a bunch of hard-coded values to speed up the demo process. And temp.clj is just a place to store code that I may or may not need in the future.
I had to make a choice between having a single session and have all the functions use that one session or to pass the session into each function as a parameter. There are pros and cons to each method and I chose to pass the session in as a parameter.
Enterprise Content Management Systems
I am currently working with the Inmemory CMIS Server for most of my testing. However, I will be actively testing with Alfresco in the near future.
Content Management Interoperability Services (CMIS) Version 1.1
The 1.1 version of the specification was released on May 23, 2013. At this point in time, I don't think there is much support for it. However, at some point we will need a CHEM110.
- Apache Chemistry
- The Apache Chemistry book
- Leiningen - Automate Clojure projects without setting your hair on fire
- Clojure-Java Interop
- Midje - Unit Tests
- Emacs nREPL.el
- A Better Java than Java
Copyright © 2013 Zia Consulting, Inc.
Distributed under the Eclipse Public License, the same as Clojure.