You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2013/05/11 23:19:48 UTC

svn commit: r1481420 [3/7] - in /chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src: main/java/org/apache/chemistry/opencmis/server/impl/ main/java/org/apache/chemistry/opencmis/server/impl/atompub/ main/java/org/...

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java?rev=1481420&r1=1481419&r2=1481420&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/ObjectService.java Sat May 11 21:19:48 2013
@@ -18,21 +18,8 @@
  */
 package org.apache.chemistry.opencmis.server.impl.atompub;
 
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_BULK_UPDATE;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_CONTENT;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_ENTRY;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileBaseUrl;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrl;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrlBuilder;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.getNamespaces;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.writeObjectEntry;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
-
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
@@ -76,575 +63,586 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
 import org.apache.chemistry.opencmis.commons.spi.Holder;
-import org.apache.chemistry.opencmis.server.shared.HttpUtils;
 import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
 
 /**
  * Object Service operations.
  */
-public final class ObjectService {
+public class ObjectService {
 
     private static final int BUFFER_SIZE = 64 * 1024;
 
-    private ObjectService() {
-    }
-
     /**
      * Create.
      */
-    public static void create(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String folderId = getStringParameter(request, Constants.PARAM_ID);
-        String sourceFolderId = getStringParameter(request, Constants.PARAM_SOURCE_FOLDER_ID);
-        VersioningState versioningState = getEnumParameter(request, Constants.PARAM_VERSIONIG_STATE,
-                VersioningState.class);
-
-        ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
-                .get(CallContext.STREAM_FACTORY);
-        AtomEntryParser parser = new AtomEntryParser(streamFactory);
-        parser.setIgnoreAtomContentSrc(true); // needed for some clients
-        parser.parse(request.getInputStream());
-
-        String objectId = parser.getId();
-
-        // execute
-        String newObjectId = null;
-
-        if (objectId == null) {
-            // create
-            ContentStream contentStream = parser.getContentStream();
-            try {
-                newObjectId = service.create(repositoryId, parser.getProperties(), folderId, contentStream,
-                        versioningState, parser.getPolicyIds(), null);
-            } finally {
-                closeContentStream(contentStream);
-            }
-        } else {
-            if ((sourceFolderId == null) || (sourceFolderId.trim().length() == 0)) {
-                // addObjectToFolder
-                service.addObjectToFolder(repositoryId, objectId, folderId, null, null);
-                newObjectId = objectId;
+    public static class Create extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String folderId = getStringParameter(request, Constants.PARAM_ID);
+            String sourceFolderId = getStringParameter(request, Constants.PARAM_SOURCE_FOLDER_ID);
+            VersioningState versioningState = getEnumParameter(request, Constants.PARAM_VERSIONIG_STATE,
+                    VersioningState.class);
+
+            ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
+                    .get(CallContext.STREAM_FACTORY);
+            AtomEntryParser parser = new AtomEntryParser(streamFactory);
+            parser.setIgnoreAtomContentSrc(true); // needed for some clients
+            parser.parse(request.getInputStream());
+
+            String objectId = parser.getId();
+
+            // execute
+            String newObjectId = null;
+
+            if (objectId == null) {
+                // create
+                ContentStream contentStream = parser.getContentStream();
+                try {
+                    newObjectId = service.create(repositoryId, parser.getProperties(), folderId, contentStream,
+                            versioningState, parser.getPolicyIds(), null);
+                } finally {
+                    closeContentStream(contentStream);
+                }
             } else {
-                // move
-                Holder<String> objectIdHolder = new Holder<String>(objectId);
-                service.moveObject(repositoryId, objectIdHolder, folderId, sourceFolderId, null);
-                newObjectId = objectIdHolder.getValue();
+                if ((sourceFolderId == null) || (sourceFolderId.trim().length() == 0)) {
+                    // addObjectToFolder
+                    service.addObjectToFolder(repositoryId, objectId, folderId, null, null);
+                    newObjectId = objectId;
+                } else {
+                    // move
+                    Holder<String> objectIdHolder = new Holder<String>(objectId);
+                    service.moveObject(repositoryId, objectIdHolder, folderId, sourceFolderId, null);
+                    newObjectId = objectIdHolder.getValue();
+                }
             }
-        }
 
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
-
-        ObjectData object = objectInfo.getObject();
-        if (object == null) {
-            throw new CmisRuntimeException("Object is null!");
-        }
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
 
-        // set headers
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+            ObjectData object = objectInfo.getObject();
+            if (object == null) {
+                throw new CmisRuntimeException("Object is null!");
+            }
 
-        response.setStatus(HttpServletResponse.SC_CREATED);
-        response.setContentType(Constants.MEDIATYPE_ENTRY);
-        response.setHeader("Location", compileUrl(baseUrl, RESOURCE_ENTRY, newObjectId));
+            // set headers
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
 
-        // write XML
-        AtomEntry entry = new AtomEntry();
-        entry.startDocument(response.getOutputStream(), getNamespaces(service));
-        writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
-                context.getCmisVersion());
-        entry.endDocument();
+            response.setStatus(HttpServletResponse.SC_CREATED);
+            response.setContentType(Constants.MEDIATYPE_ENTRY);
+            response.setHeader("Location", compileUrl(baseUrl, RESOURCE_ENTRY, newObjectId));
+
+            // write XML
+            AtomEntry entry = new AtomEntry();
+            entry.startDocument(response.getOutputStream(), getNamespaces(service));
+            writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
+                    context.getCmisVersion());
+            entry.endDocument();
+        }
     }
 
     /**
      * Create relationship.
      */
-    public static void createRelationship(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
-                .get(CallContext.STREAM_FACTORY);
-        AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), streamFactory);
-
-        // execute
-        String newObjectId = service.createRelationship(repositoryId, parser.getProperties(), parser.getPolicyIds(),
-                null, null, null);
-
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
-
-        ObjectData object = objectInfo.getObject();
-        if (object == null) {
-            throw new CmisRuntimeException("Object is null!");
-        }
-
-        // set headers
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-
-        response.setStatus(HttpServletResponse.SC_CREATED);
-        response.setContentType(Constants.MEDIATYPE_ENTRY);
-        response.setHeader("Location", compileUrl(baseUrl, RESOURCE_ENTRY, newObjectId));
-
-        // write XML
-        AtomEntry entry = new AtomEntry();
-        entry.startDocument(response.getOutputStream(), getNamespaces(service));
-        writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
-                context.getCmisVersion());
-        entry.endDocument();
+    public static class CreateRelationship extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
+                    .get(CallContext.STREAM_FACTORY);
+            AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), streamFactory);
+
+            // execute
+            String newObjectId = service.createRelationship(repositoryId, parser.getProperties(),
+                    parser.getPolicyIds(), null, null, null);
+
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, newObjectId);
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
+
+            ObjectData object = objectInfo.getObject();
+            if (object == null) {
+                throw new CmisRuntimeException("Object is null!");
+            }
+
+            // set headers
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+
+            response.setStatus(HttpServletResponse.SC_CREATED);
+            response.setContentType(Constants.MEDIATYPE_ENTRY);
+            response.setHeader("Location", compileUrl(baseUrl, RESOURCE_ENTRY, newObjectId));
+
+            // write XML
+            AtomEntry entry = new AtomEntry();
+            entry.startDocument(response.getOutputStream(), getNamespaces(service));
+            writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
+                    context.getCmisVersion());
+            entry.endDocument();
+        }
     }
 
     /**
      * Delete object.
      */
