chemistry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r785815 - /websites/staging/chemistry/trunk/content/how-to-build-a-server.html
Date Sun, 20 Feb 2011 22:32:01 GMT
Author: buildbot
Date: Sun Feb 20 22:32:01 2011
New Revision: 785815

Log:
Staging update by buildbot

Modified:
    websites/staging/chemistry/trunk/content/how-to-build-a-server.html

Modified: websites/staging/chemistry/trunk/content/how-to-build-a-server.html
==============================================================================
--- websites/staging/chemistry/trunk/content/how-to-build-a-server.html (original)
+++ websites/staging/chemistry/trunk/content/how-to-build-a-server.html Sun Feb 20 22:32:01 2011
@@ -172,7 +172,594 @@ Apache Chemistry - How To Build A Server
            </td>
            <td height="100%">
              <!-- Content -->
-             <div class="wiki-content"></div>
+             <div class="wiki-content"><p><a name="HowToBuildAServer-HowtocreateaCMISserverusingOpenCMIS"></a></p>
+<h1 id="how_to_create_a_cmis_server_using_opencmis">How to create a CMIS server using OpenCMIS</h1>
+<p>This document contains a step-by-step introduction how you can use opencmis
+to build an CMIS server. The document is divided iton the following
+sections:</p>
+<p>Getting started. (download, setup Eclipse, etc.)</p>
+<ol>
+<li>Implementing the services</li>
+<li>The ServiceWrapper</li>
+<li>Differences between SOAP and AtomPub (ObjectHolder)</li>
+<li>Running the server</li>
+<li>Handling Authentication</li>
+<li>Testing the server</li>
+</ol>
+<p><a name="HowToBuildAServer-Gettingstarted:"></a></p>
+<h1 id="getting_started">Getting started:</h1>
+<p>The following step-by-step guide is a sample how to create a web
+application acting as CMIS server. It will support both bindings web
+services and AtomPub.</p>
+<p>The following section describes how to initially setup a project to compile
+a CMIS server. Please note that CMIS comes with two built-in servers. The
+fileshare and the in-memory server. It is a good hint for all upcoming
+questions to look at these implementations as example code containing
+working implementations.</p>
+<p><a name="HowToBuildAServer-Usingmaven"></a></p>
+<h2 id="using_maven">Using maven</h2>
+<p>Using maven is the easiest way to get started. OpenCMIS itself is using
+maven and you can get easily your setup and dependencies using maven. This
+requires that you have a working maven environment. In case you don't yet
+have one you can find instructions <a href="http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html">here</a>
+.</p>
+<p>The first step is to create your initial pom.xml file to build your project
+and to setup the dependencies. The following steps require that you have
+build opencmis and installed it to your local maven repository {{(mvn
+install)}}. See <a href="opencmis-how-to-build.html">here</a>
+ for detailed instructions how to do this.</p>
+<p>You can create your initial setup using maven itself (adjust package name,
+version number and so on according to your needs):</p>
+<div class="codehilite"><pre><span class="n">mvn</span> <span class="n">archetype:generate</span> <span class="o">-</span><span class="n">DgroupId</span><span class="o">=</span><span class="n">org</span><span class="o">.</span><span class="n">mycmis</span> <span class="o">-</span><span class="n">DartifactId</span><span class="o">=</span> <span class="n">mycmissrv</span> <span class="o">\</span>
+<span class="o">-</span><span class="n">DpackageName</span><span class="o">=</span><span class="nb">local</span><span class="o">.</span><span class="n">mycmis</span> <span class="o">-</span><span class="n">Dversion</span><span class="o">=</span><span class="mf">0.1</span>
+</pre></div>
+
+
+<p>Then select option 18 <em>maven-archetype-webapp</em> and confirm settings.</p>
+<p>You will find a project setup then consisting of a directory <em>mycmissvr</em>
+and subdirectories for source code and test code and the Java packages. We
+need to adapt the .pom file so that maven creates a web application file
+that can be deployed in a servlet container (like Apache Tomcat or Jetty).
+We also need to setup the dependencies to opencmis and we need to instruct
+maven generating an overlay with the existing server code in opencmis.
+Please remove therefore the entire generated src/webapp directory and all
+included files (<em>.jsp, web.xml).
+The final </em>pom.xml* will look like this:</p>
+<p>{code:xml|title=pom.xml|borderStyle=solid}
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.mycmis</groupId>
+  <artifactId>mycmissrv</artifactId>
+  <packaging>war</packaging>
+  <version>0.1</version>
+  <name>mycmissrv Maven Webapp</name>
+  <url>http://maven.apache.org</url></p>
+<p><properties>
+    <opencmisVersion>0.1.0-incubating-SNAPSHOT</opencmisVersion>
+    <opencmisGroupId>org.apache.chemistry.opencmis</opencmisGroupId>
+  </properties></p>
+<p><build>
+    <finalName>mycmissrv</finalName>
+    <plugins>
+      <plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-war-plugin</artifactId>
+    <configuration>
+      <overlays>
+        <overlay>
+        </overlay>
+        <overlay>
+          <groupId>${opencmisGroupId}</groupId>
+          <artifactId>chemistry-opencmis-server-bindings</artifactId>
+        </overlay>
+      </overlays>
+    </configuration>
+      </plugin>
+      <plugin>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <configuration>
+       <target>1.5</target>
+       <source>1.5</source>
+       <encoding>UTF-8</encoding>
+    </configuration>
+      </plugin>
+    </plugins>
+  </build></p>
+<p><dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${opencmisGroupId}</groupId>
+      <artifactId>chemistry-opencmis-commons-api</artifactId>
+      <version>${opencmisVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>${opencmisGroupId}</groupId>
+      <artifactId>chemistry-opencmis-commons-impl</artifactId>
+      <version>${opencmisVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>${opencmisGroupId}</groupId>
+      <artifactId>chemistry-opencmis-test-util</artifactId>
+      <version>${opencmisVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>${opencmisGroupId}</groupId>
+      <artifactId>chemistry-opencmis-server-bindings</artifactId>
+      <version>${opencmisVersion}</version>
+      <type>war</type>
+   </dependency>
+    <dependency>
+      <groupId>${opencmisGroupId}</groupId>
+      <artifactId>chemistry-opencmis-server-support</artifactId>
+      <version>${opencmisVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.antlr</groupId>
+      <artifactId>antlr-runtime</artifactId>
+      <version>3.1.3</version>
+    </dependency><br />
+  </dependencies>
+</project></p>
+<div class="codehilite"><pre><span class="n">You</span> <span class="n">will</span> <span class="n">get</span> <span class="n">your</span> <span class="p">{{</span><span class="n">web</span><span class="o">.</span><span class="n">xml</span><span class="p">}}</span> <span class="ow">and</span> <span class="n">other</span> <span class="n">required</span> <span class="n">files</span> <span class="k">for</span> <span class="n">your</span> <span class="n">web</span>
+</pre></div>
+
+
+<p>application from opencmis which you may adjust according to your needs. You
+may run {{mvn eclipse:eclipse}} to generate the required {{.projects}} and
+{{.classpath}} files for Eclipse that you just need to import in your
+Eclipse workspace.</p>
+<div class="codehilite"><pre><span class="n">h2</span><span class="o">.</span> <span class="n">Without</span> <span class="n">maven</span>
+
+<span class="n">If</span> <span class="n">you</span> <span class="k">do</span> <span class="ow">not</span> <span class="n">want</span> <span class="n">to</span> <span class="k">use</span> <span class="n">maven</span> <span class="n">to</span> <span class="n">build</span> <span class="n">your</span> <span class="n">project</span> <span class="n">you</span> <span class="n">currently</span> <span class="n">have</span> <span class="n">to</span>
+</pre></div>
+
+
+<p>use maven to produce the binaries from the source code. Download the source
+code and run</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">mvn</span> <span class="nb">package</span>
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">to</span> <span class="n">produce</span> <span class="n">a</span> <span class="n">binary</span> <span class="n">version</span> <span class="n">of</span> <span class="n">all</span> <span class="n">packaged</span> <span class="n">files</span><span class="o">.</span> <span class="n">To</span> <span class="n">reuse</span> <span class="n">the</span> <span class="n">relevant</span>
+</pre></div>
+
+
+<p>files from the server implementation in opencmis type:</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">cd</span> <span class="n">chemistry</span><span class="o">-</span><span class="n">opencmis</span><span class="o">-</span><span class="n">server</span>
+<span class="n">cd</span> <span class="n">chemistry</span><span class="o">-</span><span class="n">opencmis</span><span class="o">-</span><span class="n">server</span><span class="o">-</span><span class="n">bindings</span>
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+
+<span class="n">Unzip</span> <span class="n">the</span> <span class="n">file</span>
+</pre></div>
+
+
+<p>{{chemistry-opencmis-server-bindings-0.1-incubating-SNAPSHOT.jar}} and copy
+the contents to your project. It includes all required jars, web.xml and
+other supporting files. In case you prefer an empty classes directory and
+use a jar instead you can use:</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">mvn</span> <span class="n">jar:jar</span>
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">Then</span> <span class="n">copy</span> <span class="n">the</span> <span class="n">file</span> <span class="n">named</span> <span class="p">{{</span><span class="n">opencmis</span><span class="o">-</span><span class="n">server</span><span class="o">-</span><span class="n">impl</span><span class="o">-</span><span class="mf">0.1</span><span class="o">-</span><span class="n">SNAPSHOT</span><span class="o">.</span><span class="n">jar</span><span class="p">}}</span> <span class="n">from</span> <span class="n">the</span>
+</pre></div>
+
+
+<p>target directory to your project directory. Add all jar files from the
+{{.war}} and the one created in the previous step to your project setup.
+Add the {{repository.properties}} file to your classpath.</p>
+<div class="codehilite"><pre><span class="n">Now</span> <span class="n">you</span> <span class="n">have</span> <span class="n">an</span> <span class="n">initial</span> <span class="p">{{</span><span class="n">web</span><span class="o">.</span><span class="n">xml</span><span class="p">}}</span> <span class="ow">and</span> <span class="n">the</span> <span class="n">required</span> <span class="n">support</span> <span class="n">files</span> <span class="k">for</span> <span class="n">the</span>
+</pre></div>
+
+
+<p>web services binding. Unless you have specific requirements you do not need
+to modify them.</p>
+<h1 id="implementing_the_services">Implementing the services</h1>
+<div class="codehilite"><pre><span class="n">The</span> <span class="n">first</span> <span class="n">step</span> <span class="n">is</span> <span class="n">to</span> <span class="nb">tell</span> <span class="n">opencmis</span> <span class="n">where</span> <span class="n">it</span> <span class="n">can</span> <span class="n">find</span> <span class="n">your</span> <span class="n">classes</span> <span class="n">that</span>
+</pre></div>
+
+
+<p>implement the CMIS logic. For this purpose a file named
+repository.properties must be in the classpath. It must contain a property
+named class that refers to your service factory:</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">class</span><span class="o">=</span><span class="nb">local</span><span class="o">.</span><span class="n">mycmis</span><span class="o">.</span><span class="n">ServiceFactory</span>
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+
+<span class="n">The</span> <span class="n">ServiceFactory</span> <span class="n">class</span> <span class="n">should</span> <span class="n">extend</span> <span class="n">the</span> <span class="p">{{</span><span class="n">AbstractServiceFactory</span><span class="p">}}</span> <span class="n">class</span>
+</pre></div>
+
+
+<p>from org.apache.chemistry.opencmis.commons.impl.server. You have to
+implement the interface CmisServiceFactory:</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">code:java</span><span class="o">|</span><span class="n">borderStyle</span><span class="o">=</span><span class="n">solid</span><span class="p">}</span>
+  <span class="n">public</span> <span class="n">void</span> <span class="n">init</span><span class="p">(</span><span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">String</span><span class="o">&gt;</span> <span class="n">parameters</span><span class="p">)</span> <span class="p">{</span>
+    <span class="p">}</span>
+
+  <span class="n">public</span> <span class="n">void</span> <span class="n">destroy</span><span class="p">()</span> <span class="p">{</span>
+    <span class="p">}</span>
+
+  <span class="n">public</span> <span class="n">abstract</span> <span class="n">CmisService</span> <span class="n">getService</span><span class="p">(</span><span class="n">CallContext</span> <span class="n">context</span><span class="p">);</span>
+</pre></div>
+
+
+<p>The <em>init()</em> method is used to perform initialization and passes a set of
+configuration parameters from repository.properties:</p>
+<p>{code:java|borderStyle=solid}
+@Override
+public void init(Map<String, String> parameters) {
+}</p>
+<div class="codehilite"><pre><span class="n">Typically</span> <span class="n">you</span> <span class="n">will</span> <span class="n">create</span> <span class="n">an</span> <span class="n">instance</span> <span class="n">of</span> <span class="n">your</span> <span class="n">service</span> <span class="n">implementation</span><span class="o">.</span>
+
+<span class="n">There</span> <span class="n">is</span> <span class="n">also</span> <span class="n">wrapper</span> <span class="n">classes</span> <span class="n">is</span> <span class="n">explained</span> <span class="n">in</span> <span class="n">the</span> <span class="k">next</span> <span class="n">section</span><span class="o">.</span>
+
+<span class="n">The</span> <span class="k">next</span> <span class="n">step</span> <span class="n">is</span> <span class="n">that</span> <span class="n">you</span> <span class="n">need</span> <span class="n">to</span> <span class="n">implement</span> <span class="n">the</span> <span class="n">services</span> <span class="n">according</span> <span class="n">to</span> <span class="n">the</span>
+</pre></div>
+
+
+<p>CMIS spec. We will do this here for one example call. The important piece
+is that your class implements {{CmisService}} which is central access point
+to all incoming calls. Here is an implementation of an example call
+getRepositoryInfo():</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">code:java</span><span class="o">|</span><span class="n">borderStyle</span><span class="o">=</span><span class="n">solid</span><span class="p">}</span>
+<span class="n">public</span> <span class="n">class</span> <span class="n">MyCmisServiceImpl</span> <span class="n">extends</span> <span class="n">AbstractCmisService</span> <span class="p">{</span>
+
+    <span class="n">public</span> <span class="n">RepositoryInfo</span> <span class="n">getRepositoryInfo</span><span class="p">(</span><span class="n">CallContext</span> <span class="n">context</span><span class="p">,</span>
+      <span class="n">String</span> <span class="n">repositoryId</span><span class="p">,</span> <span class="n">ExtensionsData</span> <span class="n">extension</span><span class="p">)</span> <span class="p">{</span>
+
+        <span class="n">RepositoryInfoImpl</span> <span class="n">repoInfo</span> <span class="o">=</span> <span class="k">new</span> <span class="n">RepositoryInfoImpl</span><span class="p">();</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setRepositoryId</span><span class="p">(</span><span class="n">repositoryId</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setRepositoryName</span><span class="p">(</span><span class="s">&quot;My CMIS Repository&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setRepositoryDescription</span><span class="p">(</span><span class="s">&quot;Sample Repository&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setCmisVersionSupported</span><span class="p">(</span><span class="s">&quot;1.0&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setRepositoryCapabilities</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setRootFolder</span><span class="p">(</span><span class="s">&quot;MyRootFolderId&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setPrincipalAnonymous</span><span class="p">(</span><span class="s">&quot;anonymous&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setPrincipalAnyone</span><span class="p">(</span><span class="s">&quot;anyone&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setThinClientUri</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setChangesIncomplete</span><span class="p">(</span><span class="n">Boolean</span><span class="o">.</span><span class="n">TRUE</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setChangesOnType</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setLatestChangeLogToken</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setVendorName</span><span class="p">(</span><span class="s">&quot;ACME&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setProductName</span><span class="p">(</span><span class="s">&quot;ACME CMIS Connector&quot;</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setProductVersion</span><span class="p">(</span><span class="s">&quot;0.1&quot;</span><span class="p">);</span>
+
+        <span class="sr">//</span> <span class="n">set</span> <span class="n">capabilities</span>
+        <span class="n">RepositoryCapabilitiesImpl</span> <span class="n">caps</span> <span class="o">=</span> <span class="k">new</span>
+            <span class="n">RepositoryCapabilitiesImpl</span><span class="p">();</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setAllVersionsSearchable</span><span class="p">(</span><span class="n">false</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setCapabilityAcl</span><span class="p">(</span><span class="n">CapabilityAcl</span><span class="o">.</span><span class="n">NONE</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setCapabilityChanges</span><span class="p">(</span><span class="n">CapabilityChanges</span><span class="o">.</span><span class="n">PROPERTIES</span><span class="p">);</span>
+
+        <span class="n">caps</span><span class="o">.</span><span class="n">setCapabilityContentStreamUpdates</span><span class="p">(</span>
+            <span class="n">CapabilityContentStreamUpdates</span><span class="o">.</span><span class="n">PWCONLY</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setCapabilityJoin</span><span class="p">(</span><span class="n">CapabilityJoin</span><span class="o">.</span><span class="n">NONE</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setCapabilityQuery</span><span class="p">(</span><span class="n">CapabilityQuery</span><span class="o">.</span><span class="n">METADATAONLY</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setCapabilityRendition</span><span class="p">(</span><span class="n">CapabilityRenditions</span><span class="o">.</span><span class="n">NONE</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setIsPwcSearchable</span><span class="p">(</span><span class="n">false</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setIsPwcUpdatable</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setSupportsGetDescendants</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setSupportsGetFolderTree</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setSupportsMultifiling</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setSupportsUnfiling</span><span class="p">(</span><span class="n">true</span><span class="p">);</span>
+        <span class="n">caps</span><span class="o">.</span><span class="n">setSupportsVersionSpecificFiling</span><span class="p">(</span><span class="n">false</span><span class="p">);</span>
+            <span class="n">repoInfo</span><span class="o">.</span><span class="n">setRepositoryCapabilities</span><span class="p">(</span><span class="n">caps</span><span class="p">);</span>
+
+        <span class="n">AclCapabilitiesDataImpl</span> <span class="n">aclCaps</span> <span class="o">=</span> <span class="k">new</span> <span class="n">AclCapabilitiesDataImpl</span><span class="p">();</span>
+        <span class="n">aclCaps</span><span class="o">.</span><span class="n">setAclPropagation</span><span class="p">(</span><span class="n">AclPropagation</span><span class="o">.</span><span class="n">REPOSITORYDETERMINED</span><span class="p">);</span>
+        <span class="n">aclCaps</span><span class="o">.</span><span class="n">setPermissionDefinitionData</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">aclCaps</span><span class="o">.</span><span class="n">setPermissionMappingData</span><span class="p">(</span><span class="n">null</span><span class="p">);</span>
+        <span class="n">repoInfo</span><span class="o">.</span><span class="n">setAclCapabilities</span><span class="p">(</span><span class="n">aclCaps</span><span class="p">);</span>
+        <span class="k">return</span> <span class="n">repoInfo</span><span class="p">;</span>
+      <span class="p">}</span>
+     <span class="sr">//</span> <span class="o">...</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>Now you can start implementing all the required methods with their methods.</p>
+<p><a name="HowToBuildAServer-TheServiceWrapper"></a></p>
+<h2 id="the_servicewrapper">The ServiceWrapper</h2>
+<p>For the CmisService interface exists a corresponding abstract class. This
+can be used as a starting point for your implementation. This is optional
+but gives you the benefit of providing many common null pointer checks and
+default values for optional parameters. The abstract class also provides a
+default implementation for generating the ObjectInfo needed for the AtomPub
+binding. This wrapper can reduce the code required in your service
+implementation. You should always start using the wrapper class and
+directly implement the CmisService interface only when necessary. It is
+strongly recommended however to provide a better implementation for create
+the ObjectInfo however (see next section for details).</p>
+<p><a name="HowToBuildAServer-DifferencesbetweentheCMISbindings"></a></p>
+<h1 id="differences_between_the_cmis_bindings">Differences between the CMIS bindings</h1>
+<p>OpenCMIS supports both the AtomPub and the web services binding interface.
+It hides all the details how to handle the protocol but there are some
+subtle differences that need to be reflected in the Java interfaces. This
+chapter explains where the differences are and why they are needed.</p>
+<p><a name="HowToBuildAServer-TheObjectInfointerface"></a></p>
+<h2 id="the_objectinfo_interface">The ObjectInfo interface</h2>
+<p>The methods in the interfaces <em>CmisService</em> are following the data model
+in the CMIS specification. The specification defines the following
+services:</p>
+<ul>
+<li>AclService</li>
+<li>DiscoveryService</li>
+<li>ObjectService</li>
+<li>MultifFlingService</li>
+<li>NavigationService</li>
+<li>PolicyService</li>
+<li>RelationshipService</li>
+<li>RepositoryService</li>
+<li>Versioning Service</li>
+</ul>
+<p>For each of these services exists a corresponding interface in opencmis.
+CmisService is an interface that unifies all interfaces in one interface.
+The methods in this interface correspond to the methods in the
+specification. For the web service binding this is a one-to-one mapping.
+For the AtomPub binding this information is not sufficient in all cases.
+Take the creation of a document as an example. The web service returns in
+this case a single string value containing the id of the created document.
+A response in the AtomPub binding however consists of an AtomPub entry
+element which is an XML fragment (for an example look at
+<em>DocumentEntry.xml</em> in the examples directory of the CMIS specification).
+You will notice that generating this XML requires much more information
+than the create...() methods in the specification provide as return value.
+Your implementation needs to provide all the information so that opencmis
+can generate the complete response. For this purpose the <em>ObjectInfo</em> was
+introduced. <em>getObjectInfo</em> is the method of the CmisService interface
+that provides this information. The <em>AbstractCmisService</em> contains a
+member <em>objectInfoMap</em> that you can fill with this information. If you
+ignore this the class <em>AbstractCmisService</em> contains a default
+implementation which works but is very ineffecient. You should use this
+only as a starting point. Beware that a service can be called from multiple
+threads, so have to take care to handle threading issues properly.</p>
+<p>If the method you are implementing returns a list of objects and not only a
+single value (for example methods like <em>getChildren(), getDescendants()</em>
+in the navigation service) you need to provide an <em>ObjectInfo</em> for each
+element in the collection. <em>getObjectInfo</em> therefore returns a map with
+the object id for each object as key and the corresponding <em>ObjectInfo</em>
+as value. You can use the method <em>addObjectInfo</em> to add an element to the
+map. </p>
+<p><a name="HowToBuildAServer-Thecreate()methods"></a></p>
+<h2 id="the_create_methods">The create() methods</h2>
+<p>The web service binding has separate calls for each object type to be
+created: policies, relationshiops, documents and folders:</p>
+<ul>
+<li>createDocument</li>
+<li>createFolder</li>
+<li>createRelationship</li>
+<li>createPolicy</li>
+</ul>
+<p>In the AtomPub binding there is one general <em>create()</em> method that is
+used for all object types. The CmisObjectService interface therefore
+contains 5 <em>create()</em> methods, the four specific ones are used for the
+web service bindings and the general one for the AtomPub binding.</p>
+<p><a name="HowToBuildAServer-ApplyingACLs"></a></p>
+<h2 id="applying_acls">Applying ACLs</h2>
+<p>The class CmisAclService has two methods <em>applyAcl()</em>. One uses two
+AccessControlLists with one Acl to add &nbsp;and one to remove. The other
+method contains only one Acl to be set on the target object. The web
+service binding uses the method with two parameters, the AtomPub binding
+uses the method with one parameter.</p>
+<p><a name="HowToBuildAServer-RunningTheServer"></a></p>
+<h1 id="running_the_server">Running The Server</h1>
+<p>When your services are implemented (or parts of them) you can try to run
+the server in a servlet container like Tomcat. If you have used maven to
+setup your project you can run</p>
+<div class="codehilite"><pre><span class="n">mvn</span> <span class="nb">package</span>
+</pre></div>
+
+
+<p>to generate a war file that you will find in the target directory. If you
+have not used maven create the war with the mechanisms of your build
+environment. Check the war contains a &nbsp;web.xml, the wsdl files in
+<em>WEB-INF</em> and all the required jars from opencmis and dependent libraries
+in <em>WEB-INF/lib</em>. For jetty maven contains a build-in integration that
+you may use if you like using <em>mvn jetty:run</em>. Adjust your pom.xml in
+this case accordingly.</p>
+<p>Deploy your application and start testing.</p>
+<p><a name="HowToBuildAServer-HandlingAuthentication"></a></p>
+<h1 id="handling_authentication">Handling Authentication</h1>
+<p>Opencmis does not provide or expect any specific mechanism how
+authentication is handled. It provides some basic mechanisms hot to extract
+user name and password depending on the protocol. For AtomPub binding http
+basic authentication is supported, for web services WS-Security 1.1 for
+Username Token Profile 1.1 is supported.</p>
+<p>If you want to use servlet filters dealing with authentication, &nbsp;just
+add them to your web.xml file. You also can handle authentication inside of
+your code. In this case derive a class from <em>BasicAuthCallContextHandler</em>
+and implement method <em>getCallContextMap()</em>. There you have access to user
+name and password as provided by the user. By default opencmis does not
+enforce authentication, so initially the map will be null. If you raise a
+CmisPermissionDeniedException the exception is caught by the server
+implementation and a <em>401</em> http return code is sent as response to the
+browser. This usually opens a dialog for user name and password then.</p>
+<p>{code:java|borderStyle=solid}
+public class MyContextHandler
+    extends BasicAuthCallContextHandler
+{
+  public Map<String, String> getCallContextMap(HttpServletRequest request){</p>
+<div class="codehilite"><pre><span class="sr">//</span> <span class="n">call</span> <span class="n">superclass</span> <span class="n">to</span> <span class="n">get</span> <span class="n">user</span> <span class="ow">and</span> <span class="n">password</span> <span class="n">via</span> <span class="n">basic</span> <span class="n">authentication</span>
+<span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">String</span><span class="o">&gt;</span>  <span class="n">ctxMap</span> <span class="o">=</span> <span class="n">super</span><span class="o">.</span><span class="n">getCallContextMap</span><span class="p">(</span><span class="n">request</span><span class="p">);</span>
+
+<span class="k">if</span> <span class="p">(</span><span class="n">null</span> <span class="o">==</span> <span class="n">ctxMap</span><span class="p">)</span>
+  <span class="sr">//</span> <span class="nb">no</span> <span class="n">user</span> <span class="n">name</span><span class="p">,</span> <span class="n">password</span> <span class="n">given</span> <span class="n">yet</span> <span class="n">say:</span> <span class="n">we</span> <span class="n">need</span> <span class="n">authentication:</span>
+  <span class="n">throw</span> <span class="k">new</span> <span class="n">CmisPermissionDeniedException</span><span class="p">(</span><span class="s">&quot;Authentication required&quot;</span><span class="p">);</span>
+
+<span class="sr">//</span> <span class="n">call</span> <span class="n">your</span> <span class="n">authentication</span>
+
+<span class="n">MyAuthentication</span><span class="o">.</span><span class="n">login</span><span class="p">(</span>
+    <span class="n">ctxMap</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">CallContext</span><span class="o">.</span><span class="n">USERNAME</span><span class="p">),</span>
+    <span class="n">ctxMap</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">CallContext</span><span class="o">.</span><span class="n">PASSWORD</span><span class="p">));</span>
+
+<span class="k">return</span> <span class="n">ctxMap</span><span class="p">;</span>
+</pre></div>
+
+
+<p>}
+}</p>
+<div class="codehilite"><pre><span class="n">Beyond</span> <span class="n">this</span> <span class="n">it</span> <span class="n">is</span> <span class="n">up</span> <span class="n">to</span> <span class="n">you</span> <span class="n">how</span> <span class="n">to</span> <span class="n">implement</span> <span class="n">authentication</span><span class="o">.</span> <span class="n">Creating</span>
+</pre></div>
+
+
+<p>tokens for example, using cookies, etc. is not covered by opencmis, but you
+can add it in your code.</p>
+<h1 id="configuring_your_server">Configuring your server</h1>
+<div class="codehilite"><pre><span class="n">Opencmis</span> <span class="n">reads</span> <span class="n">a</span> <span class="n">file</span> <span class="n">repository</span><span class="o">.</span><span class="n">properties</span> <span class="n">on</span> <span class="n">startup</span><span class="o">.</span> <span class="n">By</span> <span class="n">default</span> <span class="n">you</span> <span class="n">only</span>
+</pre></div>
+
+
+<p>have to configure the class of your service factory (see above). You can
+add additional properties in this file. These configuration parameters are
+then passed to the {{init()}} method of your ServiceFactory method as key
+value pairs in a hashmap.</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">code:title</span><span class="o">=</span><span class="n">repository</span><span class="o">.</span><span class="n">properties</span><span class="o">|</span><span class="n">borderStyle</span><span class="o">=</span><span class="n">solid</span><span class="p">}</span>
+  <span class="n">class</span><span class="o">=</span><span class="nb">local</span><span class="o">.</span><span class="n">mycmis</span><span class="o">.</span><span class="n">ServiceFactory</span>
+  <span class="n">myparam</span><span class="o">=</span><span class="k">my</span><span class="o">-</span><span class="n">configuration</span><span class="o">-</span><span class="n">value</span>
+</pre></div>
+
+
+<p>{code:java|title=local.mycmis.ServiceFactory.java|borderStyle=solid}
+// ...
+@Override
+public void init(Map<String, String> parameters) {
+  String myParamValue = parameters.get("myparam");
+    // use myParamValue
+}
+// ...</p>
+<h1 id="testing_the_server">Testing the server</h1>
+<div class="codehilite"><pre><span class="n">There</span> <span class="n">are</span> <span class="n">various</span> <span class="n">ways</span> <span class="n">how</span> <span class="n">you</span> <span class="n">can</span> <span class="n">test</span> <span class="n">your</span> <span class="n">implementation</span><span class="o">.</span> <span class="n">You</span> <span class="n">may</span> <span class="n">add</span>
+</pre></div>
+
+
+<p>unit tests that directly call your service implementations as a first step.
+Opencmis also contains some basic tests that perform client-server
+communication. You can choose the protocol binding and whether read-only or
+read-write tests are performed. The amount of functionality tested depends
+on the capabilities returned in your getRepositoryInfo return value. You
+can run them using junit:</p>
+<div class="codehilite"><pre><span class="err">Examples:</span>
+
+<span class="err">Test</span> <span class="kd">class</span><span class="err">:</span>
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="err">org.apache.chemistry.opencmis.client.bindings.atompub.SimpleReadOnlyTests</span>
+<span class="err">{noformat}</span>
+
+<span class="err">Test</span> <span class="err">Parameters</span> <span class="err">(passed</span> <span class="err">as</span> <span class="err">JVM</span> <span class="err">args):</span>
+<span class="err">{noformat}</span>
+<span class="err">-Dopencmis.test=true</span>
+<span class="err">-Dopencmis.test.username=myuser</span>
+<span class="err">-Dopencmis.test.password=mypasswd</span>
+<span class="err">-Dopencmis.test.repository=my_repository_id&amp;nbsp;</span>
+<span class="err">-Dopencmis.test.atompub.url=[http:</span><span class="c1">//localhost:8080/opencmis/atom]</span>
+<span class="err">{noformat}</span>
+
+<span class="err">The</span> <span class="err">following</span> <span class="err">test</span> <span class="kd">class</span><span class="err">es</span> <span class="err">exist:</span>
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="err">org.apache.opencmis.client.bindings.atompub.SimpleReadOnlyTests</span>
+<span class="err">org.apache.opencmis.client.bindings.atompub.SimpleReadWriteTests</span>
+<span class="err">org.apache.opencmis.client.bindings.webservices.SimpleReadOnlyTests</span>
+<span class="err">org.apache.opencmis.client.bindings.webservices.SimpleReadWriteTests</span>
+<span class="err">{noformat}</span>
+
+<span class="err">For</span> <span class="err">web</span> <span class="err">services</span> <span class="err">you</span> <span class="err">need</span> <span class="err">an</span> <span class="err">additional</span> <span class="err">parameter</span> <span class="err">for</span> <span class="err">the</span> <span class="err">service</span> <span class="err">endpoint:</span>
+<span class="err">{noformat}</span>
+<span class="err">-Dopencmis.test.webservices.url=[http:</span><span class="c1">//localhost:8080/opencmis/services/]</span>
+<span class="err">{noformat}</span>
+</pre></div>
+
+
+<h2 id="test_using_curl">Test using curl</h2>
+<div class="codehilite"><pre><span class="n">Simple</span> <span class="n">tests</span> <span class="p">(</span><span class="n">which</span> <span class="n">might</span> <span class="n">be</span> <span class="n">useful</span> <span class="n">at</span> <span class="n">the</span> <span class="n">beginning</span><span class="p">)</span> <span class="n">can</span> <span class="n">also</span> <span class="n">be</span> <span class="n">done</span>
+</pre></div>
+
+
+<p>using tools like curl or wget (AtomPub binding only). A simple example for
+a .BAT file (Windows) would look like this:</p>
+<div class="codehilite"><pre><span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="n">rem</span> <span class="n">set</span> <span class="n">PATH</span><span class="o">=...\</span><span class="n">libcurl</span><span class="o">-</span><span class="mf">7.19.7</span><span class="p">;</span><span class="o">...\</span><span class="n">OpenSSL</span><span class="o">\</span><span class="n">bin</span><span class="p">;</span><span class="nv">%PATH%</span>
+<span class="nv">set</span> <span class="n">CURL</span><span class="o">=</span><span class="n">curl</span><span class="o">.</span><span class="n">exe</span>
+<span class="n">set</span> <span class="n">VIEWER</span><span class="o">=</span><span class="s">&quot;C:\Program Files\Mozilla Firefox\firefox.exe&quot;</span>
+<span class="n">set</span> <span class="n">USER</span><span class="o">=</span><span class="n">XXX</span>
+<span class="n">set</span> <span class="n">PWD</span><span class="o">=</span><span class="n">YYY</span>
+<span class="n">set</span> <span class="n">URLPREFIX</span><span class="o">=</span><span class="p">[</span><span class="n">http:</span><span class="sr">//</span><span class="n">localhost:8080</span><span class="sr">/opencmis/</span><span class="n">atom</span><span class="p">]</span>
+<span class="n">SET</span> <span class="n">OUTFILE</span><span class="o">=</span><span class="n">atom</span><span class="o">.</span><span class="n">xml</span>
+
+<span class="nv">%CURL%</span> <span class="err">\--</span><span class="nv">user</span> <span class="nv">%USER%:%PWD%</span> <span class="err">\--</span><span class="nv">dump</span><span class="o">-</span><span class="n">header</span> <span class="n">header</span><span class="o">.</span><span class="n">txt</span> <span class="o">\--</span><span class="n">output</span> <span class="nv">%OUTFILE%</span>
+</pre></div>
+
+
+<p>%URLPREFIX%
+    IF ERRORLEVEL 0 %VIEWER% %OUTFILE%
+    {noformat}</p>
+<div class="codehilite"><pre><span class="n">Another</span> <span class="n">example</span> <span class="n">how</span> <span class="n">to</span> <span class="n">get</span> <span class="n">a</span> <span class="n">document</span> <span class="n">with</span> <span class="n">id</span> <span class="n">MyDocument:</span>
+
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="nv">%CURL%</span> <span class="err">\--</span><span class="nv">user</span> <span class="nv">%USER%:%PWD%</span> <span class="err">\--</span><span class="nv">dump</span><span class="o">-</span><span class="n">header</span> <span class="n">header</span><span class="o">.</span><span class="n">txt</span> <span class="o">\--</span><span class="n">output</span> <span class="nv">%OUTFILE%</span>
+</pre></div>
+
+
+<p>%URLPREFIX%/A1/entry?id=%%2FMyDocument
+    {noformat}</p>
+<div class="codehilite"><pre><span class="n">You</span> <span class="n">also</span> <span class="n">can</span> <span class="k">use</span> <span class="n">this</span> <span class="n">to</span> <span class="n">create</span> <span class="n">documents:</span>
+
+<span class="p">{</span><span class="n">noformat</span><span class="p">}</span>
+<span class="nv">%CURL%</span> <span class="err">\--</span><span class="nv">user</span> <span class="nv">%USER%:%PWD%</span> <span class="err">\--</span><span class="nv">header</span> <span class="err">&quot;</span><span class="n">Content</span><span class="o">-</span><span class="n">Type:</span>
+</pre></div>
+
+
+<p>application/atom+xml;type=entry" -d @post-item.xml --output
+%OUTFILE%&nbsp; --url %URLPREFIX%/A1/children?id=/
+    {noformat}</p>
+<div class="codehilite"><pre>The file {{post-item.xml}} must contain a valid Atom entry then:
+
+{code:xml title=post-item.xml|borderStyle=solid}
+<span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
+<span class="nt">&lt;entry</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/2005/Atom&quot;</span>
+    <span class="na">xmlns:cmis=</span><span class="s">&quot;http://docs.oasis-open.org/ns/cmis/core/200908/&quot;</span>
+    <span class="na">xmlns:cmisra=</span><span class="s">&quot;http://docs.oasis-open.org/ns/cmis/restatom/200908/&quot;</span>
+    <span class="na">xmlns:app=</span><span class="s">&quot;http://www.w3.org/2007/app&quot;</span><span class="nt">&gt;</span>
+  <span class="nt">&lt;id&gt;</span>http://vmelcmis1:8080/cmis/atom/cd-library/main/Default-I10915<span class="nt">&lt;/id&gt;</span>
+  <span class="nt">&lt;author&gt;</span>
+    <span class="nt">&lt;name&gt;</span>Admin<span class="nt">&lt;/name&gt;</span>
+  <span class="nt">&lt;/author&gt;</span>
+  <span class="nt">&lt;updated&gt;</span>2009-03-01T00:00:00.000Z<span class="nt">&lt;/updated&gt;</span>
+  <span class="nt">&lt;title</span> <span class="na">type=</span><span class="s">&quot;text&quot;</span><span class="nt">&gt;</span>Content from Curl<span class="nt">&lt;/title&gt;</span>
+  <span class="nt">&lt;cmisra:object&gt;</span>
+    <span class="nt">&lt;cmis:properties&gt;</span>
+      <span class="nt">&lt;cmis:propertyId</span> <span class="na">propertyDefinitionId=</span><span class="s">&quot;cmis:name&quot;</span><span class="nt">&gt;</span>
+    <span class="nt">&lt;cmis:value&gt;</span>Content from Curl<span class="nt">&lt;/cmis:value&gt;</span>
+      <span class="nt">&lt;/cmis:propertyId&gt;</span>
+      <span class="nt">&lt;cmis:propertyId</span> <span class="na">propertyDefinitionId=</span><span class="s">&quot;cmis:objectTypeId&quot;</span><span class="nt">&gt;</span>
+    <span class="nt">&lt;cmis:value&gt;</span>cmis:document<span class="nt">&lt;/cmis:value&gt;</span>
+      <span class="nt">&lt;/cmis:propertyId&gt;</span>
+    <span class="nt">&lt;/cmis:properties&gt;</span>
+  <span class="nt">&lt;/cmisra:object&gt;</span>
+
+  <span class="nt">&lt;cmisra:content</span> <span class="na">type=</span><span class="s">&quot;text/plain&quot;</span><span class="nt">&gt;</span>
+  <span class="nt">&lt;cmisra:base64&gt;</span>
+RmF1c3Q6DQoNCk1laW4gc2No9m5lcyBGcuR1bGVpbiwgZGFyZiBpY2ggd2FnZW4sDQpNZWlu
+ZW4gQXJtIHVuZCBHZWxlaXQgSWhyIGFuenV0cmFnZW4/DQoNCk1hcmdhcmV0ZToNCg0KQmlu
+IHdlZGVyIEZy5HVsZWluLCB3ZWRlciBzY2j2biwNCkthbm4gdW5nZWxlaXRldCBuYWNoIEhh
+dXNlIGdlaG4uDQoNCihTaWUgbWFjaHQgc2ljaCBsb3MgdW5kIGFiLikNCg0KRmF1c3Q6DQoN
+CkJlaW0gSGltbWVsLCBkaWVzZXMgS2luZCBpc3Qgc2No9m4hDQpTbyBldHdhcyBoYWIgaWNo
+IG5pZSBnZXNlaG4uDQpTaWUgaXN0IHNvIHNpdHQtIHVuZCB0dWdlbmRyZWljaCwNClVuZCBl
+dHdhcyBzY2huaXBwaXNjaCBkb2NoIHp1Z2xlaWNoLg0KRGVyIExpcHBlIFJvdCwgZGVyIFdh
+bmdlIExpY2h0LA0KRGllIFRhZ2UgZGVyIFdlbHQgdmVyZ2XfIGljaCdzIG5pY2h0IQ0KV2ll
+IHNpZSBkaWUgQXVnZW4gbmllZGVyc2NobORndCwNCkhhdCB0aWVmIHNpY2ggaW4gbWVpbiBI
+ZXJ6IGdlcHLkZ3Q7DQpXaWUgc2llIGt1cnogYW5nZWJ1bmRlbiB3YXIsDQpEYXMgaXN0IG51
+biB6dW0gRW50evxja2VuIGdhciE=
+  <span class="nt">&lt;/cmisra:base64&gt;</span>
+  <span class="nt">&lt;/cmisra:content&gt;</span>
+<span class="nt">&lt;/entry&gt;</span>
+</pre></div></div>
              <!-- Content -->
            </td>
           </tr>



Mime
View raw message