You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fg...@apache.org on 2010/04/15 12:33:51 UTC

svn commit: r934361 [4/9] - in /incubator/chemistry/opencmis/trunk: chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/ chemistry-opencmis-client/chemistry-opencmis-client-bindings/s...

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java?rev=934361&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java Thu Apr 15 10:33:49 2010
@@ -0,0 +1,526 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
+
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.Session;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomBase;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomFeed;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
+import org.apache.chemistry.opencmis.commons.api.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderContainerImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectInFolderListImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectParentDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.chemistry.opencmis.commons.provider.NavigationService;
+import org.apache.chemistry.opencmis.commons.provider.ObjectData;
+import org.apache.chemistry.opencmis.commons.provider.ObjectInFolderContainer;
+import org.apache.chemistry.opencmis.commons.provider.ObjectInFolderData;
+import org.apache.chemistry.opencmis.commons.provider.ObjectInFolderList;
+import org.apache.chemistry.opencmis.commons.provider.ObjectList;
+import org.apache.chemistry.opencmis.commons.provider.ObjectParentData;
+
+/**
+ * Navigation Service AtomPub client.
+ * 
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public class NavigationServiceImpl extends AbstractAtomPubService implements NavigationService {
+
+  /**
+   * Constructor.
+   */
+  public NavigationServiceImpl(Session session) {
+    setSession(session);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.NavigationService#getChildren(java.lang.String,
+   * java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean,
+   * java.math.BigInteger, java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectInFolderList getChildren(String repositoryId, String folderId, String filter,
+      String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePathSegment, BigInteger maxItems,
+      BigInteger skipCount, ExtensionsData extension) {
+    ObjectInFolderListImpl result = new ObjectInFolderListImpl();
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+    url.addParameter(Constants.PARAM_ORDER_BY, orderBy);
+    url.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+    url.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);
+    url.addParameter(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+    url.addParameter(Constants.PARAM_PATH_SEGMENT, includePathSegment);
+    url.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+    url.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // handle top level
+    for (AtomElement element : feed.getElements()) {
+      if (element.getObject() instanceof AtomLink) {
+        if (isNextLink(element)) {
+          result.setHasMoreItems(Boolean.TRUE);
+        }
+      }
+      else if (isInt(NAME_NUM_ITEMS, element)) {
+        result.setNumItems((BigInteger) element.getObject());
+      }
+    }
+
+    // get the children
+    if (!feed.getEntries().isEmpty()) {
+      result.setObjects(new ArrayList<ObjectInFolderData>(feed.getEntries().size()));
+
+      for (AtomEntry entry : feed.getEntries()) {
+        ObjectInFolderDataImpl child = null;
+        String pathSegment = null;
+
+        lockLinks();
+        try {
+          // clean up cache
+          removeLinks(repositoryId, entry.getId());
+
+          // walk through the entry
+          for (AtomElement element : entry.getElements()) {
+            if (element.getObject() instanceof AtomLink) {
+              addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+            }
+            else if (isStr(NAME_PATH_SEGMENT, element)) {
+              pathSegment = (String) element.getObject();
+            }
+            else if (element.getObject() instanceof CmisObjectType) {
+              child = new ObjectInFolderDataImpl();
+              child.setObject(convert((CmisObjectType) element.getObject()));
+            }
+          }
+        }
+        finally {
+          unlockLinks();
+        }
+
+        if (child != null) {
+          child.setPathSegment(pathSegment);
+          result.getObjects().add(child);
+        }
+      }
+    }
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.NavigationService#getDescendants(java.lang.String,
+   * java.lang.String, java.math.BigInteger, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectInFolderContainer> getDescendants(String repositoryId, String folderId,
+      BigInteger depth, String filter, Boolean includeAllowableActions,
+      IncludeRelationships includeRelationships, String renditionFilter,
+      Boolean includePathSegment, ExtensionsData extension) {
+    List<ObjectInFolderContainer> result = new ArrayList<ObjectInFolderContainer>();
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_DOWN,
+        Constants.MEDIATYPE_DESCENDANTS);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_DOWN,
+          Constants.MEDIATYPE_DESCENDANTS);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_DEPTH, depth);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+    url.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+    url.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);
+    url.addParameter(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+    url.addParameter(Constants.PARAM_PATH_SEGMENT, includePathSegment);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // process tree
+    addDescendantsLevel(repositoryId, feed, result);
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.NavigationService#getFolderParent(java.lang.String,
+   * java.lang.String, java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectData getFolderParent(String repositoryId, String folderId, String filter,
+      ExtensionsData extension) {
+    ObjectData result = null;
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_UP, Constants.MEDIATYPE_ENTRY);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_UP, Constants.MEDIATYPE_ENTRY);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+
+    // read
+    HttpUtils.Response resp = read(url);
+
+    AtomBase base = parse(resp.getStream(), AtomBase.class);
+
+    // get the entry
+    AtomEntry entry = null;
+    if (base instanceof AtomFeed) {
+      AtomFeed feed = (AtomFeed) base;
+      if (feed.getEntries().isEmpty()) {
+        throw new CmisRuntimeException("Parent feed is empty!");
+      }
+      entry = feed.getEntries().get(0);
+    }
+    else if (base instanceof AtomEntry) {
+      entry = (AtomEntry) base;
+    }
+    else {
+      throw new CmisRuntimeException("Unexpected document!");
+    }
+
+    lockLinks();
+    try {
+      // clean up cache
+      removeLinks(repositoryId, entry.getId());
+
+      // walk through the entry
+      for (AtomElement element : entry.getElements()) {
+        if (element.getObject() instanceof AtomLink) {
+          addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+        }
+        else if (element.getObject() instanceof CmisObjectType) {
+          result = convert((CmisObjectType) element.getObject());
+        }
+      }
+    }
+    finally {
+      unlockLinks();
+    }
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.NavigationService#getFolderTree(java.lang.String,
+   * java.lang.String, java.math.BigInteger, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectInFolderContainer> getFolderTree(String repositoryId, String folderId,
+      BigInteger depth, String filter, Boolean includeAllowableActions,
+      IncludeRelationships includeRelationships, String renditionFilter,
+      Boolean includePathSegment, ExtensionsData extension) {
+    List<ObjectInFolderContainer> result = new ArrayList<ObjectInFolderContainer>();
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_FOLDERTREE,
+        Constants.MEDIATYPE_DESCENDANTS);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_FOLDERTREE,
+          Constants.MEDIATYPE_DESCENDANTS);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_DEPTH, depth);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+    url.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+    url.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);
+    url.addParameter(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+    url.addParameter(Constants.PARAM_PATH_SEGMENT, includePathSegment);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // process tree
+    addDescendantsLevel(repositoryId, feed, result);
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.NavigationService#getObjectParents(java.lang.String,
+   * java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectParentData> getObjectParents(String repositoryId, String objectId,
+      String filter, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includeRelativePathSegment, ExtensionsData extension) {
+    List<ObjectParentData> result = new ArrayList<ObjectParentData>();
+
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_UP, Constants.MEDIATYPE_FEED);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_UP, Constants.MEDIATYPE_FEED);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+    url.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+    url.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);
+    url.addParameter(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+    url.addParameter(Constants.PARAM_RELATIVE_PATH_SEGMENT, includeRelativePathSegment);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+
+    AtomBase base = parse(resp.getStream(), AtomBase.class);
+
+    if (base instanceof AtomFeed) {
+      // it's a feed
+      AtomFeed feed = (AtomFeed) base;
+
+      // walk through the feed
+      for (AtomEntry entry : feed.getEntries()) {
+        ObjectParentDataImpl objectParent = processParentEntry(entry, repositoryId);
+
+        if (objectParent != null) {
+          result.add(objectParent);
+        }
+      }
+    }
+    else if (base instanceof AtomEntry) {
+      // it's an entry
+      AtomEntry entry = (AtomEntry) base;
+
+      ObjectParentDataImpl objectParent = processParentEntry(entry, repositoryId);
+
+      if (objectParent != null) {
+        result.add(objectParent);
+      }
+    }
+
+    return result;
+  }
+
+  private ObjectParentDataImpl processParentEntry(AtomEntry entry, String repositoryId) {
+    ObjectParentDataImpl result = null;
+    String relativePathSegment = null;
+
+    lockLinks();
+    try {
+      // clean up cache
+      removeLinks(repositoryId, entry.getId());
+
+      // walk through the entry
+      for (AtomElement element : entry.getElements()) {
+        if (element.getObject() instanceof AtomLink) {
+          addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+        }
+        else if (element.getObject() instanceof CmisObjectType) {
+          result = new ObjectParentDataImpl(convert((CmisObjectType) element.getObject()));
+        }
+        else if (is(NAME_RELATIVE_PATH_SEGMENT, element)) {
+          relativePathSegment = (String) element.getObject();
+        }
+      }
+    }
+    finally {
+      unlockLinks();
+    }
+
+    if (result != null) {
+      result.setRelativePathSegment(relativePathSegment);
+    }
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.NavigationService#getCheckedOutDocs(java.lang.String,
+   * java.lang.String, java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.math.BigInteger,
+   * java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectList getCheckedOutDocs(String repositoryId, String folderId, String filter,
+      String orderBy, Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+    ObjectListImpl result = new ObjectListImpl();
+
+    // find the link
+    String link = loadCollection(repositoryId, Constants.COLLECTION_CHECKEDOUT);
+
+    if (link == null) {
+      throw new CmisObjectNotFoundException(
+          "Unknown repository or checkedout collection not supported!");
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_FOLDER_ID, folderId);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+    url.addParameter(Constants.PARAM_ORDER_BY, orderBy);
+    url.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+    url.addParameter(Constants.PARAM_RELATIONSHIPS, includeRelationships);
+    url.addParameter(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+    url.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+    url.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // handle top level
+    for (AtomElement element : feed.getElements()) {
+      if (element.getObject() instanceof AtomLink) {
+        if (isNextLink(element)) {
+          result.setHasMoreItems(Boolean.TRUE);
+        }
+      }
+      else if (isInt(NAME_NUM_ITEMS, element)) {
+        result.setNumItems((BigInteger) element.getObject());
+      }
+    }
+
+    // get the documents
+    if (!feed.getEntries().isEmpty()) {
+      result.setObjects(new ArrayList<ObjectData>(feed.getEntries().size()));
+
+      for (AtomEntry entry : feed.getEntries()) {
+        ObjectData child = null;
+
+        lockLinks();
+        try {
+          // clean up cache
+          removeLinks(repositoryId, entry.getId());
+
+          // walk through the entry
+          for (AtomElement element : entry.getElements()) {
+            if (element.getObject() instanceof AtomLink) {
+              addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+            }
+            else if (element.getObject() instanceof CmisObjectType) {
+              child = convert((CmisObjectType) element.getObject());
+            }
+          }
+        }
+        finally {
+          unlockLinks();
+        }
+
+        if (child != null) {
+          result.getObjects().add(child);
+        }
+      }
+    }
+
+    return result;
+  }
+
+  // ---- internal ----
+
+  /**
+   * Adds descendants level recursively.
+   */
+  private void addDescendantsLevel(String repositoryId, AtomFeed feed,
+      List<ObjectInFolderContainer> containerList) {
+    if ((feed == null) || (feed.getEntries().isEmpty())) {
+      return;
+    }
+
+    // walk through the feed
+    for (AtomEntry entry : feed.getEntries()) {
+      ObjectInFolderDataImpl objectInFolder = null;
+      String pathSegment = null;
+      List<ObjectInFolderContainer> childContainerList = new ArrayList<ObjectInFolderContainer>();
+
+      lockLinks();
+      try {
+        // clean up cache
+        removeLinks(repositoryId, entry.getId());
+
+        // walk through the entry
+        for (AtomElement element : entry.getElements()) {
+          if (element.getObject() instanceof AtomLink) {
+            addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+          }
+          else if (element.getObject() instanceof CmisObjectType) {
+            objectInFolder = new ObjectInFolderDataImpl(convert((CmisObjectType) element
+                .getObject()));
+          }
+          else if (is(NAME_PATH_SEGMENT, element)) {
+            pathSegment = (String) element.getObject();
+          }
+          else if (element.getObject() instanceof AtomFeed) {
+            addDescendantsLevel(repositoryId, (AtomFeed) element.getObject(), childContainerList);
+          }
+        }
+      }
+      finally {
+        unlockLinks();
+      }
+
+      if (objectInFolder != null) {
+        objectInFolder.setPathSegment(pathSegment);
+        ObjectInFolderContainerImpl childContainer = new ObjectInFolderContainerImpl(objectInFolder);
+        childContainer.setChildren(childContainerList);
+        containerList.add(childContainer);
+      }
+    }
+  }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/NavigationServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java?rev=934361&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java Thu Apr 15 10:33:49 2010
@@ -0,0 +1,786 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
+
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convertPolicyIds;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.Session;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AllowableActions;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.api.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.enums.UnfileObjects;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.ReturnVersion;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisProperty;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisPropertyString;
+import org.apache.chemistry.opencmis.commons.provider.AccessControlList;
+import org.apache.chemistry.opencmis.commons.provider.AllowableActionsData;
+import org.apache.chemistry.opencmis.commons.provider.ContentStreamData;
+import org.apache.chemistry.opencmis.commons.provider.FailedToDeleteData;
+import org.apache.chemistry.opencmis.commons.provider.Holder;
+import org.apache.chemistry.opencmis.commons.provider.ObjectData;
+import org.apache.chemistry.opencmis.commons.provider.ObjectService;
+import org.apache.chemistry.opencmis.commons.provider.PropertiesData;
+import org.apache.chemistry.opencmis.commons.provider.PropertyData;
+import org.apache.chemistry.opencmis.commons.provider.PropertyIdData;
+import org.apache.chemistry.opencmis.commons.provider.RenditionData;
+
+/**
+ * Object Service AtomPub client.
+ * 
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public class ObjectServiceImpl extends AbstractAtomPubService implements ObjectService {
+
+  /**
+   * Constructor.
+   */
+  public ObjectServiceImpl(Session session) {
+    setSession(session);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#createDocument(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String,
+   * org.apache.opencmis.client.provider.ContentStreamData,
+   * org.apache.opencmis.commons.enums.VersioningState, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createDocument(String repositoryId, PropertiesData properties, String folderId,
+      ContentStreamData contentStream, VersioningState versioningState, List<String> policies,
+      AccessControlList addAces, AccessControlList removeAces, ExtensionsData extension) {
+    checkCreateProperties(properties);
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_VERSIONIG_STATE, versioningState);
+
+    // set up object and writer
+    CmisObjectType object = new CmisObjectType();
+    object.setProperties(convert(properties));
+    object.setPolicyIds(convertPolicyIds(policies));
+
+    String mediaType = null;
+    InputStream stream = null;
+
+    if (contentStream != null) {
+      mediaType = contentStream.getMimeType();
+      stream = contentStream.getStream();
+    }
+
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(object, mediaType, stream);
+
+    // post the new folder object
+    HttpUtils.Response resp = post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+
+    // parse the response
+    AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+    // handle ACL modifications
+    handleAclModifications(repositoryId, entry, addAces, removeAces);
+
+    return entry.getId();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.ObjectService#createDocumentFromSource(java.lang.String,
+   * java.lang.String, org.apache.opencmis.client.provider.PropertiesData, java.lang.String,
+   * org.apache.opencmis.commons.enums.VersioningState, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createDocumentFromSource(String repositoryId, String sourceId,
+      PropertiesData properties, String folderId, VersioningState versioningState,
+      List<String> policies, AccessControlList addACEs, AccessControlList removeACEs,
+      ExtensionsData extension) {
+    throw new CmisNotSupportedException(
+        "createDocumentFromSource is not supported by the AtomPub binding!");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#createFolder(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createFolder(String repositoryId, PropertiesData properties, String folderId,
+      List<String> policies, AccessControlList addAces, AccessControlList removeAces,
+      ExtensionsData extension) {
+    checkCreateProperties(properties);
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+
+    // set up object and writer
+    CmisObjectType object = new CmisObjectType();
+    object.setProperties(convert(properties));
+    object.setPolicyIds(convertPolicyIds(policies));
+
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(object);
+
+    // post the new folder object
+    HttpUtils.Response resp = post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+
+    // parse the response
+    AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+    // handle ACL modifications
+    handleAclModifications(repositoryId, entry, addAces, removeAces);
+
+    return entry.getId();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#createPolicy(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.lang.String, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createPolicy(String repositoryId, PropertiesData properties, String folderId,
+      List<String> policies, AccessControlList addAces, AccessControlList removeAces,
+      ExtensionsData extension) {
+    checkCreateProperties(properties);
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+
+    // set up object and writer
+    CmisObjectType object = new CmisObjectType();
+    object.setProperties(convert(properties));
+    object.setPolicyIds(convertPolicyIds(policies));
+
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(object);
+
+    // post the new folder object
+    HttpUtils.Response resp = post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+
+    // parse the response
+    AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+    // handle ACL modifications
+    handleAclModifications(repositoryId, entry, addAces, removeAces);
+
+    return entry.getId();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#createRelationship(java.lang.String,
+   * org.apache.opencmis.client.provider.PropertiesData, java.util.List,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.AccessControlList,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public String createRelationship(String repositoryId, PropertiesData properties,
+      List<String> policies, AccessControlList addAces, AccessControlList removeAces,
+      ExtensionsData extension) {
+    checkCreateProperties(properties);
+
+    // find source id
+    PropertyData<?> sourceIdProperty = properties.getProperties().get(PropertyIds.CMIS_SOURCE_ID);
+    if (!(sourceIdProperty instanceof PropertyIdData)) {
+      throw new CmisInvalidArgumentException("Source Id is not set!");
+    }
+
+    String sourceId = ((PropertyIdData) sourceIdProperty).getFirstValue();
+    if (sourceId == null) {
+      throw new CmisInvalidArgumentException("Source Id is not set!");
+    }
+
+    // find the link
+    String link = loadLink(repositoryId, sourceId, Constants.REL_RELATIONSHIPS,
+        Constants.MEDIATYPE_FEED);
+
+    if (link == null) {
+      throwLinkException(repositoryId, sourceId, Constants.REL_RELATIONSHIPS,
+          Constants.MEDIATYPE_FEED);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+
+    // set up object and writer
+    CmisObjectType object = new CmisObjectType();
+    object.setProperties(convert(properties));
+    object.setPolicyIds(convertPolicyIds(policies));
+
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(object);
+
+    // post the new folder object
+    HttpUtils.Response resp = post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+
+    // parse the response
+    AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+    // handle ACL modifications
+    handleAclModifications(repositoryId, entry, addAces, removeAces);
+
+    return entry.getId();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#updateProperties(java.lang.String,
+   * org.apache.opencmis.client.provider.Holder, org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.PropertiesData,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void updateProperties(String repositoryId, Holder<String> objectId,
+      Holder<String> changeToken, PropertiesData properties, ExtensionsData extension) {
+    // we need an object id
+    if ((objectId == null) || (objectId.getValue() == null) || (objectId.getValue().length() == 0)) {
+      throw new CmisInvalidArgumentException("Object id must be set!");
+    }
+
+    // find the link
+    String link = loadLink(repositoryId, objectId.getValue(), Constants.REL_SELF,
+        Constants.MEDIATYPE_ENTRY);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId.getValue(), Constants.REL_SELF,
+          Constants.MEDIATYPE_ENTRY);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    if (changeToken != null) {
+      url.addParameter(Constants.PARAM_CHANGE_TOKEN, changeToken.getValue());
+    }
+
+    // set up object and writer
+    CmisObjectType object = new CmisObjectType();
+    object.setProperties(convert(properties));
+
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(object);
+
+    // update
+    HttpUtils.Response resp = put(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+
+    // parse new entry
+    AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+    // we expect a CMIS entry
+    if (entry.getId() == null) {
+      throw new CmisConnectionException("Received Atom entry is not a CMIS entry!");
+    }
+
+    // set object id
+    objectId.setValue(entry.getId());
+
+    if (changeToken != null) {
+      changeToken.setValue(null); // just in case
+    }
+
+    lockLinks();
+    try {
+      // clean up cache
+      removeLinks(repositoryId, entry.getId());
+
+      // walk through the entry
+      for (AtomElement element : entry.getElements()) {
+        if (element.getObject() instanceof AtomLink) {
+          addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+        }
+        else if (element.getObject() instanceof CmisObjectType) {
+          // extract new change token
+          if (changeToken != null) {
+            object = (CmisObjectType) element.getObject();
+
+            if (object.getProperties() != null) {
+              for (CmisProperty property : object.getProperties().getProperty()) {
+                if (PropertyIds.CMIS_CHANGE_TOKEN.equals(property.getPropertyDefinitionId())
+                    && (property instanceof CmisPropertyString)) {
+
+                  CmisPropertyString changeTokenProperty = (CmisPropertyString) property;
+                  if (!changeTokenProperty.getValue().isEmpty()) {
+                    changeToken.setValue(changeTokenProperty.getValue().get(0));
+                  }
+
+                  break;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    finally {
+      unlockLinks();
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#deleteObject(java.lang.String,
+   * java.lang.String, java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void deleteObject(String repositoryId, String objectId, Boolean allVersions,
+      ExtensionsData extension) {
+
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_SELF, Constants.MEDIATYPE_ENTRY);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_SELF, Constants.MEDIATYPE_ENTRY);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_ALL_VERSIONS, allVersions);
+
+    delete(url);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#deleteTree(java.lang.String,
+   * java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.UnfileObject,
+   * java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public FailedToDeleteData deleteTree(String repositoryId, String folderId, Boolean allVersions,
+      UnfileObjects unfileObjects, Boolean continueOnFailure, ExtensionsData extension) {
+
+    // find the link
+    String link = loadLink(repositoryId, folderId, Constants.REL_DOWN,
+        Constants.MEDIATYPE_DESCENDANTS);
+
+    if (link == null) {
+      throwLinkException(repositoryId, folderId, Constants.REL_DOWN,
+          Constants.MEDIATYPE_DESCENDANTS);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_ALL_VERSIONS, allVersions);
+    url.addParameter(Constants.PARAM_UNFILE_OBJECTS, unfileObjects);
+    url.addParameter(Constants.PARAM_CONTINUE_ON_FAILURE, continueOnFailure);
+
+    // make the call
+    HttpUtils.Response resp = HttpUtils.invokeDELETE(url, getSession());
+
+    // check response code
+    if ((resp.getResponseCode() == 200) || (resp.getResponseCode() == 202)
+        || (resp.getResponseCode() == 204)) {
+      return new FailedToDeleteDataImpl();
+    }
+
+    throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp
+        .getErrorContent(), null);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getAllowableActions(java.lang.String,
+   * java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public AllowableActionsData getAllowableActions(String repositoryId, String objectId,
+      ExtensionsData extension) {
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_ALLOWABLEACTIONS,
+        Constants.MEDIATYPE_ALLOWABLEACTION);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_ALLOWABLEACTIONS,
+          Constants.MEDIATYPE_ALLOWABLEACTION);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AllowableActions allowableActions = parse(resp.getStream(), AllowableActions.class);
+
+    return convert(allowableActions.getAllowableActions());
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getContentStream(java.lang.String,
+   * java.lang.String, java.lang.String, java.math.BigInteger, java.math.BigInteger,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ContentStreamData getContentStream(String repositoryId, String objectId, String streamId,
+      BigInteger offset, BigInteger length, ExtensionsData extension) {
+    ContentStreamDataImpl result = new ContentStreamDataImpl();
+
+    // find the link
+    String link = loadLink(repositoryId, objectId, AtomPubParser.LINK_REL_CONTENT, null);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, AtomPubParser.LINK_REL_CONTENT, null);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_STREAM_ID, streamId);
+
+    // get the content
+    HttpUtils.Response resp = HttpUtils.invokeGET(url, getSession(), offset, length);
+
+    // check response code
+    if ((resp.getResponseCode() != 200) && (resp.getResponseCode() != 206)) {
+      throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp
+          .getErrorContent(), null);
+    }
+
+    result.setFilename(null);
+    result.setLength(resp.getContentLength());
+    result.setMimeType(resp.getContentTypeHeader());
+    result.setStream(resp.getStream());
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getObject(java.lang.String,
+   * java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean,
+   * java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectData getObject(String repositoryId, String objectId, String filter,
+      Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePolicyIds, Boolean includeACL, ExtensionsData extension) {
+
+    return getObjectInternal(repositoryId, IdentifierType.ID, objectId, ReturnVersion.THIS, filter,
+        includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
+        includeACL, extension);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getObjectByPath(java.lang.String,
+   * java.lang.String, java.lang.String, java.lang.Boolean,
+   * org.apache.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.lang.Boolean,
+   * java.lang.Boolean, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectData getObjectByPath(String repositoryId, String path, String filter,
+      Boolean includeAllowableActions, IncludeRelationships includeRelationships,
+      String renditionFilter, Boolean includePolicyIds, Boolean includeACL, ExtensionsData extension) {
+
+    return getObjectInternal(repositoryId, IdentifierType.PATH, path, ReturnVersion.THIS, filter,
+        includeAllowableActions, includeRelationships, renditionFilter, includePolicyIds,
+        includeACL, extension);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getProperties(java.lang.String,
+   * java.lang.String, java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public PropertiesData getProperties(String repositoryId, String objectId, String filter,
+      ExtensionsData extension) {
+    ObjectData object = getObjectInternal(repositoryId, IdentifierType.ID, objectId,
+        ReturnVersion.THIS, filter, Boolean.FALSE, IncludeRelationships.NONE, "cmis:none",
+        Boolean.FALSE, Boolean.FALSE, extension);
+
+    return object.getProperties();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#getRenditions(java.lang.String,
+   * java.lang.String, java.lang.String, java.math.BigInteger, java.math.BigInteger,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<RenditionData> getRenditions(String repositoryId, String objectId,
+      String renditionFilter, BigInteger maxItems, BigInteger skipCount, ExtensionsData extension) {
+    ObjectData object = getObjectInternal(repositoryId, IdentifierType.ID, objectId,
+        ReturnVersion.THIS, PropertyIds.CMIS_OBJECT_ID, Boolean.FALSE, IncludeRelationships.NONE,
+        renditionFilter, Boolean.FALSE, Boolean.FALSE, extension);
+
+    List<RenditionData> result = object.getRenditions();
+    if (result == null) {
+      result = Collections.emptyList();
+    }
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#moveObject(java.lang.String,
+   * org.apache.opencmis.client.provider.Holder, java.lang.String, java.lang.String,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void moveObject(String repositoryId, Holder<String> objectId, String targetFolderId,
+      String sourceFolderId, ExtensionsData extension) {
+    if ((objectId == null) || (objectId.getValue() == null) || (objectId.getValue().length() == 0)) {
+      throw new CmisInvalidArgumentException("Object id must be set!");
+    }
+
+    if ((targetFolderId == null) || (targetFolderId.length() == 0) || (sourceFolderId == null)
+        || (sourceFolderId.length() == 0)) {
+      throw new CmisInvalidArgumentException("Source and target folder must be set!");
+    }
+
+    // find the link
+    String link = loadLink(repositoryId, targetFolderId, Constants.REL_DOWN,
+        Constants.MEDIATYPE_CHILDREN);
+
+    if (link == null) {
+      throwLinkException(repositoryId, targetFolderId, Constants.REL_DOWN,
+          Constants.MEDIATYPE_CHILDREN);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_SOURCE_FOLDER_ID, sourceFolderId);
+
+    // set up object and writer
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(createIdObject(objectId.getValue()));
+
+    // post move request
+    HttpUtils.Response resp = post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+
+    // parse the response
+    AtomEntry entry = parse(resp.getStream(), AtomEntry.class);
+
+    objectId.setValue(entry.getId());
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#setContentStream(java.lang.String,
+   * org.apache.opencmis.client.provider.Holder, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.ContentStreamData,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void setContentStream(String repositoryId, Holder<String> objectId, Boolean overwriteFlag,
+      Holder<String> changeToken, ContentStreamData contentStream, ExtensionsData extension) {
+    // we need an object id
+    if ((objectId == null) || (objectId.getValue() == null)) {
+      throw new CmisInvalidArgumentException("Object ID must be set!");
+    }
+
+    // we need content
+    if ((contentStream == null) || (contentStream.getStream() == null)
+        || (contentStream.getMimeType() == null)) {
+      throw new CmisInvalidArgumentException("Content must be set!");
+    }
+
+    // find the link
+    String link = loadLink(repositoryId, objectId.getValue(), Constants.REL_EDITMEDIA, null);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId.getValue(), Constants.REL_EDITMEDIA, null);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    if (changeToken != null) {
+      url.addParameter(Constants.PARAM_CHANGE_TOKEN, changeToken.getValue());
+    }
+    url.addParameter(Constants.PARAM_OVERWRITE_FLAG, overwriteFlag);
+
+    final InputStream stream = contentStream.getStream();
+
+    // send content
+    HttpUtils.Response resp = HttpUtils.invokePUT(url, contentStream.getMimeType(),
+        new HttpUtils.Output() {
+          public void write(OutputStream out) throws Exception {
+            int b;
+            byte[] buffer = new byte[4096];
+
+            while ((b = stream.read(buffer)) > -1) {
+              out.write(buffer, 0, b);
+            }
+
+            stream.close();
+          }
+        }, getSession());
+
+    // check response code
+    if ((resp.getResponseCode() != 200) && (resp.getResponseCode() != 201)
+        && (resp.getResponseCode() != 204)) {
+      throw convertStatusCode(resp.getResponseCode(), resp.getResponseMessage(), resp
+          .getErrorContent(), null);
+    }
+
+    objectId.setValue(null);
+    if (changeToken != null) {
+      changeToken.setValue(null);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.ObjectService#deleteContentStream(java.lang.String,
+   * org.apache.opencmis.client.provider.Holder, org.apache.opencmis.client.provider.Holder,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void deleteContentStream(String repositoryId, Holder<String> objectId,
+      Holder<String> changeToken, ExtensionsData extension) {
+    // we need an object id
+    if ((objectId == null) || (objectId.getValue() == null)) {
+      throw new CmisInvalidArgumentException("Object ID must be set!");
+    }
+
+    // find the link
+    String link = loadLink(repositoryId, objectId.getValue(), Constants.REL_EDITMEDIA, null);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId.getValue(), Constants.REL_EDITMEDIA, null);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    if (changeToken != null) {
+      url.addParameter(Constants.PARAM_CHANGE_TOKEN, changeToken.getValue());
+    }
+
+    delete(url);
+
+    objectId.setValue(null);
+    if (changeToken != null) {
+      changeToken.setValue(null);
+    }
+  }
+
+  // ---- internal ----
+
+  private void checkCreateProperties(PropertiesData properties) {
+    if ((properties == null) || (properties.getProperties() == null)) {
+      throw new CmisInvalidArgumentException("Properties must be set!");
+    }
+
+    if (!properties.getProperties().containsKey(PropertyIds.CMIS_OBJECT_TYPE_ID)) {
+      throw new CmisInvalidArgumentException("Property " + PropertyIds.CMIS_OBJECT_TYPE_ID
+          + " must be set!");
+    }
+
+    if (properties.getProperties().containsKey(PropertyIds.CMIS_OBJECT_ID)) {
+      throw new CmisInvalidArgumentException("Property " + PropertyIds.CMIS_OBJECT_ID
+          + " must not be set!");
+    }
+  }
+
+  /**
+   * Handles ACL modifications of newly created objects.
+   */
+  private void handleAclModifications(String repositoryId, AtomEntry entry,
+      AccessControlList addAces, AccessControlList removeAces) {
+    if (!isAclMergeRequired(addAces, removeAces)) {
+      return;
+    }
+
+    AccessControlList originalAces = null;
+
+    // walk through the entry and find the current ACL
+    for (AtomElement element : entry.getElements()) {
+      if (element.getObject() instanceof CmisObjectType) {
+        // extract current ACL
+        CmisObjectType object = (CmisObjectType) element.getObject();
+        originalAces = convert(object.getAcl(), object.isExactACL());
+
+        break;
+      }
+    }
+
+    if (originalAces != null) {
+      // merge and update ACL
+      AccessControlList newACL = mergeAcls(originalAces, addAces, removeAces);
+      if (newACL != null) {
+        updateAcl(repositoryId, entry.getId(), newACL, null);
+      }
+    }
+  }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ObjectServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java?rev=934361&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java Thu Apr 15 10:33:49 2010
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
+
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
+
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.Session;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomFeed;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.api.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisProperty;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisPropertyId;
+import org.apache.chemistry.opencmis.commons.provider.ObjectData;
+import org.apache.chemistry.opencmis.commons.provider.PolicyService;
+
+/**
+ * Policy Service AtomPub client.
+ * 
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public class PolicyServiceImpl extends AbstractAtomPubService implements PolicyService {
+
+  /**
+   * Constructor.
+   */
+  public PolicyServiceImpl(Session session) {
+    setSession(session);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.PolicyService#applyPolicy(java.lang.String, java.lang.String,
+   * java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void applyPolicy(String repositoryId, String policyId, String objectId,
+      ExtensionsData extension) {
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_POLICIES, Constants.MEDIATYPE_FEED);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_POLICIES, Constants.MEDIATYPE_FEED);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+
+    // set up object and writer
+    final AtomEntryWriter entryWriter = new AtomEntryWriter(createIdObject(objectId));
+
+    // post applyPolicy request
+    post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+      public void write(OutputStream out) throws Exception {
+        entryWriter.write(out);
+      }
+    });
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.PolicyService#getAppliedPolicies(java.lang.String,
+   * java.lang.String, java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<ObjectData> getAppliedPolicies(String repositoryId, String objectId, String filter,
+      ExtensionsData extension) {
+    List<ObjectData> result = new ArrayList<ObjectData>();
+
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_POLICIES, Constants.MEDIATYPE_FEED);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_POLICIES, Constants.MEDIATYPE_FEED);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // get the policies
+    if (!feed.getEntries().isEmpty()) {
+      for (AtomEntry entry : feed.getEntries()) {
+        ObjectData policy = null;
+
+        // walk through the entry
+        for (AtomElement element : entry.getElements()) {
+          if (element.getObject() instanceof CmisObjectType) {
+            policy = convert((CmisObjectType) element.getObject());
+          }
+        }
+
+        if (policy != null) {
+          result.add(policy);
+        }
+      }
+    }
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.PolicyService#removePolicy(java.lang.String,
+   * java.lang.String, java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public void removePolicy(String repositoryId, String policyId, String objectId,
+      ExtensionsData extension) {
+    // we need a policy id
+    if (policyId == null) {
+      throw new CmisInvalidArgumentException("Policy id must be set!");
+    }
+
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_POLICIES, Constants.MEDIATYPE_FEED);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_POLICIES, Constants.MEDIATYPE_FEED);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_FILTER, PropertyIds.CMIS_OBJECT_ID);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // find the policy
+    String policyLink = null;
+    boolean found = false;
+
+    if (!feed.getEntries().isEmpty()) {
+      for (AtomEntry entry : feed.getEntries()) {
+        // walk through the entry
+        for (AtomElement element : entry.getElements()) {
+          if (element.getObject() instanceof AtomLink) {
+            AtomLink atomLink = (AtomLink) element.getObject();
+            if (Constants.REL_SELF.equals(atomLink.getRel())) {
+              policyLink = atomLink.getHref();
+            }
+          }
+          else if (element.getObject() instanceof CmisObjectType) {
+            String id = findIdProperty((CmisObjectType) element.getObject());
+            if (policyId.equals(id)) {
+              found = true;
+            }
+          }
+        }
+
+        if (found) {
+          break;
+        }
+      }
+    }
+
+    // if found, delete it
+    if (found && (policyLink != null)) {
+      delete(new UrlBuilder(policyLink));
+    }
+  }
+
+  /**
+   * Finds the id property within a CMIS object.
+   */
+  private String findIdProperty(CmisObjectType object) {
+    if ((object == null) || (object.getProperties() == null)) {
+      return null;
+    }
+
+    for (CmisProperty property : object.getProperties().getProperty()) {
+      if (PropertyIds.CMIS_OBJECT_ID.equals(property.getPropertyDefinitionId())
+          && (property instanceof CmisPropertyId)) {
+        List<String> values = ((CmisPropertyId) property).getValue();
+        if (values.size() == 1) {
+          return values.get(0);
+        }
+      }
+    }
+
+    return null;
+  }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/PolicyServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java?rev=934361&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java Thu Apr 15 10:33:49 2010
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
+
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.Session;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomFeed;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
+import org.apache.chemistry.opencmis.commons.api.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ObjectListImpl;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisObjectType;
+import org.apache.chemistry.opencmis.commons.provider.ObjectData;
+import org.apache.chemistry.opencmis.commons.provider.ObjectList;
+import org.apache.chemistry.opencmis.commons.provider.RelationshipService;
+
+/**
+ * Relationship Service AtomPub client.
+ * 
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public class RelationshipServiceImpl extends AbstractAtomPubService implements RelationshipService {
+
+  /**
+   * Constructor.
+   */
+  public RelationshipServiceImpl(Session session) {
+    setSession(session);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.RelationshipService#getObjectRelationships(java.lang.String
+   * , java.lang.String, java.lang.Boolean, org.apache.opencmis.commons.enums.RelationshipDirection,
+   * java.lang.String, java.lang.String, java.lang.Boolean, java.math.BigInteger,
+   * java.math.BigInteger, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public ObjectList getObjectRelationships(String repositoryId, String objectId,
+      Boolean includeSubRelationshipTypes, RelationshipDirection relationshipDirection,
+      String typeId, String filter, Boolean includeAllowableActions, BigInteger maxItems,
+      BigInteger skipCount, ExtensionsData extension) {
+    ObjectListImpl result = new ObjectListImpl();
+
+    // find the link
+    String link = loadLink(repositoryId, objectId, Constants.REL_RELATIONSHIPS,
+        Constants.MEDIATYPE_FEED);
+
+    if (link == null) {
+      throwLinkException(repositoryId, objectId, Constants.REL_RELATIONSHIPS,
+          Constants.MEDIATYPE_FEED);
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_SUB_RELATIONSHIP_TYPES, includeSubRelationshipTypes);
+    url.addParameter(Constants.PARAM_RELATIONSHIP_DIRECTION, relationshipDirection);
+    url.addParameter(Constants.PARAM_TYPE_ID, typeId);
+    url.addParameter(Constants.PARAM_FILTER, filter);
+    url.addParameter(Constants.PARAM_ALLOWABLE_ACTIONS, includeAllowableActions);
+    url.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+    url.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // handle top level
+    for (AtomElement element : feed.getElements()) {
+      if (element.getObject() instanceof AtomLink) {
+        if (isNextLink(element)) {
+          result.setHasMoreItems(Boolean.TRUE);
+        }
+      }
+      else if (isInt(NAME_NUM_ITEMS, element)) {
+        result.setNumItems((BigInteger) element.getObject());
+      }
+    }
+
+    // get the children
+    if (!feed.getEntries().isEmpty()) {
+      result.setObjects(new ArrayList<ObjectData>(feed.getEntries().size()));
+
+      for (AtomEntry entry : feed.getEntries()) {
+        ObjectData relationship = null;
+
+        lockLinks();
+        try {
+          // clean up cache
+          removeLinks(repositoryId, entry.getId());
+
+          // walk through the entry
+          for (AtomElement element : entry.getElements()) {
+            if (element.getObject() instanceof AtomLink) {
+              addLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+            }
+            else if (element.getObject() instanceof CmisObjectType) {
+              relationship = convert((CmisObjectType) element.getObject());
+            }
+          }
+        }
+        finally {
+          unlockLinks();
+        }
+
+        if (relationship != null) {
+          result.getObjects().add(relationship);
+        }
+      }
+
+    }
+
+    return result;
+  }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RelationshipServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java?rev=934361&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java Thu Apr 15 10:33:49 2010
@@ -0,0 +1,264 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
+
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.Session;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomElement;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomEntry;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomFeed;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomLink;
+import org.apache.chemistry.opencmis.commons.api.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.api.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.api.TypeDefinitionContainer;
+import org.apache.chemistry.opencmis.commons.api.TypeDefinitionList;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionListImpl;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisTypeDefinitionType;
+import org.apache.chemistry.opencmis.commons.provider.RepositoryInfoData;
+import org.apache.chemistry.opencmis.commons.provider.RepositoryService;
+
+/**
+ * Repository Service AtomPub client.
+ * 
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public class RepositoryServiceImpl extends AbstractAtomPubService implements RepositoryService {
+
+  /**
+   * Constructor.
+   */
+  public RepositoryServiceImpl(Session session) {
+    setSession(session);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see
+   * org.apache.opencmis.client.provider.RepositoryService#getRepositoryInfos(org.apache.opencmis
+   * .client.provider .ExtensionsData)
+   */
+  public List<RepositoryInfoData> getRepositoryInfos(ExtensionsData extension) {
+    return getRepositoriesInternal(null);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getRepositoryInfo(java.lang.String,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public RepositoryInfoData getRepositoryInfo(String repositoryId, ExtensionsData extension) {
+    List<RepositoryInfoData> repositoryInfos = getRepositoriesInternal(repositoryId);
+
+    // find the repository
+    for (RepositoryInfoData info : repositoryInfos) {
+      if (info.getRepositoryId() == null) {
+        continue;
+      }
+
+      if (info.getRepositoryId().equals(repositoryId)) {
+        return info;
+      }
+    }
+
+    throw new CmisObjectNotFoundException("Repository not found!");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getTypeDefinition(java.lang.String,
+   * java.lang.String, org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public TypeDefinition getTypeDefinition(String repositoryId, String typeId,
+      ExtensionsData extension) {
+    return getTypeDefinitionInternal(repositoryId, typeId);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getTypeChildren(java.lang.String,
+   * java.lang.String, java.lang.Boolean, java.math.BigInteger, java.math.BigInteger,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public TypeDefinitionList getTypeChildren(String repositoryId, String typeId,
+      Boolean includePropertyDefinitions, BigInteger maxItems, BigInteger skipCount,
+      ExtensionsData extension) {
+    TypeDefinitionListImpl result = new TypeDefinitionListImpl();
+
+    // find the link
+    String link = null;
+    if (typeId == null) {
+      link = loadCollection(repositoryId, Constants.COLLECTION_TYPES);
+    }
+    else {
+      link = loadTypeLink(repositoryId, typeId, Constants.REL_DOWN, Constants.MEDIATYPE_CHILDREN);
+    }
+
+    if (link == null) {
+      throw new CmisObjectNotFoundException("Unknown repository or type!");
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_TYPE_ID, typeId);
+    url.addParameter(Constants.PARAM_PROPERTY_DEFINITIONS, includePropertyDefinitions);
+    url.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+    url.addParameter(Constants.PARAM_SKIP_COUNT, skipCount);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // handle top level
+    for (AtomElement element : feed.getElements()) {
+      if (element.getObject() instanceof AtomLink) {
+        if (isNextLink(element)) {
+          result.setHasMoreItems(Boolean.TRUE);
+        }
+      }
+      else if (isInt(NAME_NUM_ITEMS, element)) {
+        result.setNumItems((BigInteger) element.getObject());
+      }
+    }
+
+    result.setList(new ArrayList<TypeDefinition>(feed.getEntries().size()));
+
+    // get the children
+    if (!feed.getEntries().isEmpty()) {
+      for (AtomEntry entry : feed.getEntries()) {
+        TypeDefinition child = null;
+
+        lockTypeLinks();
+        try {
+          // walk through the entry
+          for (AtomElement element : entry.getElements()) {
+            if (element.getObject() instanceof AtomLink) {
+              addTypeLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+            }
+            else if (element.getObject() instanceof CmisTypeDefinitionType) {
+              child = convert((CmisTypeDefinitionType) element.getObject());
+            }
+          }
+        }
+        finally {
+          unlockTypeLinks();
+        }
+
+        if (child != null) {
+          result.getList().add(child);
+        }
+      }
+    }
+
+    return result;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.opencmis.client.provider.RepositoryService#getTypeDescendants(java.lang.String,
+   * java.lang.String, java.math.BigInteger, java.lang.Boolean,
+   * org.apache.opencmis.client.provider.ExtensionsData)
+   */
+  public List<TypeDefinitionContainer> getTypeDescendants(String repositoryId, String typeId,
+      BigInteger depth, Boolean includePropertyDefinitions, ExtensionsData extension) {
+    List<TypeDefinitionContainer> result = new ArrayList<TypeDefinitionContainer>();
+
+    // find the link
+    String link = null;
+    if (typeId == null) {
+      link = loadRepositoryLink(repositoryId, Constants.REP_REL_TYPEDESC);
+    }
+    else {
+      link = loadTypeLink(repositoryId, typeId, Constants.REL_DOWN, Constants.MEDIATYPE_DESCENDANTS);
+    }
+
+    if (link == null) {
+      throw new CmisObjectNotFoundException("Unknown repository or type!");
+    }
+
+    UrlBuilder url = new UrlBuilder(link);
+    url.addParameter(Constants.PARAM_TYPE_ID, typeId);
+    url.addParameter(Constants.PARAM_DEPTH, depth);
+    url.addParameter(Constants.PARAM_PROPERTY_DEFINITIONS, includePropertyDefinitions);
+
+    // read and parse
+    HttpUtils.Response resp = read(url);
+    AtomFeed feed = parse(resp.getStream(), AtomFeed.class);
+
+    // process tree
+    addTypeDescendantsLevel(repositoryId, feed, result);
+
+    return result;
+  }
+
+  /**
+   * Adds type descendants level recursively.
+   */
+  private void addTypeDescendantsLevel(String repositoryId, AtomFeed feed,
+      List<TypeDefinitionContainer> containerList) {
+    if ((feed == null) || (feed.getEntries().isEmpty())) {
+      return;
+    }
+
+    // walk through the feed
+    for (AtomEntry entry : feed.getEntries()) {
+      TypeDefinitionContainerImpl childContainer = null;
+      List<TypeDefinitionContainer> childContainerList = new ArrayList<TypeDefinitionContainer>();
+
+      // walk through the entry
+      lockTypeLinks();
+      try {
+        for (AtomElement element : entry.getElements()) {
+          if (element.getObject() instanceof AtomLink) {
+            addTypeLink(repositoryId, entry.getId(), (AtomLink) element.getObject());
+          }
+          else if (element.getObject() instanceof CmisTypeDefinitionType) {
+            childContainer = new TypeDefinitionContainerImpl(
+                convert((CmisTypeDefinitionType) element.getObject()));
+          }
+          else if (element.getObject() instanceof AtomFeed) {
+            addTypeDescendantsLevel(repositoryId, (AtomFeed) element.getObject(),
+                childContainerList);
+          }
+        }
+      }
+      finally {
+        unlockTypeLinks();
+      }
+
+      if (childContainer != null) {
+        childContainer.setChildren(childContainerList);
+        containerList.add(childContainer);
+      }
+    }
+  }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/RepositoryServiceImpl.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java?rev=934361&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java Thu Apr 15 10:33:49 2010
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.atompub;
+
+/**
+ * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
+ * 
+ */
+public final class SpiSessionParameter {
+
+  public static final String LINK_CACHE = "org.apache.chemistry.opencmis.provider.atompub.linkcache";
+
+  private SpiSessionParameter() {
+  }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/SpiSessionParameter.java
------------------------------------------------------------------------------
    svn:keywords = Id