-    public static void deleteObject(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        Boolean allVersions = getBooleanParameter(request, Constants.PARAM_ALL_VERSIONS);
+    public static class DeleteObject extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            Boolean allVersions = getBooleanParameter(request, Constants.PARAM_ALL_VERSIONS);
 
-        // execute
-        service.deleteObjectOrCancelCheckOut(repositoryId, objectId, allVersions, null);
+            // execute
+            service.deleteObjectOrCancelCheckOut(repositoryId, objectId, allVersions, null);
 
-        // set headers
-        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+            // set headers
+            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+        }
     }
 
     /**
      * Delete content stream.
      */
-    public static void deleteContentStream(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        String changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
-
-        // execute
-        service.deleteContentStream(repositoryId, new Holder<String>(objectId), changeToken == null ? null
-                : new Holder<String>(changeToken), null);
+    public static class DeleteContentStream extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            String changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
+
+            // execute
+            service.deleteContentStream(repositoryId, new Holder<String>(objectId), changeToken == null ? null
+                    : new Holder<String>(changeToken), null);
 
-        // set headers
-        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+            // set headers
+            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+        }
     }
 
     /**
      * Set or append content stream.
      */
-    public static void setOrAppendContentStream(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        String changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
-        Boolean appendFlag = getBooleanParameter(request, Constants.PARAM_APPEND);
-        Boolean overwriteFlag = getBooleanParameter(request, Constants.PARAM_OVERWRITE_FLAG);
-        Boolean isLastChunk = getBooleanParameter(request, Constants.PARAM_IS_LAST_CHUNK);
-
-        ContentStreamImpl contentStream = new ContentStreamImpl();
-        contentStream.setStream(request.getInputStream());
-        contentStream.setMimeType(request.getHeader("Content-Type"));
-        String lengthStr = request.getHeader("Content-Length");
-        if (lengthStr != null) {
-            try {
-                contentStream.setLength(new BigInteger(lengthStr));
-            } catch (NumberFormatException e) {
-            }
-        }
-        String contentDisposition = request.getHeader(MimeHelper.CONTENT_DISPOSITION);
-        if (contentDisposition != null) {
-            contentStream.setFileName(MimeHelper.decodeContentDispositionFilename(contentDisposition));
-        }
-
-        // execute
-        Holder<String> objectIdHolder = new Holder<String>(objectId);
-        if (Boolean.TRUE.equals(appendFlag)) {
-            service.appendContentStream(repositoryId, objectIdHolder, changeToken == null ? null : new Holder<String>(
-                    changeToken), contentStream, (Boolean.TRUE.equals(isLastChunk) ? true : false), null);
-        } else {
-            service.setContentStream(repositoryId, objectIdHolder, overwriteFlag, changeToken == null ? null
-                    : new Holder<String>(changeToken), contentStream, null);
-        }
-
-        // set headers
-        String newObjectId = (objectIdHolder.getValue() == null ? objectId : objectIdHolder.getValue());
-        String location = compileUrl(compileBaseUrl(request, repositoryId), RESOURCE_CONTENT, newObjectId);
-
-        response.setStatus(HttpServletResponse.SC_CREATED);
-        response.setHeader("Content-Location", location);
-        response.setHeader("Location", location);
+    public static class SetOrAppendContentStream extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            String changeToken = getStringParameter(request, Constants.PARAM_CHANGE_TOKEN);
+            Boolean appendFlag = getBooleanParameter(request, Constants.PARAM_APPEND);
+            Boolean overwriteFlag = getBooleanParameter(request, Constants.PARAM_OVERWRITE_FLAG);
+            Boolean isLastChunk = getBooleanParameter(request, Constants.PARAM_IS_LAST_CHUNK);
+
+            ContentStreamImpl contentStream = new ContentStreamImpl();
+            contentStream.setStream(request.getInputStream());
+            contentStream.setMimeType(request.getHeader("Content-Type"));
+            String lengthStr = request.getHeader("Content-Length");
+            if (lengthStr != null) {
+                try {
+                    contentStream.setLength(new BigInteger(lengthStr));
+                } catch (NumberFormatException e) {
+                }
+            }
+            String contentDisposition = request.getHeader(MimeHelper.CONTENT_DISPOSITION);
+            if (contentDisposition != null) {
+                contentStream.setFileName(MimeHelper.decodeContentDispositionFilename(contentDisposition));
+            }
+
+            // execute
+            Holder<String> objectIdHolder = new Holder<String>(objectId);
+            if (Boolean.TRUE.equals(appendFlag)) {
+                service.appendContentStream(repositoryId, objectIdHolder, changeToken == null ? null
+                        : new Holder<String>(changeToken), contentStream, (Boolean.TRUE.equals(isLastChunk) ? true
+                        : false), null);
+            } else {
+                service.setContentStream(repositoryId, objectIdHolder, overwriteFlag, changeToken == null ? null
+                        : new Holder<String>(changeToken), contentStream, null);
+            }
+
+            // set headers
+            String newObjectId = (objectIdHolder.getValue() == null ? objectId : objectIdHolder.getValue());
+            String location = compileUrl(compileBaseUrl(request, repositoryId), RESOURCE_CONTENT, newObjectId);
+
+            response.setStatus(HttpServletResponse.SC_CREATED);
+            response.setHeader("Content-Location", location);
+            response.setHeader("Location", location);
+        }
     }
 
     /**
      * Delete tree.
      */
