Added: websites/staging/chemistry/trunk/content/java/how-to-build-a-server.html ============================================================================== --- websites/staging/chemistry/trunk/content/java/how-to-build-a-server.html (added) +++ websites/staging/chemistry/trunk/content/java/how-to-build-a-server.html Mon Feb 21 14:22:49 2011 @@ -0,0 +1,771 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<html> + <head> + <link type="text/css" rel="stylesheet" href="/resources/site.css"></link> + <script src="/resources/space.js" type="text/javascript"></script> + <meta name="keywords" content="CMIS, Content Management Interoperability Service, ECM, Enterprise Content Management, OASIS, integration standards, Chemistry, OpenCMIS"/> + <meta name="description" content="Apache Chemistry, CMIS Implementation" /> + <title> +Apache Chemistry - How To Build A Server + </title> + </head> +<body onload="init()"> + <table width="100%" cellpadding="0" cellspacing="0"> + <tr width="100%"> + <td id="cell-0-0"> </td> + <td id="cell-0-1"> </td> + <td id="cell-0-2"> </td> + </tr> + <tr width="100%"> + <td id="cell-1-0"> </td> + <td id="cell-1-1"> + <div style="padding: 5px;"> + <div id="banner"> + <!-- Banner --> +<TABLE border="0" cellpadding="0" cellspacing="0" width="100%"> +<TR> +<TD align="left" class="topbardiv" nowrap=""> + <A href="http://chemistry.apache.org/" title="Apache Chemistry"> + <IMG border="0" src="/images/chemistry_tm_logo_small.png"/> + </A> +</TD> +<TD align="right" nowrap=""> + <A href="http://www.apache.org/" title="The Apache Software Foundation"> + <IMG border="0" src="/images/asf-logo.png"/> + </A> +</TD> +</TR> +</TABLE> + <!-- Banner --> + </div> + </div> + <div id="top-menu"> + <table border="0" cellpadding="1" cellspacing="0" width="100%"> + <tr> + <td> + <div align="left"> + <!-- Breadcrumbs --> +<a href="/">Home</a> » <a href="/java">Java</a> » <a href="/java/opencmis.html">OpenCMIS</a> » <a href="/java/how-to-build-a-server.html">How To Build A Server</a> + <!-- Breadcrumbs --> + </div> + </td> + <td> + <div align="right"> + <!-- Quicklinks --> +<P> +<A href="http://www.apache.org/" class="external-link" rel="nofollow">Apache</A> +| +<A href="http://www.apache.org/licenses/LICENSE-2.0.html" class="external-link" rel="nofollow">License</A> +| +<A href="sitemap.html" title="SiteMap">Site Map</A> +</P> + <!-- Quicklinks --> + </div> + </td> + </tr> + </table> + </div> + </td> + <td id="cell-1-2"> </td> + </tr> + <tr width="100%"> + <td id="cell-2-0"> </td> + <td id="cell-2-1"> + <table> + <tr height="100%" valign="top"> + <td height="100%"> + <div id="wrapper-menu-page-right"> + <div id="wrapper-menu-page-top"> + <div id="wrapper-menu-page-bottom"> + <div id="menu-page"> + <!-- NavigationBar --> + <H3><A name="Navigation-Overview"></A>Overview</H3> + +<UL class="alternate" type="square"> + <LI><A href="http://www.apache.org/licenses/LICENSE-2.0.html" class="external-link" rel="nofollow">License</A></LI> + <LI><A href="sitemap.html" title="SiteMap">Site Map</A></LI> + <LI><A href="http://mail-archives.apache.org/mod_mbox/incubator-chemistry-dev/" class="external-link" rel="nofollow">Mailing List</A></LI> + <LI><A href="https://issues.apache.org/jira/browse/CMIS" class="external-link" rel="nofollow">Issue Tracking</A></LI> +</UL> + + +<H3><A name="Navigation-Search"></A>Search</H3> + +<DIV style="padding: 0px 0px 0px 20px;"> +<FORM action="http://www.google.com/search" method="get" style="font-size: 10px;"> +<INPUT name="ie" type="hidden" value="UTF-8"></INPUT> +<INPUT name="oe" type="hidden" value="UTF-8"></INPUT> + <INPUT maxlength="255" name="q" size="12" type="text" value=""></INPUT> + <INPUT name="btnG" type="submit" value="Search"></INPUT> + <INPUT name="domains" type="hidden" value="incubator.apache.org/chemistry"></INPUT> + <INPUT name="sitesearch" type="hidden" value="incubator.apache.org/chemistry"></INPUT> +</FORM> +</DIV> + + +<H3><A name="Navigation-CMISforJava"></A>CMIS for Java</H3> + +<UL class="alternate" type="square"> + <LI><A href="opencmis.html" title="OpenCMIS">OpenCMIS</A></LI> + <LI><A href="opencmis-modules.html" title="OpenCMIS Modules">Overview</A></LI> + <LI><A href="opencmis-client-api.html" title="OpenCMIS Client API">Client API</A></LI> + <LI><A href="https://svn.apache.org/repos/asf/chemistry/opencmis/trunk" class="external-link" rel="nofollow">Source Code</A></LI> + <LI><A href="http://incubator.apache.org/chemistry/javadoc/index.html" class="external-link" rel="nofollow">JavaDoc</A></LI> +</UL> + + +<H3><A name="Navigation-CMISforPython"></A>CMIS for Python</H3> + +<UL class="alternate" type="square"> + <LI><A href="cmislib.html" title="cmislib">cmislib</A></LI> + <LI><A href="http://incubator.apache.org/chemistry/cmislib-doc/" class="external-link" rel="nofollow">cmislib Documentation</A></LI> + <LI><A href="https://svn.apache.org/repos/asf/chemistry/cmislib/trunk" class="external-link" rel="nofollow">Source Code</A></LI> +</UL> + + +<H3><A name="Navigation-CMISforPHP"></A>CMIS for PHP</H3> + +<UL class="alternate" type="square"> + <LI><A href="phpclient.html" title="phpclient">CMIS PHP Client</A></LI> + <LI><A href="https://svn.apache.org/repos/asf/chemistry/phpclient/trunk" class="external-link" rel="nofollow">Source Code</A></LI> +</UL> + + +<H3><A name="Navigation-CMISfor.NET"></A>CMIS for .NET</H3> + +<UL class="alternate" type="square"> + <LI><A href="dotcmis.html" title="DotCMIS">DotCMIS</A></LI> + <LI><A href="https://svn.apache.org/repos/asf/chemistry/dotcmis/trunk" class="external-link" rel="nofollow">Source Code</A></LI> +</UL> + + +<H3><A name="Navigation-Sponsorship"></A>Sponsorship</H3> + +<UL class="alternate" type="square"> + <LI><A href="http://www.apache.org/foundation/thanks.html" class="external-link" rel="nofollow">Thanks</A></LI> + <LI><A href="http://www.apache.org/foundation/sponsorship.html" class="external-link" rel="nofollow">Sponsoring Apache</A></LI> +</UL> + + <!-- NavigationBar --> + </div> + </div> + </div> + </div> + </td> + <td height="100%"> + <!-- Content --> + <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> +<h2 id="getting_started">Getting started:</h2> +<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> +<h3 id="using_maven">Using maven</h3> +<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 (<code>mvn +install</code>). 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="sb">`web.xml`</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 <code>mvn eclipse:eclipse</code> to generate the required <code>.projects</code> and +<code>.classpath</code> files for Eclipse that you just need to import in your +Eclipse workspace.</p> +<h3 id="without_maven">Without maven</h3> +<div class="codehilite"><pre><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="n">mvn</span> <span class="nb">package</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="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="n">Unzip</span> <span class="n">the</span> <span class="n">file</span> +</pre></div> + + +<p><code>chemistry-opencmis-server-bindings-0.1-incubating-SNAPSHOT.jar</code> 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="n">mvn</span> <span class="n">jar:jar</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="sb">`opencmis-server-impl-0.1-SNAPSHOT.jar`</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 +<code>.war</code> and the one created in the previous step to your project setup. +Add the <code>repository.properties</code> 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="sb">`web.xml`</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> +<h2 id="implementing_the_services">Implementing the services</h2> +<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="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">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="sb">`AbstractServiceFactory`</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="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">parameters</span><span class="o">)</span> <span class="o">{</span> +<span class="o">}</span> + +<span class="kd">public</span> <span class="kt">void</span> <span class="nf">destroy</span><span class="o">()</span> <span class="o">{</span> +<span class="o">}</span> + +<span class="kd">public</span> <span class="kd">abstract</span> <span class="n">CmisService</span> <span class="nf">getService</span><span class="o">(</span><span class="n">CallContext</span> <span class="n">context</span><span class="o">);</span> +</pre></div> + + +<p>The <code>init()</code> method is used to perform initialization and passes a set of +configuration parameters from repository.properties:</p> +<div class="codehilite"><pre><span class="nd">@Override</span> +<span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">parameters</span><span class="o">)</span> <span class="o">{</span> +<span class="o">}</span> + +<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="n">next</span> <span class="n">section</span><span class="o">.</span> + +<span class="n">The</span> <span class="n">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 <code>CmisService</code> 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="kd">public</span> <span class="kd">class</span> <span class="nc">MyCmisServiceImpl</span> <span class="kd">extends</span> <span class="n">AbstractCmisService</span> <span class="o">{</span> + + <span class="kd">public</span> <span class="n">RepositoryInfo</span> <span class="nf">getRepositoryInfo</span><span class="o">(</span><span class="n">CallContext</span> <span class="n">context</span><span class="o">,</span> + <span class="n">String</span> <span class="n">repositoryId</span><span class="o">,</span> <span class="n">ExtensionsData</span> <span class="n">extension</span><span class="o">)</span> <span class="o">{</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="o">();</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setRepositoryId</span><span class="o">(</span><span class="n">repositoryId</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setRepositoryName</span><span class="o">(</span><span class="s">"My CMIS Repository"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setRepositoryDescription</span><span class="o">(</span><span class="s">"Sample Repository"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setCmisVersionSupported</span><span class="o">(</span><span class="s">"1.0"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setRepositoryCapabilities</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setRootFolder</span><span class="o">(</span><span class="s">"MyRootFolderId"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setPrincipalAnonymous</span><span class="o">(</span><span class="s">"anonymous"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setPrincipalAnyone</span><span class="o">(</span><span class="s">"anyone"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setThinClientUri</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setChangesIncomplete</span><span class="o">(</span><span class="n">Boolean</span><span class="o">.</span><span class="na">TRUE</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setChangesOnType</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setLatestChangeLogToken</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setVendorName</span><span class="o">(</span><span class="s">"ACME"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setProductName</span><span class="o">(</span><span class="s">"ACME CMIS Connector"</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setProductVersion</span><span class="o">(</span><span class="s">"0.1"</span><span class="o">);</span> + + <span class="c1">// set 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="o">();</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setAllVersionsSearchable</span><span class="o">(</span><span class="kc">false</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setCapabilityAcl</span><span class="o">(</span><span class="n">CapabilityAcl</span><span class="o">.</span><span class="na">NONE</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setCapabilityChanges</span><span class="o">(</span><span class="n">CapabilityChanges</span><span class="o">.</span><span class="na">PROPERTIES</span><span class="o">);</span> + + <span class="n">caps</span><span class="o">.</span><span class="na">setCapabilityContentStreamUpdates</span><span class="o">(</span> + <span class="n">CapabilityContentStreamUpdates</span><span class="o">.</span><span class="na">PWCONLY</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setCapabilityJoin</span><span class="o">(</span><span class="n">CapabilityJoin</span><span class="o">.</span><span class="na">NONE</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setCapabilityQuery</span><span class="o">(</span><span class="n">CapabilityQuery</span><span class="o">.</span><span class="na">METADATAONLY</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setCapabilityRendition</span><span class="o">(</span><span class="n">CapabilityRenditions</span><span class="o">.</span><span class="na">NONE</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setIsPwcSearchable</span><span class="o">(</span><span class="kc">false</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setIsPwcUpdatable</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setSupportsGetDescendants</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setSupportsGetFolderTree</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setSupportsMultifiling</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setSupportsUnfiling</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> + <span class="n">caps</span><span class="o">.</span><span class="na">setSupportsVersionSpecificFiling</span><span class="o">(</span><span class="kc">false</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setRepositoryCapabilities</span><span class="o">(</span><span class="n">caps</span><span class="o">);</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="o">();</span> + <span class="n">aclCaps</span><span class="o">.</span><span class="na">setAclPropagation</span><span class="o">(</span><span class="n">AclPropagation</span><span class="o">.</span><span class="na">REPOSITORYDETERMINED</span><span class="o">);</span> + <span class="n">aclCaps</span><span class="o">.</span><span class="na">setPermissionDefinitionData</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> + <span class="n">aclCaps</span><span class="o">.</span><span class="na">setPermissionMappingData</span><span class="o">(</span><span class="kc">null</span><span class="o">);</span> + <span class="n">repoInfo</span><span class="o">.</span><span class="na">setAclCapabilities</span><span class="o">(</span><span class="n">aclCaps</span><span class="o">);</span> + <span class="k">return</span> <span class="n">repoInfo</span><span class="o">;</span> + <span class="o">}</span> + <span class="c1">// ...</span> +<span class="o">}</span> +</pre></div> + + +<p>Now you can start implementing all the required methods with their methods.</p> +<p><a name="HowToBuildAServer-TheServiceWrapper"></a></p> +<h3 id="the_servicewrapper">The ServiceWrapper</h3> +<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> +<h2 id="differences_between_the_cmis_bindings">Differences between the CMIS bindings</h2> +<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> +<h3 id="the_objectinfo_interface">The ObjectInfo interface</h3> +<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> +<h3 id="the_create_methods">The create() methods</h3> +<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> +<h3 id="applying_acls">Applying ACLs</h3> +<p>The class CmisAclService has two methods <em>applyAcl()</em>. One uses two +AccessControlLists with one Acl to add 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> +<h2 id="running_the_server">Running The Server</h2> +<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 web.xml, the wsdl files in +<code>WEB-INF</code> and all the required jars from opencmis and dependent libraries +in <code>WEB-INF/lib</code>. For jetty maven contains a build-in integration that +you may use if you like using <code>mvn jetty:run</code>. Adjust your pom.xml in +this case accordingly.</p> +<p>Deploy your application and start testing.</p> +<p><a name="HowToBuildAServer-HandlingAuthentication"></a></p> +<h2 id="handling_authentication">Handling Authentication</h2> +<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, 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> +<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyContextHandler</span> + <span class="kd">extends</span> <span class="n">BasicAuthCallContextHandler</span> +<span class="o">{</span> + <span class="kd">public</span> <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">getCallContextMap</span><span class="o">(</span><span class="n">HttpServletRequest</span> <span class="n">request</span><span class="o">){</span> + + <span class="c1">// call superclass to get user and password via basic authentication</span> + <span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="o">,</span> <span class="n">String</span><span class="o">></span> <span class="n">ctxMap</span> <span class="o">=</span> <span class="kd">super</span><span class="o">.</span><span class="na">getCallContextMap</span><span class="o">(</span><span class="n">request</span><span class="o">);</span> + + <span class="k">if</span> <span class="o">(</span><span class="kc">null</span> <span class="o">==</span> <span class="n">ctxMap</span><span class="o">)</span> + <span class="c1">// no user name, password given yet say: we need authentication:</span> + <span class="k">throw</span> <span class="k">new</span> <span class="nf">CmisPermissionDeniedException</span><span class="o">(</span><span class="s">"Authentication required"</span><span class="o">);</span> + + <span class="c1">// call your authentication</span> + + <span class="n">MyAuthentication</span><span class="o">.</span><span class="na">login</span><span class="o">(</span> + <span class="n">ctxMap</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">CallContext</span><span class="o">.</span><span class="na">USERNAME</span><span class="o">),</span> + <span class="n">ctxMap</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">CallContext</span><span class="o">.</span><span class="na">PASSWORD</span><span class="o">));</span> + + <span class="k">return</span> <span class="n">ctxMap</span><span class="o">;</span> + <span class="o">}</span> +<span class="o">}</span> + +<span class="n">Beyond</span> <span class="k">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> +<h2 id="configuring_your_server">Configuring your server</h2> +<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 <code>init()</code> 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> +<h2 id="testing_the_server">Testing the server</h2> +<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> +<p>Examples:</p> +<p>Test class:</p> +<div class="codehilite"><pre><span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">chemistry</span><span class="o">.</span><span class="n">opencmis</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">bindings</span><span class="o">.</span><span class="n">atompub</span><span class="o">.</span><span class="n">SimpleReadOnlyTests</span> +</pre></div> + + +<p>Test Parameters (passed as JVM args):</p> +<div class="codehilite"><pre><span class="o">-</span><span class="n">Dopencmis</span><span class="o">.</span><span class="n">test</span><span class="o">=</span><span class="n">true</span> +<span class="o">-</span><span class="n">Dopencmis</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">username</span><span class="o">=</span><span class="n">myuser</span> +<span class="o">-</span><span class="n">Dopencmis</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">password</span><span class="o">=</span><span class="n">mypasswd</span> +<span class="o">-</span><span class="n">Dopencmis</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">repository</span><span class="o">=</span><span class="n">my_repository_id</span><span class="o">&</span><span class="n">nbsp</span><span class="p">;</span> +<span class="o">-</span><span class="n">Dopencmis</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">atompub</span><span class="o">.</span><span class="n">url</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> +</pre></div> + + +<p>The following test classes exist:</p> +<div class="codehilite"><pre><span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">opencmis</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">bindings</span><span class="o">.</span><span class="n">atompub</span><span class="o">.</span><span class="n">SimpleReadOnlyTests</span> +<span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">opencmis</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">bindings</span><span class="o">.</span><span class="n">atompub</span><span class="o">.</span><span class="n">SimpleReadWriteTests</span> +<span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">opencmis</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">bindings</span><span class="o">.</span><span class="n">webservices</span><span class="o">.</span><span class="n">SimpleReadOnlyTests</span> +<span class="n">org</span><span class="o">.</span><span class="n">apache</span><span class="o">.</span><span class="n">opencmis</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">bindings</span><span class="o">.</span><span class="n">webservices</span><span class="o">.</span><span class="n">SimpleReadWriteTests</span> +</pre></div> + + +<p>For web services you need an additional parameter for the service endpoint:</p> +<div class="codehilite"><pre><span class="o">-</span><span class="n">Dopencmis</span><span class="o">.</span><span class="n">test</span><span class="o">.</span><span class="n">webservices</span><span class="o">.</span><span class="n">url</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/s</span><span class="n">ervices</span><span class="o">/</span><span class="p">]</span> +</pre></div> + + +<h3 id="test_using_curl">Test using curl</h3> +<p>Simple tests (which might be useful at the beginning) can also be done +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="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">"C:\Program Files\Mozilla Firefox\firefox.exe"</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> <span class="err">%</span><span class="nv">URLPREFIX%</span> +<span class="nv">IF</span> <span class="n">ERRORLEVEL</span> <span class="mi">0</span> <span class="nv">%VIEWER%</span> <span class="err">%</span><span class="nv">OUTFILE%</span> +</pre></div> + + +<p>Another example how to get a document with id MyDocument:</p> +<div class="codehilite"><pre><span class="c">%CURL% \--user %USER%:%PWD% \--dump-header header.txt \--output %OUTFILE% %URLPREFIX%/A1/entry?id=%%2FMyDocument</span> +</pre></div> + + +<p>You also can use this to create documents:</p> +<div class="codehilite"><pre><span class="c">%CURL% \--user %USER%:%PWD% \--header "Content-Type: application/atom+xml;type=entry" \-d @post-item.xml \--output %OUTFILE%&nbsp; \--url %URLPREFIX%/A1/children?id=/</span> +</pre></div> + + +<p>The file <code>post-item.xml</code> must contain a valid Atom entry then:</p> +<div class="codehilite"><pre><span class="cp"><?xml version="1.0" encoding="utf-8"?></span> +<span class="nt"><entry</span> <span class="na">xmlns=</span><span class="s">"http://www.w3.org/2005/Atom"</span> + <span class="na">xmlns:cmis=</span><span class="s">"http://docs.oasis-open.org/ns/cmis/core/200908/"</span> + <span class="na">xmlns:cmisra=</span><span class="s">"http://docs.oasis-open.org/ns/cmis/restatom/200908/"</span> + <span class="na">xmlns:app=</span><span class="s">"http://www.w3.org/2007/app"</span><span class="nt">></span> + <span class="nt"><id></span>http://vmelcmis1:8080/cmis/atom/cd-library/main/Default-I10915<span class="nt"></id></span> + <span class="nt"><author></span> + <span class="nt"><name></span>Admin<span class="nt"></name></span> + <span class="nt"></author></span> + <span class="nt"><updated></span>2009-03-01T00:00:00.000Z<span class="nt"></updated></span> + <span class="nt"><title</span> <span class="na">type=</span><span class="s">"text"</span><span class="nt">></span>Content from Curl<span class="nt"></title></span> + <span class="nt"><cmisra:object></span> + <span class="nt"><cmis:properties></span> + <span class="nt"><cmis:propertyId</span> <span class="na">propertyDefinitionId=</span><span class="s">"cmis:name"</span><span class="nt">></span> + <span class="nt"><cmis:value></span>Content from Curl<span class="nt"></cmis:value></span> + <span class="nt"></cmis:propertyId></span> + <span class="nt"><cmis:propertyId</span> <span class="na">propertyDefinitionId=</span><span class="s">"cmis:objectTypeId"</span><span class="nt">></span> + <span class="nt"><cmis:value></span>cmis:document<span class="nt"></cmis:value></span> + <span class="nt"></cmis:propertyId></span> + <span class="nt"></cmis:properties></span> + <span class="nt"></cmisra:object></span> + + <span class="nt"><cmisra:content</span> <span class="na">type=</span><span class="s">"text/plain"</span><span class="nt">></span> + <span class="nt"><cmisra:base64></span> +RmF1c3Q6DQoNCk1laW4gc2No9m5lcyBGcuR1bGVpbiwgZGFyZiBpY2ggd2FnZW4sDQpNZWlu +ZW4gQXJtIHVuZCBHZWxlaXQgSWhyIGFuenV0cmFnZW4/DQoNCk1hcmdhcmV0ZToNCg0KQmlu +IHdlZGVyIEZy5HVsZWluLCB3ZWRlciBzY2j2biwNCkthbm4gdW5nZWxlaXRldCBuYWNoIEhh +dXNlIGdlaG4uDQoNCihTaWUgbWFjaHQgc2ljaCBsb3MgdW5kIGFiLikNCg0KRmF1c3Q6DQoN +CkJlaW0gSGltbWVsLCBkaWVzZXMgS2luZCBpc3Qgc2No9m4hDQpTbyBldHdhcyBoYWIgaWNo +IG5pZSBnZXNlaG4uDQpTaWUgaXN0IHNvIHNpdHQtIHVuZCB0dWdlbmRyZWljaCwNClVuZCBl +dHdhcyBzY2huaXBwaXNjaCBkb2NoIHp1Z2xlaWNoLg0KRGVyIExpcHBlIFJvdCwgZGVyIFdh +bmdlIExpY2h0LA0KRGllIFRhZ2UgZGVyIFdlbHQgdmVyZ2XfIGljaCdzIG5pY2h0IQ0KV2ll +IHNpZSBkaWUgQXVnZW4gbmllZGVyc2NobORndCwNCkhhdCB0aWVmIHNpY2ggaW4gbWVpbiBI +ZXJ6IGdlcHLkZ3Q7DQpXaWUgc2llIGt1cnogYW5nZWJ1bmRlbiB3YXIsDQpEYXMgaXN0IG51 +biB6dW0gRW50evxja2VuIGdhciE= + <span class="nt"></cmisra:base64></span> + <span class="nt"></cmisra:content></span> +<span class="nt"></entry></span> +</pre></div></div> + <!-- Content --> + </td> + </tr> + </table> + </td> + <td id="cell-2-2"> </td> + </tr> + <tr width="100%"> + <td id="cell-3-0"> </td> + <td id="cell-3-1"> </td> + <td id="cell-3-2"> </td> + </tr> + <tr width="100%"> + <td id="cell-3-0"> </td> + <td id="cell-3-1"> + <div id="footer"> + <!-- Footer --> + <div id="site-footer"> + + Apache Chemistry, Apache, the Apache feather logo, and the Apache + Chemistry project logo are trademarks of The Apache Software + Foundation. + <BR /> + Content Management Interoperability Services (CMIS) is an + <a href="http://www.oasis-open.org/committees/cmis/">OASIS</a> + specification. + + </div> + <!-- Footer --> + </div> + </td> + <td id="cell-3-2"> </td> + </tr> + <tr width="100%"> + <td id="cell-4-0"> </td> + <td id="cell-4-1"> </td> + <td id="cell-4-2"> </td> + </tr> + </table> +</body> +</html>