-    public static void deleteTree(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String folderId = getStringParameter(request, Constants.PARAM_ID);
-        Boolean allVersions = getBooleanParameter(request, Constants.PARAM_ALL_VERSIONS);
-        UnfileObject unfileObjects = getEnumParameter(request, Constants.PARAM_UNFILE_OBJECTS, UnfileObject.class);
-        Boolean continueOnFailure = getBooleanParameter(request, Constants.PARAM_CONTINUE_ON_FAILURE);
-
-        // execute
-        FailedToDeleteData ftd = service.deleteTree(repositoryId, folderId, allVersions, unfileObjects,
-                continueOnFailure, null);
-
-        if ((ftd != null) && (ftd.getIds() != null) && (ftd.getIds().size() > 0)) {
-            // print ids that could not be deleted
-            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-            response.setContentType("text/plain");
+    public static class DeleteTree extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String folderId = getStringParameter(request, Constants.PARAM_ID);
+            Boolean allVersions = getBooleanParameter(request, Constants.PARAM_ALL_VERSIONS);
+            UnfileObject unfileObjects = getEnumParameter(request, Constants.PARAM_UNFILE_OBJECTS, UnfileObject.class);
+            Boolean continueOnFailure = getBooleanParameter(request, Constants.PARAM_CONTINUE_ON_FAILURE);
+
+            // execute
+            FailedToDeleteData ftd = service.deleteTree(repositoryId, folderId, allVersions, unfileObjects,
+                    continueOnFailure, null);
+
+            if ((ftd != null) && (ftd.getIds() != null) && (ftd.getIds().size() > 0)) {
+                // print ids that could not be deleted
+                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+                response.setContentType("text/plain");
+
+                PrintWriter pw = response.getWriter();
+
+                pw.println("Failed to delete the following objects:");
+                for (String id : ftd.getIds()) {
+                    pw.println(id);
+                }
 
-            PrintWriter pw = response.getWriter();
+                pw.flush();
 
-            pw.println("Failed to delete the following objects:");
-            for (String id : ftd.getIds()) {
-                pw.println(id);
+                return;
             }
 
-            pw.flush();
-
-            return;
+            // set headers
+            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
         }
-
-        // set headers
-        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
     }
 
     /**
      * getObject.
      */
-    public static void getObject(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        ReturnVersion returnVersion = getEnumParameter(request, Constants.PARAM_RETURN_VERSION, ReturnVersion.class);
-        String filter = getStringParameter(request, Constants.PARAM_FILTER);
-        Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
-        IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
-                IncludeRelationships.class);
-        String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
-        Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
-        Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
-
-        // execute
-        ObjectData object = null;
-
-        if ((returnVersion == ReturnVersion.LATEST) || (returnVersion == ReturnVersion.LASTESTMAJOR)) {
-            object = service.getObjectOfLatestVersion(repositoryId, objectId, null,
-                    returnVersion == ReturnVersion.LASTESTMAJOR, filter, includeAllowableActions, includeRelationships,
-                    renditionFilter, includePolicyIds, includeAcl, null);
-        } else {
-            object = service.getObject(repositoryId, objectId, filter, includeAllowableActions, includeRelationships,
-                    renditionFilter, includePolicyIds, includeAcl, null);
-        }
-
-        if (object == null) {
-            throw new CmisRuntimeException("Object is null!");
-        }
-
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
-
-        // set headers
-        response.setStatus(HttpServletResponse.SC_OK);
-        response.setContentType(Constants.MEDIATYPE_ENTRY);
-
-        // write XML
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-
-        AtomEntry entry = new AtomEntry();
-        entry.startDocument(response.getOutputStream(), getNamespaces(service));
-        writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
-                context.getCmisVersion());
-        entry.endDocument();
+    public static class GetObject extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            ReturnVersion returnVersion = getEnumParameter(request, Constants.PARAM_RETURN_VERSION, ReturnVersion.class);
+            String filter = getStringParameter(request, Constants.PARAM_FILTER);
+            Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+            IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+                    IncludeRelationships.class);
+            String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+            Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
+            Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
+
+            // execute
+            ObjectData object = null;
+
+            if ((returnVersion == ReturnVersion.LATEST) || (returnVersion == ReturnVersion.LASTESTMAJOR)) {
+                object = service.getObjectOfLatestVersion(repositoryId, objectId, null,
+                        returnVersion == ReturnVersion.LASTESTMAJOR, filter, includeAllowableActions,
+                        includeRelationships, renditionFilter, includePolicyIds, includeAcl, null);
+            } else {
+                object = service.getObject(repositoryId, objectId, filter, includeAllowableActions,
+                        includeRelationships, renditionFilter, includePolicyIds, includeAcl, null);
+            }
+
+            if (object == null) {
+                throw new CmisRuntimeException("Object is null!");
+            }
+
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
+
+            // set headers
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setContentType(Constants.MEDIATYPE_ENTRY);
+
+            // write XML
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+
+            AtomEntry entry = new AtomEntry();
+            entry.startDocument(response.getOutputStream(), getNamespaces(service));
+            writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
+                    context.getCmisVersion());
+            entry.endDocument();
+        }
     }
 
     /**
      * objectByPath URI template.
      */
-    public static void getObjectByPath(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String path = getStringParameter(request, Constants.PARAM_PATH);
-        String filter = getStringParameter(request, Constants.PARAM_FILTER);
-        Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
-        IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
-                IncludeRelationships.class);
-        String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
-        Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
-        Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
-
-        // execute
-        ObjectData object = service.getObjectByPath(repositoryId, path, filter, includeAllowableActions,
-                includeRelationships, renditionFilter, includePolicyIds, includeAcl, null);
-
-        if (object == null) {
-            throw new CmisRuntimeException("Object is null!");
-        }
-
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, object.getId());
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
-
-        // set headers
-        response.setStatus(HttpServletResponse.SC_OK);
-        response.setContentType(Constants.MEDIATYPE_ENTRY);
-
-        // write XML
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-
-        AtomEntry entry = new AtomEntry();
-        entry.startDocument(response.getOutputStream(), getNamespaces(service));
-        writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
-                context.getCmisVersion());
-        entry.endDocument();
+    public static class GetObjectByPath extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String path = getStringParameter(request, Constants.PARAM_PATH);
+            String filter = getStringParameter(request, Constants.PARAM_FILTER);
+            Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+            IncludeRelationships includeRelationships = getEnumParameter(request, Constants.PARAM_RELATIONSHIPS,
+                    IncludeRelationships.class);
+            String renditionFilter = getStringParameter(request, Constants.PARAM_RENDITION_FILTER);
+            Boolean includePolicyIds = getBooleanParameter(request, Constants.PARAM_POLICY_IDS);
+            Boolean includeAcl = getBooleanParameter(request, Constants.PARAM_ACL);
+
+            // execute
+            ObjectData object = service.getObjectByPath(repositoryId, path, filter, includeAllowableActions,
+                    includeRelationships, renditionFilter, includePolicyIds, includeAcl, null);
+
+            if (object == null) {
+                throw new CmisRuntimeException("Object is null!");
+            }
+
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, object.getId());
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
+
+            // set headers
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setContentType(Constants.MEDIATYPE_ENTRY);
+
+            // write XML
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+
+            AtomEntry entry = new AtomEntry();
+            entry.startDocument(response.getOutputStream(), getNamespaces(service));
+            writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
+                    context.getCmisVersion());
+            entry.endDocument();
+        }
     }
 
     /**
      * Allowable Actions.
      */
-    public static void getAllowableActions(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-
-        // execute
-        AllowableActions allowableActions = service.getAllowableActions(repositoryId, objectId, null);
-
-        if (allowableActions == null) {
-            throw new CmisRuntimeException("Allowable Actions is null!");
-        }
-
-        // set headers
-        response.setStatus(HttpServletResponse.SC_OK);
-        response.setContentType(Constants.MEDIATYPE_ALLOWABLEACTION);
-
-        // write XML
-        XMLStreamWriter writer = XMLUtils.createWriter(response.getOutputStream());
-        XMLUtils.startXmlDocument(writer);
-        XMLConverter.writeAllowableActions(writer, context.getCmisVersion(), true, allowableActions);
-        XMLUtils.endXmlDocument(writer);
+    public static class GetAllowableActions extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+
+            // execute
+            AllowableActions allowableActions = service.getAllowableActions(repositoryId, objectId, null);
+
+            if (allowableActions == null) {
+                throw new CmisRuntimeException("Allowable Actions is null!");
+            }
+
+            // set headers
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setContentType(Constants.MEDIATYPE_ALLOWABLEACTION);
+
+            // write XML
+            XMLStreamWriter writer = XMLUtils.createWriter(response.getOutputStream());
+            XMLUtils.startXmlDocument(writer);
+            XMLConverter.writeAllowableActions(writer, context.getCmisVersion(), true, allowableActions);
+            XMLUtils.endXmlDocument(writer);
+        }
     }
 
     /**
      * getContentStream.
      */
-    public static void getContentStream(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        String streamId = getStringParameter(request, Constants.PARAM_STREAM_ID);
+    public static class GetContentStream extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            String streamId = getStringParameter(request, Constants.PARAM_STREAM_ID);
 
-        BigInteger offset = context.getOffset();
-        BigInteger length = context.getLength();
+            BigInteger offset = context.getOffset();
+            BigInteger length = context.getLength();
 
-        // execute
-        ContentStream content = service.getContentStream(repositoryId, objectId, streamId, offset, length, null);
+            // execute
+            ContentStream content = service.getContentStream(repositoryId, objectId, streamId, offset, length, null);
 
-        if ((content == null) || (content.getStream() == null)) {
-            throw new CmisRuntimeException("Content stream is null!");
-        }
+            if ((content == null) || (content.getStream() == null)) {
+                throw new CmisRuntimeException("Content stream is null!");
+            }
 
-        // set HTTP headers, if requested by the server implementation
-        if (HttpUtils.setContentStreamHeaders(content, request, response)) {
-            return;
-        }
+            // set HTTP headers, if requested by the server implementation
+            if (sendContentStreamHeaders(content, request, response)) {
+                return;
+            }
 
-        String contentType = content.getMimeType();
-        if (contentType == null) {
-            contentType = Constants.MEDIATYPE_OCTETSTREAM;
-        }
+            String contentType = content.getMimeType();
+            if (contentType == null) {
+                contentType = Constants.MEDIATYPE_OCTETSTREAM;
+            }
 
-        // set headers
-        if ((offset == null) && (length == null)) {
-            response.setStatus(HttpServletResponse.SC_OK);
-        } else {
-            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
-        }
-        response.setContentType(contentType);
+            // set headers
+            if ((offset == null) && (length == null)) {
+                response.setStatus(HttpServletResponse.SC_OK);
+            } else {
+                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
+            }
+            response.setContentType(contentType);
 
-        if (content.getFileName() != null) {
-            response.setHeader(MimeHelper.CONTENT_DISPOSITION,
-                    MimeHelper.encodeContentDisposition(MimeHelper.DISPOSITION_ATTACHMENT, content.getFileName()));
-        }
+            if (content.getFileName() != null) {
+                response.setHeader(MimeHelper.CONTENT_DISPOSITION,
+                        MimeHelper.encodeContentDisposition(MimeHelper.DISPOSITION_ATTACHMENT, content.getFileName()));
+            }
 
-        // send content
-        InputStream in = new BufferedInputStream(content.getStream(), BUFFER_SIZE);
-        OutputStream out = new BufferedOutputStream(response.getOutputStream());
+            // send content
+            InputStream in = new BufferedInputStream(content.getStream(), BUFFER_SIZE);
+            OutputStream out = new BufferedOutputStream(response.getOutputStream());
+
+            byte[] buffer = new byte[BUFFER_SIZE];
+            int b;
+            while ((b = in.read(buffer)) > -1) {
+                out.write(buffer, 0, b);
+            }
 
-        byte[] buffer = new byte[BUFFER_SIZE];
-        int b;
-        while ((b = in.read(buffer)) > -1) {
-            out.write(buffer, 0, b);
+            in.close();
+            out.flush();
         }
-
-        in.close();
-        out.flush();
     }
 
     /**
      * UpdateProperties.
      */
-    public static void updateProperties(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        Boolean checkin = getBooleanParameter(request, Constants.PARAM_CHECK_IN);
-        String checkinComment = getStringParameter(request, Constants.PARAM_CHECKIN_COMMENT);
-        Boolean major = getBooleanParameter(request, Constants.PARAM_MAJOR);
-
-        ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
-                .get(CallContext.STREAM_FACTORY);
-        AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), streamFactory);
-
-        // execute
-        Holder<String> objectIdHolder = new Holder<String>(objectId);
-
-        if ((checkin != null) && (checkin.booleanValue())) {
-            ContentStream contentStream = parser.getContentStream();
-            try {
-                service.checkIn(repositoryId, objectIdHolder, major, parser.getProperties(), contentStream,
-                        checkinComment, parser.getPolicyIds(), null, null, null);
-            } finally {
-                closeContentStream(contentStream);
-            }
-        } else {
-            String changeToken = extractChangeToken(parser.getProperties());
-
-            service.updateProperties(repositoryId, objectIdHolder, changeToken == null ? null : new Holder<String>(
-                    changeToken), parser.getProperties(), null);
-        }
-
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectIdHolder.getValue());
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
-
-        ObjectData object = objectInfo.getObject();
-        if (object == null) {
-            throw new CmisRuntimeException("Object is null!");
-        }
-
-        // set headers
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-        String location = compileUrl(baseUrl, RESOURCE_ENTRY, objectIdHolder.getValue());
-
-        response.setStatus(HttpServletResponse.SC_CREATED);
-        response.setContentType(Constants.MEDIATYPE_ENTRY);
-        response.setHeader("Content-Location", location);
-        response.setHeader("Location", location);
-
-        // write XML
-        AtomEntry entry = new AtomEntry();
-        entry.startDocument(response.getOutputStream(), getNamespaces(service));
-        writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
-                context.getCmisVersion());
-        entry.endDocument();
-    }
+    public static class UpdateProperties extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            Boolean checkin = getBooleanParameter(request, Constants.PARAM_CHECK_IN);
+            String checkinComment = getStringParameter(request, Constants.PARAM_CHECKIN_COMMENT);
+            Boolean major = getBooleanParameter(request, Constants.PARAM_MAJOR);
+
+            ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
+                    .get(CallContext.STREAM_FACTORY);
+            AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), streamFactory);
+
+            // execute
+            Holder<String> objectIdHolder = new Holder<String>(objectId);
+
+            if ((checkin != null) && (checkin.booleanValue())) {
+                ContentStream contentStream = parser.getContentStream();
+                try {
+                    service.checkIn(repositoryId, objectIdHolder, major, parser.getProperties(), contentStream,
+                            checkinComment, parser.getPolicyIds(), null, null, null);
+                } finally {
+                    closeContentStream(contentStream);
+                }
+            } else {
+                String changeToken = extractChangeToken(parser.getProperties());
 
-    /**
-     * BulkUpdateProperties.
-     */
-    public static void bulkUpdateProperties(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
+                service.updateProperties(repositoryId, objectIdHolder, changeToken == null ? null : new Holder<String>(
+                        changeToken), parser.getProperties(), null);
+            }
 
-        ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
-                .get(CallContext.STREAM_FACTORY);
-        AtomEntryParser parser = new AtomEntryParser(streamFactory);
-        parser.parse(request.getInputStream());
-
-        BulkUpdateImpl bulkUpdate = parser.getBulkUpdate();
-        if (bulkUpdate == null) {
-            throw new CmisInvalidArgumentException("Bulk update data is missing!");
-        }
-
-        List<BulkUpdateObjectIdAndChangeToken> result = service.bulkUpdateProperties(repositoryId,
-                bulkUpdate.getObjectIdAndChangeToken(), bulkUpdate.getProperties(),
-                bulkUpdate.getAddSecondaryTypeIds(), bulkUpdate.getRemoveSecondaryTypeIds(), null);
-
-        response.setStatus(HttpServletResponse.SC_CREATED);
-        response.setContentType(Constants.MEDIATYPE_FEED);
-
-        // write XML
-        AtomFeed feed = new AtomFeed();
-        feed.startDocument(response.getOutputStream(), getNamespaces(service));
-        feed.startFeed(true);
-
-        // write basic Atom feed elements
-        feed.writeFeedElements(null, null, null, "Bulk Update Properties",
-                new GregorianCalendar(TimeZone.getTimeZone("GMT")), null,
-                (result == null ? null : BigInteger.valueOf(result.size())));
-
-        // write links
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-
-        feed.writeServiceLink(baseUrl.toString(), repositoryId);
-
-        UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_BULK_UPDATE, null);
-        feed.writeSelfLink(selfLink.toString(), null);
-
-        // write entries
-        if (result != null) {
-            AtomEntry entry = new AtomEntry(feed.getWriter());
-            for (BulkUpdateObjectIdAndChangeToken idAndToken : result) {
-                if ((idAndToken == null) || (idAndToken.getId() == null)) {
-                    continue;
-                }
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectIdHolder.getValue());
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
 
-                ObjectDataImpl object = new ObjectDataImpl();
-                PropertiesImpl properties = new PropertiesImpl();
-                object.setProperties(properties);
-
-                properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_ID, idAndToken.getId()));
-
-                if (idAndToken.getChangeToken() != null) {
-                    properties
-                            .addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN, idAndToken.getChangeToken()));
-                }
+            ObjectData object = objectInfo.getObject();
+            if (object == null) {
+                throw new CmisRuntimeException("Object is null!");
+            }
 
-                writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, false,
-                        context.getCmisVersion());
+            // set headers
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+            String location = compileUrl(baseUrl, RESOURCE_ENTRY, objectIdHolder.getValue());
+
+            response.setStatus(HttpServletResponse.SC_CREATED);
+            response.setContentType(Constants.MEDIATYPE_ENTRY);
+            response.setHeader("Content-Location", location);
+            response.setHeader("Location", location);
+
+            // write XML
+            AtomEntry entry = new AtomEntry();
+            entry.startDocument(response.getOutputStream(), getNamespaces(service));
+            writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, true,
+                    context.getCmisVersion());
+            entry.endDocument();
+        }
+
+        /**
+         * Gets the change token from a property set.
+         */
+        private String extractChangeToken(Properties properties) {
+            if (properties == null) {
+                return null;
             }
-        }
 
-        // we are done
-        feed.endFeed();
-        feed.endDocument();
-    }
+            Map<String, PropertyData<?>> propertiesMap = properties.getProperties();
+            if (propertiesMap == null) {
+                return null;
+            }
 
-    /**
-     * Gets the change token from a property set.
-     */
-    private static String extractChangeToken(Properties properties) {
-        if (properties == null) {
-            return null;
-        }
+            PropertyData<?> changeLogProperty = propertiesMap.get(PropertyIds.CHANGE_TOKEN);
+            if (!(changeLogProperty instanceof PropertyString)) {
+                return null;
+            }
 
-        Map<String, PropertyData<?>> propertiesMap = properties.getProperties();
-        if (propertiesMap == null) {
-            return null;
+            return ((PropertyString) changeLogProperty).getFirstValue();
         }
+    }
 
-        PropertyData<?> changeLogProperty = propertiesMap.get(PropertyIds.CHANGE_TOKEN);
-        if (!(changeLogProperty instanceof PropertyString)) {
-            return null;
-        }
+    /**
+     * BulkUpdateProperties.
+     */
+    public static class BulkUpdateProperties extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
+                    .get(CallContext.STREAM_FACTORY);
+            AtomEntryParser parser = new AtomEntryParser(streamFactory);
+            parser.parse(request.getInputStream());
+
+            BulkUpdateImpl bulkUpdate = parser.getBulkUpdate();
+            if (bulkUpdate == null) {
+                throw new CmisInvalidArgumentException("Bulk update data is missing!");
+            }
 
-        return ((PropertyString) changeLogProperty).getFirstValue();
-    }
+            List<BulkUpdateObjectIdAndChangeToken> result = service.bulkUpdateProperties(repositoryId,
+                    bulkUpdate.getObjectIdAndChangeToken(), bulkUpdate.getProperties(),
+                    bulkUpdate.getAddSecondaryTypeIds(), bulkUpdate.getRemoveSecondaryTypeIds(), null);
+
+            response.setStatus(HttpServletResponse.SC_CREATED);
+            response.setContentType(Constants.MEDIATYPE_FEED);
+
+            // write XML
+            AtomFeed feed = new AtomFeed();
+            feed.startDocument(response.getOutputStream(), getNamespaces(service));
+            feed.startFeed(true);
+
+            // write basic Atom feed elements
+            feed.writeFeedElements(null, null, null, "Bulk Update Properties",
+                    new GregorianCalendar(TimeZone.getTimeZone("GMT")), null,
+                    (result == null ? null : BigInteger.valueOf(result.size())));
+
+            // write links
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+
+            feed.writeServiceLink(baseUrl.toString(), repositoryId);
+
+            UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_BULK_UPDATE, null);
+            feed.writeSelfLink(selfLink.toString(), null);
+
+            // write entries
+            if (result != null) {
+                AtomEntry entry = new AtomEntry(feed.getWriter());
+                for (BulkUpdateObjectIdAndChangeToken idAndToken : result) {
+                    if ((idAndToken == null) || (idAndToken.getId() == null)) {
+                        continue;
+                    }
+
+                    ObjectDataImpl object = new ObjectDataImpl();
+                    PropertiesImpl properties = new PropertiesImpl();
+                    object.setProperties(properties);
+
+                    properties.addProperty(new PropertyIdImpl(PropertyIds.OBJECT_ID, idAndToken.getId()));
+
+                    if (idAndToken.getChangeToken() != null) {
+                        properties.addProperty(new PropertyStringImpl(PropertyIds.CHANGE_TOKEN, idAndToken
+                                .getChangeToken()));
+                    }
 
-    public static void closeContentStream(ContentStream contentStream) {
-        if (contentStream != null && contentStream.getStream() != null) {
-            try {
-                contentStream.getStream().close();
-            } catch (IOException e) {
-                // we tried our best
+                    writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, false,
+                            context.getCmisVersion());
+                }
             }
+
+            // we are done
+            feed.endFeed();
+            feed.endDocument();
         }
     }
+
 }

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/PolicyService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/PolicyService.java?rev=1481420&r1=1481419&r2=1481420&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/PolicyService.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/PolicyService.java Sat May 11 21:19:48 2013
@@ -18,12 +18,6 @@
  */
 package org.apache.chemistry.opencmis.server.impl.atompub;
 
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_POLICIES;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileBaseUrl;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrlBuilder;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.getNamespaces;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
-
 import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
@@ -42,149 +36,154 @@ import org.apache.chemistry.opencmis.ser
 /**
  * Policy Service operations.
  */
-public final class PolicyService {
+public class PolicyService {
+
+    public static abstract class AbstractPoliciesServiceCall extends AbstractAtomPubServiceCall {
+        /**
+         * Writes an entry that is attached to an object.
+         */
+        protected void writePolicyEntry(CmisService service, AtomEntry entry, String objectId, ObjectData policy,
+                String repositoryId, UrlBuilder baseUrl, CmisVersion cmisVersion) throws Exception {
+            ObjectInfo info = service.getObjectInfo(repositoryId, policy.getId());
+            if (info == null) {
+                throw new CmisRuntimeException("Object Info not found!");
+            }
+
+            // start
+            entry.startEntry(false);
 
-    private PolicyService() {
+            // write the object
+            entry.writeObject(policy, info, null, null, null, null, cmisVersion);
+
+            // write links
+            UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_POLICIES, objectId);
+            selfLink.addParameter(Constants.PARAM_POLICY_ID, info.getId());
+            entry.writeSelfLink(selfLink.toString(), null);
+
+            // we are done
+            entry.endEntry();
+        }
     }
 
     /**
      * Get applied policies.
      */
-    public static void getAppliedPolicies(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        String filter = getStringParameter(request, Constants.PARAM_FILTER);
+    public static class GetAppliedPolicies extends AbstractPoliciesServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            String filter = getStringParameter(request, Constants.PARAM_FILTER);
 
-        // execute
-        List<ObjectData> policies = service.getAppliedPolicies(repositoryId, objectId, filter, null);
+            // execute
+            List<ObjectData> policies = service.getAppliedPolicies(repositoryId, objectId, filter, null);
 
-        if (policies == null) {
-            throw new CmisRuntimeException("Policies are null!");
-        }
+            if (policies == null) {
+                throw new CmisRuntimeException("Policies are null!");
+            }
 
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
 
-        // set headers
-        response.setStatus(HttpServletResponse.SC_OK);
-        response.setContentType(Constants.MEDIATYPE_FEED);
-
-        // write XML
-        AtomFeed feed = new AtomFeed();
-        feed.startDocument(response.getOutputStream(), getNamespaces(service));
-        feed.startFeed(true);
-
-        // write basic Atom feed elements
-        feed.writeFeedElements(objectInfo.getId(), objectInfo.getAtomId(), objectInfo.getCreatedBy(),
-                objectInfo.getName(), objectInfo.getLastModificationDate(), null, null);
-
-        // write links
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-
-        feed.writeServiceLink(baseUrl.toString(), repositoryId);
-
-        UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_POLICIES, objectInfo.getId());
-        selfLink.addParameter(Constants.PARAM_FILTER, filter);
-        feed.writeSelfLink(selfLink.toString(), null);
-
-        // write entries
-        AtomEntry entry = new AtomEntry(feed.getWriter());
-        for (ObjectData policy : policies) {
-            if (policy == null) {
-                continue;
+            // set headers
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setContentType(Constants.MEDIATYPE_FEED);
+
+            // write XML
+            AtomFeed feed = new AtomFeed();
+            feed.startDocument(response.getOutputStream(), getNamespaces(service));
+            feed.startFeed(true);
+
+            // write basic Atom feed elements
+            feed.writeFeedElements(objectInfo.getId(), objectInfo.getAtomId(), objectInfo.getCreatedBy(),
+                    objectInfo.getName(), objectInfo.getLastModificationDate(), null, null);
+
+            // write links
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+
+            feed.writeServiceLink(baseUrl.toString(), repositoryId);
+
+            UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_POLICIES, objectInfo.getId());
+            selfLink.addParameter(Constants.PARAM_FILTER, filter);
+            feed.writeSelfLink(selfLink.toString(), null);
+
+            // write entries
+            AtomEntry entry = new AtomEntry(feed.getWriter());
+            for (ObjectData policy : policies) {
+                if (policy == null) {
+                    continue;
+                }
+                writePolicyEntry(service, entry, objectInfo.getId(), policy, repositoryId, baseUrl,
+                        context.getCmisVersion());
             }
-            writePolicyEntry(service, entry, objectInfo.getId(), policy, repositoryId, baseUrl,
-                    context.getCmisVersion());
-        }
 
-        // we are done
-        feed.endFeed();
-        feed.endDocument();
+            // we are done
+            feed.endFeed();
+            feed.endDocument();
+        }
     }
 
     /**
      * Apply policy.
      */
-    public static void applyPolicy(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-
-        ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
-                .get(CallContext.STREAM_FACTORY);
-        AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), streamFactory);
-
-        // execute
-        service.applyPolicy(repositoryId, parser.getId(), objectId, null);
-
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, parser.getId());
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
+    public static class ApplyPolicy extends AbstractPoliciesServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+
+            ThresholdOutputStreamFactory streamFactory = (ThresholdOutputStreamFactory) context
+                    .get(CallContext.STREAM_FACTORY);
+            AtomEntryParser parser = new AtomEntryParser(request.getInputStream(), streamFactory);
+
+            // execute
+            service.applyPolicy(repositoryId, parser.getId(), objectId, null);
+
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, parser.getId());
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
 
-        ObjectData policy = objectInfo.getObject();
-        if (policy == null) {
-            throw new CmisRuntimeException("Policy is null!");
-        }
+            ObjectData policy = objectInfo.getObject();
+            if (policy == null) {
+                throw new CmisRuntimeException("Policy is null!");
+            }
 
-        // set headers
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-        UrlBuilder location = compileUrlBuilder(baseUrl, RESOURCE_POLICIES, objectId);
-        location.addParameter(Constants.PARAM_POLICY_ID, policy.getId());
-
-        response.setStatus(HttpServletResponse.SC_CREATED);
-        response.setContentType(Constants.MEDIATYPE_ENTRY);
-        response.setHeader("Content-Location", location.toString());
-        response.setHeader("Location", location.toString());
-
-        // write XML
-        AtomEntry entry = new AtomEntry();
-        entry.startDocument(response.getOutputStream(), getNamespaces(service));
-        writePolicyEntry(service, entry, objectId, policy, repositoryId, baseUrl, context.getCmisVersion());
-        entry.endDocument();
+            // set headers
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+            UrlBuilder location = compileUrlBuilder(baseUrl, RESOURCE_POLICIES, objectId);
+            location.addParameter(Constants.PARAM_POLICY_ID, policy.getId());
+
+            response.setStatus(HttpServletResponse.SC_CREATED);
+            response.setContentType(Constants.MEDIATYPE_ENTRY);
+            response.setHeader("Content-Location", location.toString());
+            response.setHeader("Location", location.toString());
+
+            // write XML
+            AtomEntry entry = new AtomEntry();
+            entry.startDocument(response.getOutputStream(), getNamespaces(service));
+            writePolicyEntry(service, entry, objectId, policy, repositoryId, baseUrl, context.getCmisVersion());
+            entry.endDocument();
+        }
     }
 
     /**
      * Remove policy.
      */
-    public static void removePolicy(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        String policyId = getStringParameter(request, Constants.PARAM_POLICY_ID);
-
-        // execute
-        service.removePolicy(repositoryId, policyId, objectId, null);
+    public static class RemovePolicy extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            String policyId = getStringParameter(request, Constants.PARAM_POLICY_ID);
 
-        // set headers
-        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
-    }
+            // execute
+            service.removePolicy(repositoryId, policyId, objectId, null);
 
-    /**
-     * Writes an entry that is attached to an object.
-     */
-    private static void writePolicyEntry(CmisService service, AtomEntry entry, String objectId, ObjectData policy,
-            String repositoryId, UrlBuilder baseUrl, CmisVersion cmisVersion) throws Exception {
-        ObjectInfo info = service.getObjectInfo(repositoryId, policy.getId());
-        if (info == null) {
-            throw new CmisRuntimeException("Object Info not found!");
+            // set headers
+            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
         }
-
-        // start
-        entry.startEntry(false);
-
-        // write the object
-        entry.writeObject(policy, info, null, null, null, null, cmisVersion);
-
-        // write links
-        UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_POLICIES, objectId);
-        selfLink.addParameter(Constants.PARAM_POLICY_ID, info.getId());
-        entry.writeSelfLink(selfLink.toString(), null);
-
-        // we are done
-        entry.endEntry();
     }
 }

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/RelationshipService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/RelationshipService.java?rev=1481420&r1=1481419&r2=1481420&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/RelationshipService.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/atompub/RelationshipService.java Sat May 11 21:19:48 2013
@@ -18,16 +18,6 @@
  */
 package org.apache.chemistry.opencmis.server.impl.atompub;
 
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.RESOURCE_RELATIONSHIPS;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileBaseUrl;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.compileUrlBuilder;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.getNamespaces;
-import static org.apache.chemistry.opencmis.server.impl.atompub.AtomPubUtils.writeObjectEntry;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBigIntegerParameter;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getBooleanParameter;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getEnumParameter;
-import static org.apache.chemistry.opencmis.server.shared.HttpUtils.getStringParameter;
-
 import java.math.BigInteger;
 
 import javax.servlet.http.HttpServletRequest;
@@ -46,89 +36,90 @@ import org.apache.chemistry.opencmis.com
 /**
  * Relationship Service operations.
  */
-public final class RelationshipService {
-
-    private RelationshipService() {
-    }
+public class RelationshipService {
 
     /**
      * Get object relationships.
      */
-    public static void getObjectRelationships(CallContext context, CmisService service, String repositoryId,
-            HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // get parameters
-        String objectId = getStringParameter(request, Constants.PARAM_ID);
-        Boolean includeSubRelationshipTypes = getBooleanParameter(request, Constants.PARAM_SUB_RELATIONSHIP_TYPES);
-        RelationshipDirection relationshipDirection = getEnumParameter(request, Constants.PARAM_RELATIONSHIP_DIRECTION,
-                RelationshipDirection.class);
-        String typeId = getStringParameter(request, Constants.PARAM_TYPE_ID);
-        String filter = getStringParameter(request, Constants.PARAM_FILTER);
-        Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
-        BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
-        BigInteger skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);
-
-        // execute
-        ObjectList relationships = service.getObjectRelationships(repositoryId, objectId, includeSubRelationshipTypes,
-                relationshipDirection, typeId, filter, includeAllowableActions, maxItems, skipCount, null);
+    public static class GetObjectRelationships extends AbstractAtomPubServiceCall {
+        public void serve(CallContext context, CmisService service, String repositoryId, HttpServletRequest request,
+                HttpServletResponse response) throws Exception {
+            // get parameters
+            String objectId = getStringParameter(request, Constants.PARAM_ID);
+            Boolean includeSubRelationshipTypes = getBooleanParameter(request, Constants.PARAM_SUB_RELATIONSHIP_TYPES);
+            RelationshipDirection relationshipDirection = getEnumParameter(request,
+                    Constants.PARAM_RELATIONSHIP_DIRECTION, RelationshipDirection.class);
+            String typeId = getStringParameter(request, Constants.PARAM_TYPE_ID);
+            String filter = getStringParameter(request, Constants.PARAM_FILTER);
+            Boolean includeAllowableActions = getBooleanParameter(request, Constants.PARAM_ALLOWABLE_ACTIONS);
+            BigInteger maxItems = getBigIntegerParameter(request, Constants.PARAM_MAX_ITEMS);
+            BigInteger skipCount = getBigIntegerParameter(request, Constants.PARAM_SKIP_COUNT);
+
+            // execute
+            ObjectList relationships = service.getObjectRelationships(repositoryId, objectId,
+                    includeSubRelationshipTypes, relationshipDirection, typeId, filter, includeAllowableActions,
+                    maxItems, skipCount, null);
 
-        if (relationships == null) {
-            throw new CmisRuntimeException("Relationships are null!");
-        }
+            if (relationships == null) {
+                throw new CmisRuntimeException("Relationships are null!");
+            }
 
-        ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
-        if (objectInfo == null) {
-            throw new CmisRuntimeException("Object Info is missing!");
-        }
+            ObjectInfo objectInfo = service.getObjectInfo(repositoryId, objectId);
+            if (objectInfo == null) {
+                throw new CmisRuntimeException("Object Info is missing!");
+            }
 
-        // set headers
-        response.setStatus(HttpServletResponse.SC_OK);
-        response.setContentType(Constants.MEDIATYPE_FEED);
-
-        // write XML
-        AtomFeed feed = new AtomFeed();
-        feed.startDocument(response.getOutputStream(), getNamespaces(service));
-        feed.startFeed(true);
-
-        // write basic Atom feed elements
-        feed.writeFeedElements(objectInfo.getId(), objectInfo.getAtomId(), objectInfo.getCreatedBy(),
-                objectInfo.getName(), objectInfo.getLastModificationDate(), null, relationships.getNumItems());
-
-        // write links
-        UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
-
-        feed.writeServiceLink(baseUrl.toString(), repositoryId);
-
-        UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_RELATIONSHIPS, objectInfo.getId());
-        selfLink.addParameter(Constants.PARAM_SUB_RELATIONSHIP_TYPES, includeSubRelationshipTypes);
-        selfLink.addParameter(Constants.PARAM_RELATIONSHIP_DIRECTION, relationshipDirection);
-        selfLink.addParameter(Constants.PARAM_TYPE_ID, typeId);
-        selfLink.addParameter(Constants.PARAM_FILTER, filter);
-        selfLink.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
-        selfLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
-        selfLink.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
-        feed.writeSelfLink(selfLink.toString(), null);
-
-        UrlBuilder pagingUrl = new UrlBuilder(compileUrlBuilder(baseUrl, RESOURCE_RELATIONSHIPS, objectInfo.getId()));
-        pagingUrl.addParameter(Constants.PARAM_SUB_RELATIONSHIP_TYPES, includeSubRelationshipTypes);
-        pagingUrl.addParameter(Constants.PARAM_RELATIONSHIP_DIRECTION, relationshipDirection);
-        pagingUrl.addParameter(Constants.PARAM_TYPE_ID, typeId);
-        pagingUrl.addParameter(Constants.PARAM_FILTER, filter);
-        pagingUrl.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
-        feed.writePagingLinks(pagingUrl, maxItems, skipCount, relationships.getNumItems(),
-                relationships.hasMoreItems(), AtomPubUtils.PAGE_SIZE);
-
-        // write entries
-        AtomEntry entry = new AtomEntry(feed.getWriter());
-        for (ObjectData object : relationships.getObjects()) {
-            if (object == null) {
-                continue;
+            // set headers
+            response.setStatus(HttpServletResponse.SC_OK);
+            response.setContentType(Constants.MEDIATYPE_FEED);
+
+            // write XML
+            AtomFeed feed = new AtomFeed();
+            feed.startDocument(response.getOutputStream(), getNamespaces(service));
+            feed.startFeed(true);
+
+            // write basic Atom feed elements
+            feed.writeFeedElements(objectInfo.getId(), objectInfo.getAtomId(), objectInfo.getCreatedBy(),
+                    objectInfo.getName(), objectInfo.getLastModificationDate(), null, relationships.getNumItems());
+
+            // write links
+            UrlBuilder baseUrl = compileBaseUrl(request, repositoryId);
+
+            feed.writeServiceLink(baseUrl.toString(), repositoryId);
+
+            UrlBuilder selfLink = compileUrlBuilder(baseUrl, RESOURCE_RELATIONSHIPS, objectInfo.getId());
+            selfLink.addParameter(Constants.PARAM_SUB_RELATIONSHIP_TYPES, includeSubRelationshipTypes);
+            selfLink.addParameter(Constants.PARAM_RELATIONSHIP_DIRECTION, relationshipDirection);
+            selfLink.addParameter(Constants.PARAM_TYPE_ID, typeId);
+            selfLink.addParameter(Constants.PARAM_FILTER, filter);
+            selfLink.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+            selfLink.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+            selfLink.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
+            feed.writeSelfLink(selfLink.toString(), null);
+
+            UrlBuilder pagingUrl = new UrlBuilder(
+                    compileUrlBuilder(baseUrl, RESOURCE_RELATIONSHIPS, objectInfo.getId()));
+            pagingUrl.addParameter(Constants.PARAM_SUB_RELATIONSHIP_TYPES, includeSubRelationshipTypes);
+            pagingUrl.addParameter(Constants.PARAM_RELATIONSHIP_DIRECTION, relationshipDirection);
+            pagingUrl.addParameter(Constants.PARAM_TYPE_ID, typeId);
+            pagingUrl.addParameter(Constants.PARAM_FILTER, filter);
+            pagingUrl.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+            feed.writePagingLinks(pagingUrl, maxItems, skipCount, relationships.getNumItems(),
+                    relationships.hasMoreItems(), PAGE_SIZE);
+
+            // write entries
+            AtomEntry entry = new AtomEntry(feed.getWriter());
+            for (ObjectData object : relationships.getObjects()) {
+                if (object == null) {
+                    continue;
+                }
+                writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, false,
+                        context.getCmisVersion());
             }
-            writeObjectEntry(service, entry, object, null, repositoryId, null, null, baseUrl, false,
-                    context.getCmisVersion());
-        }
 
-        // we are done
-        feed.endFeed();
-        feed.endDocument();
+            // we are done
+            feed.endFeed();
+            feed.endDocument();
+        }
     }
 }