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 2012/02/24 22:46:55 UTC

svn commit: r1293440 [2/5] - in /chemistry/opencmis/branches/android: ./ chemistry-opencmis-android/ chemistry-opencmis-android/chemistry-opencmis-android-client/ chemistry-opencmis-android/chemistry-opencmis-android-client/src/ chemistry-opencmis-andr...

Added: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomPubParser.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomPubParser.java?rev=1293440&view=auto
==============================================================================
--- chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomPubParser.java (added)
+++ chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomPubParser.java Fri Feb 24 21:46:54 2012
@@ -0,0 +1,1098 @@
+/*
+ * 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.client.bindings.spi.atompub.CmisAtomPubConstants.ATTR_DOCUMENT_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.ATTR_FOLDER_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.ATTR_POLICY_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.ATTR_RELATIONSHIP_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.CONTENT_SRC;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.LINK_HREF;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.LINK_REL;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.LINK_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_ACL;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_ALLOWABLEACTIONS;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_CHILDREN;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_COLLECTION;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_COLLECTION_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_CONTENT;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_ENTRY;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_FEED;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_LINK;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_NUM_ITEMS;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_OBJECT;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_PATH_SEGMENT;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_RELATIVE_PATH_SEGMENT;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_REPOSITORY_INFO;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_SERVICE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_TEMPLATE_TEMPLATE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_TEMPLATE_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_TYPE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_URI_TEMPLATE;
+import static org.apache.chemistry.opencmis.client.bindings.spi.atompub.CmisAtomPubConstants.TAG_WORKSPACE;
+import static org.apache.chemistry.opencmis.commons.impl.JSONConstants.JSON_PROPERTY_DISPLAYNAME;
+import static org.apache.chemistry.opencmis.commons.impl.JSONConstants.JSON_PROPERTY_LOCALNAME;
+import static org.apache.chemistry.opencmis.commons.impl.JSONConstants.JSON_PROPERTY_QUERYNAME;
+import static org.apache.chemistry.opencmis.commons.impl.JSONConstants.JSON_PROPERTY_VALUE;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomAcl;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.AtomAllowableActions;
+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.client.bindings.spi.atompub.objects.RepositoryWorkspace;
+import org.apache.chemistry.opencmis.client.bindings.spi.atompub.objects.ServiceDoc;
+import org.apache.chemistry.opencmis.commons.data.Ace;
+import org.apache.chemistry.opencmis.commons.data.Acl;
+import org.apache.chemistry.opencmis.commons.data.AclCapabilities;
+import org.apache.chemistry.opencmis.commons.data.AllowableActions;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.PermissionMapping;
+import org.apache.chemistry.opencmis.commons.data.Properties;
+import org.apache.chemistry.opencmis.commons.data.PropertyData;
+import org.apache.chemistry.opencmis.commons.data.RenditionData;
+import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
+import org.apache.chemistry.opencmis.commons.definitions.PermissionDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.AtomPubConverter;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.JSONConstants;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlEntryImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlListImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AccessControlPrincipalDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PermissionDefinitionDataImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.PermissionMappingDataImpl;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.util.Xml;
+
+/**
+ * AtomPub Parser.
+ */
+public class AtomPubParser {
+
+    // public constants
+    public static final String LINK_REL_CONTENT = "@@content@@";
+
+    private final InputStream stream;
+    private AtomBase parseResult;
+
+    public AtomPubParser(InputStream stream) {
+        if (stream == null) {
+            throw new IllegalArgumentException("No stream.");
+        }
+
+        this.stream = stream;
+    }
+
+    /**
+     * Parses the stream.
+     */
+    public void parse() throws Exception {
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(stream, null);
+        // XMLInputFactory factory = XMLInputFactory.newInstance();
+        // XmlPullParser parser = factory.createXmlPullParser(stream);
+
+        try {
+            while (true) {
+                int event = parser.getEventType();
+                if (event == XmlPullParser.START_TAG) {
+                    QName name = new QName(parser.getNamespace(), parser.getName());
+
+                    if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+                        if (TAG_FEED.equals(name.getLocalPart())) {
+                            parseResult = parseFeed(parser);
+                            break;
+                        } else if (TAG_ENTRY.equals(name.getLocalPart())) {
+                            parseResult = parseEntry(parser);
+                            break;
+                        }
+                    } else if (Constants.NAMESPACE_CMIS.equals(name.getNamespaceURI())) {
+                        if (TAG_ALLOWABLEACTIONS.equals(name.getLocalPart())) {
+                            parseResult = new AtomAllowableActions(parseAllowableActions(parser));
+                            break;
+                        } else if (TAG_ACL.equals(name.getLocalPart())) {
+                            parseResult = new AtomAcl(parseACL(parser));
+                            break;
+                        }
+                    } else if (Constants.NAMESPACE_APP.equals(name.getNamespaceURI())) {
+                        if (TAG_SERVICE.equals(name.getLocalPart())) {
+                            parseResult = parseServiceDoc(parser);
+                            break;
+                        }
+                    }
+                }
+
+                if (!next(parser)) {
+                    break;
+                }
+            }
+
+            // parser.close();
+        } finally {
+            // make sure the stream is read and closed in all cases
+            try {
+                byte[] buffer = new byte[4096];
+                while (stream.read(buffer) > -1) {
+                }
+            } catch (Exception e) {
+            }
+
+            try {
+                stream.close();
+            } catch (Exception e) {
+            }
+        }
+    }
+
+    /**
+     * Return the parse results.
+     */
+    public AtomBase getResults() {
+        return parseResult;
+    }
+
+    /**
+     * Parses a service document.
+     */
+    private static ServiceDoc parseServiceDoc(XmlPullParser parser) throws Exception {
+        ServiceDoc result = new ServiceDoc();
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                QName name = new QName(parser.getNamespace(), parser.getName());
+
+                if (Constants.NAMESPACE_APP.equals(name.getNamespaceURI())) {
+                    if (TAG_WORKSPACE.equals(name.getLocalPart())) {
+                        result.addWorkspace(parseWorkspace(parser));
+                    } else {
+                        skip(parser);
+                    }
+                } else {
+                    skip(parser);
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Parses a workspace element in a service document.
+     */
+    private static RepositoryWorkspace parseWorkspace(XmlPullParser parser) throws Exception {
+        RepositoryWorkspace workspace = new RepositoryWorkspace();
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                AtomElement element = parseWorkspaceElement(parser);
+
+                // check if we can extract the workspace id
+                if ((element != null) && (element.getObject() instanceof RepositoryInfo)) {
+                    workspace.setId(((RepositoryInfo) element.getObject()).getId());
+                }
+
+                // add to workspace
+                workspace.addElement(element);
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return workspace;
+    }
+
+    /**
+     * Parses an Atom feed.
+     */
+    private AtomFeed parseFeed(XmlPullParser parser) throws Exception {
+        AtomFeed result = new AtomFeed();
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                QName name = new QName(parser.getNamespace(), parser.getName());
+
+                if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+                    if (TAG_LINK.equals(name.getLocalPart())) {
+                        result.addElement(parseLink(parser));
+                    } else if (TAG_ENTRY.equals(name.getLocalPart())) {
+                        result.addEntry(parseEntry(parser));
+                    } else {
+                        skip(parser);
+                    }
+                } else if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+                    if (TAG_NUM_ITEMS.equals(name.getLocalPart())) {
+                        result.addElement(parseBigInteger(parser));
+                    } else {
+                        skip(parser);
+                    }
+                } else {
+                    skip(parser);
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return result;
+    }
+
+    /**
+     * Parses an Atom entry.
+     */
+    private AtomEntry parseEntry(XmlPullParser parser) throws Exception {
+        AtomEntry result = new AtomEntry();
+
+        next(parser);
+
+        // walk through all tags in entry
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                AtomElement element = parseElement(parser);
+                if (element != null) {
+                    // add to entry
+                    result.addElement(element);
+
+                    // find and set object id
+                    if (element.getObject() instanceof ObjectData) {
+                        result.setId(((ObjectData) element.getObject()).getId());
+                    } else if (element.getObject() instanceof TypeDefinition) {
+                        result.setId(((TypeDefinition) element.getObject()).getId());
+                    }
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return result;
+    }
+
+    /**
+     * Parses an element.
+     */
+    private AtomElement parseElement(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+
+        if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+            if (TAG_OBJECT.equals(name.getLocalPart())) {
+                return new AtomElement(name, parseObject(parser));
+                // return unmarshalElement(parser, CmisObjectType.class);
+            } else if (TAG_PATH_SEGMENT.equals(name.getLocalPart())
+                    || TAG_RELATIVE_PATH_SEGMENT.equals(name.getLocalPart())) {
+                return parseText(parser);
+            } else if (TAG_TYPE.equals(name.getLocalPart())) {
+                // workaround for old Chemistry code - ignore the type namespace
+                String typeAttr = parser.getAttributeValue(Constants.NAMESPACE_XSI, "type");
+                if (typeAttr == null) {
+                    return new AtomElement(name, parseTypeDefinition(parser, null));
+                    // return unmarshalElement(parser,
+                    // CmisTypeDefinitionType.class);
+                } else if (typeAttr.endsWith(ATTR_DOCUMENT_TYPE)) {
+                    return new AtomElement(name, parseTypeDefinition(parser, BaseTypeId.CMIS_DOCUMENT));
+                    // return unmarshalElement(parser,
+                    // CmisTypeDocumentDefinitionType.class);
+                } else if (typeAttr.endsWith(ATTR_FOLDER_TYPE)) {
+                    return new AtomElement(name, parseTypeDefinition(parser, BaseTypeId.CMIS_FOLDER));
+                    // return unmarshalElement(parser,
+                    // CmisTypeFolderDefinitionType.class);
+                } else if (typeAttr.endsWith(ATTR_RELATIONSHIP_TYPE)) {
+                    return new AtomElement(name, parseTypeDefinition(parser, BaseTypeId.CMIS_RELATIONSHIP));
+                    // return unmarshalElement(parser,
+                    // CmisTypeRelationshipDefinitionType.class);
+                } else if (typeAttr.endsWith(ATTR_POLICY_TYPE)) {
+                    return new AtomElement(name, parseTypeDefinition(parser, BaseTypeId.CMIS_POLICY));
+                    // return unmarshalElement(parser,
+                    // CmisTypePolicyDefinitionType.class);
+                }
+                throw new CmisRuntimeException("Cannot read type definition!");
+            } else if (TAG_CHILDREN.equals(name.getLocalPart())) {
+                return parseChildren(parser);
+            }
+        } else if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+            if (TAG_LINK.equals(name.getLocalPart())) {
+                return parseLink(parser);
+            } else if (TAG_CONTENT.equals(name.getLocalPart())) {
+                return parseAtomContentSrc(parser);
+            }
+        }
+
+        // we don't know it - skip it
+        skip(parser);
+
+        return null;
+    }
+
+    /**
+     * Unmarshals a JAXB element.
+     */
+    private static <T> AtomElement unmarshalElement(XmlPullParser parser, Class<T> cmisType) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+
+        // Unmarshaller u = JaxBHelper.createUnmarshaller();
+        // JAXBElement<T> object = u.unmarshal(parser, cmisType);
+
+        // return new AtomElement(name, object.getValue());
+
+        // Serializer serializer = new Persister();
+        // parser.get
+
+        // Example example = serializer.read(CmisRepositoryInfoType.class,
+        // parser);
+        parser.next();
+        return new AtomElement(name, null);
+        // return null;
+    }
+
+    /**
+     * Parses a children element.
+     */
+    private AtomElement parseChildren(XmlPullParser parser) throws Exception {
+        AtomElement result = null;
+        QName childName = new QName(parser.getNamespace(), parser.getName());
+
+        next(parser);
+
+        // walk through the children tag
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                QName name = new QName(parser.getNamespace(), parser.getName());
+
+                if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+                    if (TAG_FEED.equals(name.getLocalPart())) {
+                        result = new AtomElement(childName, parseFeed(parser));
+                    } else {
+                        skip(parser);
+                    }
+                } else {
+                    skip(parser);
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return result;
+    }
+
+    /**
+     * Parses a workspace element.
+     */
+    private static AtomElement parseWorkspaceElement(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+
+        if (Constants.NAMESPACE_RESTATOM.equals(name.getNamespaceURI())) {
+            if (TAG_REPOSITORY_INFO.equals(name.getLocalPart())) {
+                return new AtomElement(name, parseRepositoryInfo(parser));
+            } else if (TAG_URI_TEMPLATE.equals(name.getLocalPart())) {
+                return parseTemplate(parser);
+            }
+        } else if (Constants.NAMESPACE_ATOM.equals(name.getNamespaceURI())) {
+            if (TAG_LINK.equals(name.getLocalPart())) {
+                return parseLink(parser);
+            }
+        } else if (Constants.NAMESPACE_APP.equals(name.getNamespaceURI())) {
+            if (TAG_COLLECTION.equals(name.getLocalPart())) {
+                return parseCollection(parser);
+            }
+        }
+
+        // we don't know it - skip it
+        skip(parser);
+
+        return null;
+    }
+
+    /**
+     * Parses a collection tag.
+     */
+    private static AtomElement parseCollection(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+        Map<String, String> result = new HashMap<String, String>();
+
+        result.put("href", parser.getAttributeValue(null, "href"));
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                QName tagName = new QName(parser.getNamespace(), parser.getName());
+                if (Constants.NAMESPACE_RESTATOM.equals(tagName.getNamespaceURI())
+                        && TAG_COLLECTION_TYPE.equals(tagName.getLocalPart())) {
+                    result.put("collectionType", readText(parser));
+                } else {
+                    skip(parser);
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return new AtomElement(name, result);
+    }
+
+    /**
+     * Parses a template tag.
+     */
+    private static AtomElement parseTemplate(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+        Map<String, String> result = new HashMap<String, String>();
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                QName tagName = new QName(parser.getNamespace(), parser.getName());
+                if (Constants.NAMESPACE_RESTATOM.equals(tagName.getNamespaceURI())) {
+                    if (TAG_TEMPLATE_TEMPLATE.equals(tagName.getLocalPart())) {
+                        result.put("template", readText(parser));
+                    } else if (TAG_TEMPLATE_TYPE.equals(tagName.getLocalPart())) {
+                        result.put("type", readText(parser));
+                    } else {
+                        skip(parser);
+                    }
+                } else {
+                    skip(parser);
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                break;
+            } else {
+                if (!next(parser)) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+
+        return new AtomElement(name, result);
+    }
+
+    /**
+     * Parses a link tag.
+     */
+    private static AtomElement parseLink(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+        AtomLink result = new AtomLink();
+
+        // save attributes
+        for (int i = 0; i < parser.getAttributeCount(); i++) {
+            if (LINK_REL.equals(parser.getAttributeName(i))) {
+                result.setRel(parser.getAttributeValue(i));
+            } else if (LINK_HREF.equals(parser.getAttributeName(i))) {
+                result.setHref(parser.getAttributeValue(i));
+            } else if (LINK_TYPE.equals(parser.getAttributeName(i))) {
+                result.setType(parser.getAttributeValue(i));
+            }
+        }
+
+        // skip enclosed tags, if any
+        skip(parser);
+
+        return new AtomElement(name, result);
+    }
+
+    /**
+     * Parses a link tag.
+     */
+    private static AtomElement parseAtomContentSrc(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+        AtomLink result = new AtomLink();
+        result.setRel(LINK_REL_CONTENT);
+
+        // save attributes
+        for (int i = 0; i < parser.getAttributeCount(); i++) {
+            if (CONTENT_SRC.equals(parser.getAttributeName(i))) {
+                result.setHref(parser.getAttributeValue(i));
+            }
+        }
+
+        // skip enclosed tags, if any
+        skip(parser);
+
+        return new AtomElement(name, result);
+    }
+
+    /**
+     * Parses a text tag.
+     */
+    private static AtomElement parseText(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+        return new AtomElement(name, readText(parser));
+    }
+
+    /**
+     * Parses a text tag and convert it into an integer.
+     */
+    private static AtomElement parseBigInteger(XmlPullParser parser) throws Exception {
+        QName name = new QName(parser.getNamespace(), parser.getName());
+        return new AtomElement(name, new BigInteger(readText(parser)));
+    }
+
+    /**
+     * Parses a tag that contains text.
+     */
+    private static String readText(XmlPullParser parser) throws Exception {
+        StringBuilder sb = new StringBuilder();
+
+        next(parser);
+
+        while (true) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.END_TAG) {
+                break;
+            } else if (event == XmlPullParser.TEXT) {
+                String s = parser.getText();
+                if (s != null) {
+                    sb.append(s);
+                }
+            } else if (event == XmlPullParser.START_TAG) {
+                throw new RuntimeException("Unexpected tag: " + parser.getName());
+            }
+
+            if (!next(parser)) {
+                break;
+            }
+        }
+
+        next(parser);
+
+        return sb.toString();
+    }
+
+    /**
+     * Skips a tag or subtree.
+     */
+    private static void skip(XmlPullParser parser) throws Exception {
+        int level = 1;
+        while (next(parser)) {
+            int event = parser.getEventType();
+            if (event == XmlPullParser.START_TAG) {
+                level++;
+            } else if (event == XmlPullParser.END_TAG) {
+                level--;
+                if (level == 0) {
+                    break;
+                }
+            }
+        }
+
+        next(parser);
+    }
+
+    private static boolean next(XmlPullParser parser) throws Exception {
+        parser.next();
+        return true;
+    }
+
+    // -----------------------------------------------------------------------------------
+    // ------------- NEW ANDROID METHOD
+    // -----------------------------------------------------------------------------------
+
+    private static RepositoryInfo parseRepositoryInfo(XmlPullParser parser) throws Exception {
+        int eventType = parser.getEventType();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+        Map<String, String> repositoryInfoRawValues = new HashMap<String, String>(15);
+        Map<String, String> repositoryCapabilitiesRawValues = new HashMap<String, String>(15);
+        AclCapabilities aclCapabilities = null;
+        List<String> changesOnType = new ArrayList<String>();
+
+        while (!(eventType == XmlPullParser.END_TAG && Constants.SELECTOR_REPOSITORY_INFO.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (JSONConstants.JSON_REPINFO_CAPABILITIES.equals(name)) {
+                    eventType = parser.next();
+                    name = parser.getName();
+                    while (!(eventType == XmlPullParser.END_TAG && JSONConstants.JSON_REPINFO_CAPABILITIES.equals(name))) {
+                        switch (eventType) {
+                        case XmlPullParser.START_TAG:
+                            parser.next();
+                            repositoryCapabilitiesRawValues.put(name, parser.getText());
+                            break;
+                        }
+                        eventType = parser.next();
+                        name = parser.getName();
+                    }
+                } else if ("aclCapability".equals(name)) {
+                    aclCapabilities = parseAclCapabilities(parser);
+                } else if (JSONConstants.JSON_REPINFO_CHANGES_ON_TYPE.equals(name)) {
+                    parser.next();
+                    changesOnType.add(parser.getText());
+                } else if (Constants.NAMESPACE_CMIS.equals(namespace)) {
+                    parser.next();
+                    repositoryInfoRawValues.put(name, parser.getText());
+                }
+
+                break;
+
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        parser.next();
+        return AtomPubConverter.convertRepositoryInfo(repositoryInfoRawValues, repositoryCapabilitiesRawValues,
+                aclCapabilities, changesOnType);
+    }
+
+    public static final String PROPERTY = "property";
+
+    private static TypeDefinition parseTypeDefinition(XmlPullParser parser, BaseTypeId type) throws Exception {
+        Map<String, String> definitionRawValues = new HashMap<String, String>(15);
+        List<PropertyDefinition<?>> propertyDefinitionList = new ArrayList<PropertyDefinition<?>>(10);
+
+        int eventType = parser.getEventType();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+
+        while (!(eventType == XmlPullParser.END_TAG && CmisAtomPubConstants.TAG_TEMPLATE_TYPE.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (name.startsWith(PROPERTY)) {
+                    propertyDefinitionList.add(parsePropertyDefinition(parser));
+                } else if (Constants.NAMESPACE_CMIS.equals(namespace)) {
+                    parser.next();
+                    definitionRawValues.put(name, parser.getText());
+                }
+
+                break;
+
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        parser.next();
+        return AtomPubConverter.convertTypeDefinition(type, definitionRawValues, propertyDefinitionList);
+    }
+
+    private static PropertyDefinition<?> parsePropertyDefinition(XmlPullParser parser) throws Exception {
+        String id = null;
+        Map<String, String> propertyTypeRawValues = new HashMap<String, String>(15);
+        id = parser.getName();
+        int eventType = parser.next();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+
+        while (!(eventType == XmlPullParser.END_TAG && id.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (Constants.NAMESPACE_CMIS.equals(namespace)) {
+                    parser.next();
+                    propertyTypeRawValues.put(name, parser.getText());
+                }
+                break;
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        return AtomPubConverter.convertPropertyDefinition(id, propertyTypeRawValues);
+    }
+
+    public static ObjectData parseObject(XmlPullParser parser) throws Exception {
+        List<RenditionData> renditions = new ArrayList<RenditionData>(3);
+        Properties properties = null;
+        AllowableActions allowableActions = null;
+        Acl acl = null;
+
+        int eventType = parser.getEventType();
+        String name = parser.getName();
+
+        while (!(eventType == XmlPullParser.END_TAG && Constants.SELECTOR_OBJECT.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (name.startsWith(PROPERTY)) {
+                    properties = parseProperties(parser);
+                } else if (Constants.SELECTOR_ALLOWABLEACTIONS.equals(name)) {
+                    allowableActions = parseAllowableActions(parser);
+                } else if (Constants.SELECTOR_ACL.equals(name)) {
+                    acl = parseACL(parser);
+                } else if (Constants.SELECTOR_RENDITIONS.equals(name)) {
+                    renditions.add(parseRenditions(parser));
+                }
+                break;
+
+            }
+            eventType = parser.next();
+            name = parser.getName();
+        }
+
+        // Important !
+        parser.next();
+
+        return AtomPubConverter.convertObject(properties, allowableActions, acl, renditions);
+    }
+
+    /**
+     * Converts properties.
+     * 
+     * @throws IOException
+     * @throws XmlPullParserException
+     */
+    public static Properties parseProperties(XmlPullParser parser) throws Exception {
+        if (parser == null) {
+            return null;
+        }
+
+        int eventType = parser.getEventType();
+        String name = parser.getName();
+        String nameSpace = parser.getNamespace();
+        int countParam = 0;
+        String id = null, displayName = null, queryName = null, localName = null, paramName = null, tag = null;
+        List<String> values = null;
+        List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
+
+        while (!(eventType == XmlPullParser.END_TAG && Constants.SELECTOR_PROPERTIES.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+
+                // Extension skip data
+                if (!Constants.NAMESPACE_CMIS.equals(nameSpace)) {
+                    skip(parser);
+                    eventType = parser.getEventType();
+                    name = parser.getName();
+                    nameSpace = parser.getNamespace();
+                    continue;
+                }
+
+                tag = name;
+
+                // attributes
+                countParam = parser.getAttributeCount();
+                displayName = null;
+                queryName = null;
+                localName = null;
+                paramName = null;
+                for (int i = 0; i < countParam; i++) {
+                    paramName = parser.getAttributeName(i);
+                    if (JSON_PROPERTY_DISPLAYNAME.equals(paramName)) {
+                        displayName = parser.getAttributeValue(i);
+                    } else if (JSON_PROPERTY_QUERYNAME.equals(paramName)) {
+                        queryName = parser.getAttributeValue(i);
+                    } else if (JSON_PROPERTY_LOCALNAME.equals(paramName)) {
+                        localName = parser.getAttributeValue(i);
+                    } else if ("propertyDefinitionId".equals(paramName)) {
+                        id = parser.getAttributeValue(i);
+                    }
+                }
+
+                // Values
+                values = new ArrayList<String>(2);
+                while (!(eventType == XmlPullParser.END_TAG && tag.equals(name))) {
+                    switch (eventType) {
+                    case XmlPullParser.START_TAG:
+                        if (JSON_PROPERTY_VALUE.equals(name)) {
+                            parser.next();
+                            values.add(parser.getText());
+                        }
+                        break;
+                    }
+                    eventType = parser.next();
+                    name = parser.getName();
+                }
+
+                // Convert
+                properties.add(AtomPubConverter.convertProperty(tag, id, displayName, queryName, localName, values));
+                break;
+
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            nameSpace = parser.getNamespace();
+        }
+        return AtomPubConverter.convertProperties(properties);
+    }
+
+    public static RenditionData parseRenditions(XmlPullParser parser) throws Exception {
+        Map<String, String> rendition = new HashMap<String, String>(15);
+        int eventType = parser.next();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+
+        while (!(eventType == XmlPullParser.END_TAG && "rendition".equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (Constants.NAMESPACE_CMIS.equals(namespace)) {
+                    parser.next();
+                    rendition.put(name, parser.getText());
+                }
+                break;
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        return AtomPubConverter.convertRendition(rendition);
+    }
+
+    public static AllowableActions parseAllowableActions(XmlPullParser parser) throws Exception {
+        Map<String, String> allowableActionsRawValues = new HashMap<String, String>(15);
+        int eventType = parser.next();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+
+        while (!(eventType == XmlPullParser.END_TAG && Constants.SELECTOR_ALLOWABLEACTIONS.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (Constants.NAMESPACE_CMIS.equals(namespace)) {
+                    parser.next();
+                    allowableActionsRawValues.put(name, parser.getText());
+                }
+                break;
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        return AtomPubConverter.convertAllowableActions(allowableActionsRawValues);
+    }
+
+    public static AclCapabilities parseAclCapabilities(XmlPullParser parser) throws Exception {
+        Map<String, String> AclCapabilitiesRawValues = new HashMap<String, String>(15);
+        List<PermissionDefinition> permissionDefinitionList = new ArrayList<PermissionDefinition>();
+        Map<String, PermissionMapping> permMap = new HashMap<String, PermissionMapping>();
+
+        int eventType = parser.next();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+
+        while (!(eventType == XmlPullParser.END_TAG && "aclCapability".equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (Constants.NAMESPACE_CMIS.equals(namespace) && JSONConstants.JSON_ACLCAP_PERMISSIONS.equals(name)) {
+
+                    String permission = null, description = null;
+                    // Permissions
+                    while (!(eventType == XmlPullParser.END_TAG && JSONConstants.JSON_ACLCAP_PERMISSIONS.equals(name))) {
+                        switch (eventType) {
+                        case XmlPullParser.START_TAG:
+                            if (Constants.NAMESPACE_CMIS.equals(namespace)
+                                    && JSONConstants.JSON_ACLCAP_PERMISSION_PERMISSION.equals(name)) {
+                                parser.next();
+                                permission = parser.getText();
+                            } else if (Constants.NAMESPACE_CMIS.equals(namespace)
+                                    && JSONConstants.JSON_ACLCAP_PERMISSION_DESCRIPTION.equals(name)) {
+                                parser.next();
+                                description = parser.getText();
+                            }
+                            break;
+                        }
+                        eventType = parser.next();
+                        name = parser.getName();
+                    }
+                    PermissionDefinitionDataImpl permDef = new PermissionDefinitionDataImpl();
+                    permDef.setPermission(permission);
+                    permDef.setDescription(description);
+
+                    // convertExtension(permissionMap, permDef,
+                    // ACLCAP_PERMISSION_KEYS);
+
+                    permissionDefinitionList.add(permDef);
+
+                } else if (Constants.NAMESPACE_CMIS.equals(namespace) && "mapping".equals(name)) {
+
+                    String key = null;
+                    List<String> permList = new ArrayList<String>();
+                    // MAPPINGS
+                    while (!(eventType == XmlPullParser.END_TAG && "mapping".equals(name))) {
+                        switch (eventType) {
+                        case XmlPullParser.START_TAG:
+                            if (Constants.NAMESPACE_CMIS.equals(namespace)
+                                    && JSONConstants.JSON_ACLCAP_MAPPING_KEY.equals(name)) {
+                                parser.next();
+                                key = parser.getText();
+                            } else if (Constants.NAMESPACE_CMIS.equals(namespace)
+                                    && JSONConstants.JSON_ACLCAP_PERMISSION_PERMISSION.equals(name)) {
+                                parser.next();
+                                permList.add(parser.getText());
+                            }
+                            break;
+                        }
+                        eventType = parser.next();
+                        name = parser.getName();
+                    }
+                    PermissionMappingDataImpl mapping = new PermissionMappingDataImpl();
+                    mapping.setKey(key);
+                    mapping.setPermissions(permList);
+
+                    // convertExtension(permissionMap, mapping,
+                    // ACLCAP_MAPPING_KEYS);
+
+                    permMap.put(key, mapping);
+
+                } else if (Constants.NAMESPACE_CMIS.equals(namespace)) {
+                    parser.next();
+                    AclCapabilitiesRawValues.put(name, parser.getText());
+                }
+                break;
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        return AtomPubConverter.convertAclCapabilities(AclCapabilitiesRawValues, permissionDefinitionList, permMap);
+    }
+
+    private static Acl parseACL(XmlPullParser parser) throws Exception {
+        int eventType = parser.next();
+        String name = parser.getName();
+        String namespace = parser.getNamespace();
+        boolean isPermissionRootTag = false;
+        List<Ace> aces = new ArrayList<Ace>();
+        List<String> permissions = null;
+        AccessControlEntryImpl ace = null;
+
+        while (!(eventType == XmlPullParser.END_TAG && Constants.SELECTOR_ACL.equals(name))) {
+            switch (eventType) {
+            case XmlPullParser.START_TAG:
+                if (Constants.NAMESPACE_CMIS.equals(namespace)
+                        && JSONConstants.JSON_ACLCAP_PERMISSION_PERMISSION.equals(name)) {
+                    if (isPermissionRootTag == false) {
+                        isPermissionRootTag = true;
+                        permissions = new ArrayList<String>();
+                        ace = new AccessControlEntryImpl();
+                    } else {
+                        parser.next();
+                        permissions.add(parser.getText());
+                        parser.next();
+                    }
+                } else if (Constants.NAMESPACE_CMIS.equals(namespace) && JSONConstants.JSON_ACE_PRINCIPAL.equals(name)) {
+                    AccessControlPrincipalDataImpl principal = null;
+                    while (!(eventType == XmlPullParser.END_TAG && JSONConstants.JSON_ACE_PRINCIPAL.equals(name))) {
+                        switch (eventType) {
+                        case XmlPullParser.START_TAG:
+                            if (Constants.NAMESPACE_CMIS.equals(namespace)
+                                    && JSONConstants.JSON_ACE_PRINCIPAL_ID.equals(name)) {
+                                parser.next();
+                                principal = new AccessControlPrincipalDataImpl();
+                                principal.setPrincipalId(parser.getText());
+                            }
+                            break;
+                        }
+                        eventType = parser.next();
+                        name = parser.getName();
+                        namespace = parser.getNamespace();
+                    }
+                    // convertExtension(jsonPrincipal, principal,
+                    // PRINCIPAL_KEYS);
+                    ace.setPrincipal(principal);
+                } else if (Constants.NAMESPACE_CMIS.equals(namespace) && "direct".equals(name)) {
+                    parser.next();
+                    Boolean isDirect = Boolean.parseBoolean(parser.getText());
+                    ace.setDirect(isDirect != null ? isDirect.booleanValue() : true);
+                }
+                break;
+            case XmlPullParser.END_TAG:
+                if (Constants.NAMESPACE_CMIS.equals(namespace)
+                        && JSONConstants.JSON_ACLCAP_PERMISSION_PERMISSION.equals(name)) {
+                    isPermissionRootTag = false;
+                    ace.setPermissions(permissions);
+                    aces.add(ace);
+                }
+                break;
+            }
+            eventType = parser.next();
+            name = parser.getName();
+            namespace = parser.getNamespace();
+        }
+
+        AccessControlListImpl result = new AccessControlListImpl();
+        result.setAces(aces);
+        // result.setExact(isExact);
+
+        // convertExtension(json, result, ACL_KEYS);
+
+        return result;
+    }
+
+}

Propchange: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomPubParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubConstants.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubConstants.java?rev=1293440&view=auto
==============================================================================
--- chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubConstants.java (added)
+++ chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubConstants.java Fri Feb 24 21:46:54 2012
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+/**
+ * Constants for AtomPub.
+ */
+public final class CmisAtomPubConstants {
+
+    private CmisAtomPubConstants() {
+    }
+
+    // service doc
+    public static final String TAG_SERVICE = "service";
+    public static final String TAG_WORKSPACE = "workspace";
+    public static final String TAG_REPOSITORY_INFO = "repositoryInfo";
+    public static final String TAG_COLLECTION = "collection";
+    public static final String TAG_COLLECTION_TYPE = "collectionType";
+    public static final String TAG_URI_TEMPLATE = "uritemplate";
+    public static final String TAG_TEMPLATE_TEMPLATE = "template";
+    public static final String TAG_TEMPLATE_TYPE = "type";
+    public static final String TAG_LINK = "link";
+
+    // atom
+    public static final String TAG_ATOM_ID = "id";
+    public static final String TAG_ATOM_TITLE = "title";
+    public static final String TAG_ATOM_UPDATED = "updated";
+
+    // feed
+    public static final String TAG_FEED = "feed";
+
+    // entry
+    public static final String TAG_ENTRY = "entry";
+    public static final String TAG_OBJECT = "object";
+    public static final String TAG_NUM_ITEMS = "numItems";
+    public static final String TAG_PATH_SEGMENT = "pathSegment";
+    public static final String TAG_RELATIVE_PATH_SEGMENT = "relativePathSegment";
+    public static final String TAG_TYPE = "type";
+    public static final String TAG_CHILDREN = "children";
+    public static final String TAG_CONTENT = "content";
+    public static final String TAG_CONTENT_MEDIATYPE = "mediatype";
+    public static final String TAG_CONTENT_BASE64 = "base64";
+
+    public static final String ATTR_DOCUMENT_TYPE = "cmisTypeDocumentDefinitionType";// CmisTypeDocumentDefinitionType.class.getAnnotation(XmlType.class).name();
+    public static final String ATTR_FOLDER_TYPE = "cmisTypeFolderDefinitionType";// CmisTypeFolderDefinitionType.class.getAnnotation(XmlType.class).name();
+    public static final String ATTR_RELATIONSHIP_TYPE = "cmisTypeRelationshipDefinitionType"; // CmisTypeRelationshipDefinitionType.class.getAnnotation(XmlType.class).name();
+    public static final String ATTR_POLICY_TYPE = "cmisTypePolicyDefinitionType"; // CmisTypePolicyDefinitionType.class.getAnnotation(XmlType.class).name();
+
+    // allowable actions
+    public static final String TAG_ALLOWABLEACTIONS = "allowableActions";
+
+    // ACL
+    public static final String TAG_ACL = "acl";
+
+    // links
+    public static final String LINK_REL = "rel";
+    public static final String LINK_HREF = "href";
+    public static final String LINK_TYPE = "type";
+    public static final String CONTENT_SRC = "src";
+
+}

Propchange: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubSpi.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubSpi.java?rev=1293440&view=auto
==============================================================================
--- chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubSpi.java (added)
+++ chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubSpi.java Fri Feb 24 21:46:54 2012
@@ -0,0 +1,118 @@
+/*
+ * 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 org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
+import org.apache.chemistry.opencmis.client.bindings.spi.CmisSpi;
+import org.apache.chemistry.opencmis.commons.spi.AclService;
+import org.apache.chemistry.opencmis.commons.spi.DiscoveryService;
+import org.apache.chemistry.opencmis.commons.spi.MultiFilingService;
+import org.apache.chemistry.opencmis.commons.spi.NavigationService;
+import org.apache.chemistry.opencmis.commons.spi.ObjectService;
+import org.apache.chemistry.opencmis.commons.spi.PolicyService;
+import org.apache.chemistry.opencmis.commons.spi.RelationshipService;
+import org.apache.chemistry.opencmis.commons.spi.RepositoryService;
+import org.apache.chemistry.opencmis.commons.spi.VersioningService;
+
+/**
+ * CMIS AtomPub SPI implementation.
+ */
+public class CmisAtomPubSpi implements CmisSpi {
+
+    private final BindingSession session;
+
+    private final RepositoryService repositoryService;
+    private final NavigationService navigationService;
+    private final ObjectService objectService;
+    private final VersioningService versioningService;
+    private final DiscoveryService discoveryService;
+    private final MultiFilingService multiFilingService;
+    private final RelationshipService relationshipService;
+    private final PolicyService policyService;
+    private final AclService aclService;
+
+    /**
+     * Constructor.
+     */
+    public CmisAtomPubSpi(BindingSession session) {
+
+        this.session = session;
+
+        repositoryService = new RepositoryServiceImpl(session);
+        navigationService = new NavigationServiceImpl(session);
+        objectService = new ObjectServiceImpl(session);
+        versioningService = new VersioningServiceImpl(session);
+        discoveryService = new DiscoveryServiceImpl(session);
+        multiFilingService = new MultiFilingServiceImpl(session);
+        relationshipService = new RelationshipServiceImpl(session);
+        policyService = new PolicyServiceImpl(session);
+        aclService = new AclServiceImpl(session);
+    }
+
+    public RepositoryService getRepositoryService() {
+        return repositoryService;
+    }
+
+    public NavigationService getNavigationService() {
+        return navigationService;
+    }
+
+    public ObjectService getObjectService() {
+        return objectService;
+    }
+
+    public DiscoveryService getDiscoveryService() {
+        return discoveryService;
+    }
+
+    public VersioningService getVersioningService() {
+        return versioningService;
+    }
+
+    public MultiFilingService getMultiFilingService() {
+        return multiFilingService;
+    }
+
+    public RelationshipService getRelationshipService() {
+        return relationshipService;
+    }
+
+    public PolicyService getPolicyService() {
+        return policyService;
+    }
+
+    public AclService getAclService() {
+        return aclService;
+    }
+
+    public void clearAllCaches() {
+        session.remove(SpiSessionParameter.LINK_CACHE);
+    }
+
+    public void clearRepositoryCache(String repositoryId) {
+        LinkCache linkCache = (LinkCache) session.get(SpiSessionParameter.LINK_CACHE);
+        if (linkCache != null) {
+            linkCache.clearRepository(repositoryId);
+        }
+    }
+
+    public void close() {
+        // no-op for AtomPub
+    }
+}

Propchange: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/CmisAtomPubSpi.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/DiscoveryServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/DiscoveryServiceImpl.java?rev=1293440&view=auto
==============================================================================
--- chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/DiscoveryServiceImpl.java (added)
+++ chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/DiscoveryServiceImpl.java Fri Feb 24 21:46:54 2012
@@ -0,0 +1,194 @@
+/*
+ * 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.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
+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.client.bindings.spi.http.HttpUtils;
+import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.ObjectList;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+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.ObjectListImpl;
+import org.apache.chemistry.opencmis.commons.spi.DiscoveryService;
+import org.apache.chemistry.opencmis.commons.spi.Holder;
+
+/**
+ * Discovery Service AtomPub client.
+ */
+public class DiscoveryServiceImpl extends AbstractAtomPubService implements DiscoveryService {
+
+    /**
+     * Constructor.
+     */
+    public DiscoveryServiceImpl(BindingSession session) {
+        setSession(session);
+    }
+
+    public ObjectList getContentChanges(String repositoryId, Holder<String> changeLogToken, Boolean includeProperties,
+            String filter, Boolean includePolicyIds, Boolean includeACL, BigInteger maxItems, ExtensionsData extension) {
+        ObjectListImpl result = new ObjectListImpl();
+
+        // find the link
+        String link = loadRepositoryLink(repositoryId, Constants.REP_REL_CHANGES);
+
+        if (link == null) {
+            throw new CmisObjectNotFoundException("Unknown repository or content changes not supported!");
+        }
+
+        UrlBuilder url = new UrlBuilder(link);
+        url.addParameter(Constants.PARAM_CHANGE_LOG_TOKEN, (changeLogToken == null ? null : changeLogToken.getValue()));
+        url.addParameter(Constants.PARAM_PROPERTIES, includeProperties);
+        url.addParameter(Constants.PARAM_FILTER, filter);
+        url.addParameter(Constants.PARAM_POLICY_IDS, includePolicyIds);
+        url.addParameter(Constants.PARAM_ACL, includeACL);
+        url.addParameter(Constants.PARAM_MAX_ITEMS, maxItems);
+
+        // 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 changes
+        if (!feed.getEntries().isEmpty()) {
+            result.setObjects(new ArrayList<ObjectData>(feed.getEntries().size()));
+
+            for (AtomEntry entry : feed.getEntries()) {
+                ObjectData hit = null;
+
+                // walk through the entry
+                for (AtomElement element : entry.getElements()) {
+                    if (element.getObject() instanceof ObjectData) {
+                        hit = (ObjectData) element.getObject();
+                    }
+                }
+
+                if (hit != null) {
+                    result.getObjects().add(hit);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public ObjectList query(String repositoryId, String statement, Boolean searchAllVersions,
+            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_QUERY);
+
+        if (link == null) {
+            throw new CmisObjectNotFoundException("Unknown repository or query not supported!");
+        }
+
+        UrlBuilder url = new UrlBuilder(link);
+
+        // compile query request
+        // final CmisQueryType query = new CmisQueryType();
+        // query.setStatement(statement);
+        // query.setSearchAllVersions(searchAllVersions);
+        // query.setIncludeAllowableActions(includeAllowableActions);
+        // query.setIncludeRelationships(convert(EnumIncludeRelationships.class,
+        // includeRelationships));
+        // query.setRenditionFilter(renditionFilter);
+        // query.setMaxItems(maxItems);
+        // query.setSkipCount(skipCount);
+
+        final Map<String, String> queryParameters = new HashMap<String, String>(6);
+        queryParameters.put("statement", statement);
+        queryParameters.put(Constants.PARAM_ALLOWABLE_ACTIONS, searchAllVersions.toString());
+        // queryParameters.put(Constants.PARAM_RELATIONSHIPS,
+        // searchAllVersions);
+        queryParameters.put(Constants.PARAM_RENDITION_FILTER, renditionFilter);
+        queryParameters.put(Constants.PARAM_MAX_ITEMS, maxItems.toString());
+        queryParameters.put(Constants.PARAM_SKIP_COUNT, skipCount.toString());
+
+        // post the query and parse results
+        HttpUtils.Response resp = post(url, Constants.MEDIATYPE_QUERY, new HttpUtils.Output() {
+            public void write(OutputStream out) throws Exception {
+                // TODO
+                // JaxBHelper.marshal(JaxBHelper.CMIS_OBJECT_FACTORY.createQuery(query),
+                // out, false);
+                AtomEntryWriter.writeQuery(out, queryParameters);
+            }
+        });
+        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 result set
+        if (!feed.getEntries().isEmpty()) {
+            result.setObjects(new ArrayList<ObjectData>(feed.getEntries().size()));
+
+            for (AtomEntry entry : feed.getEntries()) {
+                ObjectData hit = null;
+
+                // walk through the entry
+                for (AtomElement element : entry.getElements()) {
+                    if (element.getObject() instanceof ObjectData) {
+                        hit = (ObjectData) element.getObject();
+                    }
+                }
+
+                if (hit != null) {
+                    result.getObjects().add(hit);
+                }
+            }
+        }
+
+        return result;
+    }
+
+}

Propchange: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/DiscoveryServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/LinkCache.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/LinkCache.java?rev=1293440&view=auto
==============================================================================
--- chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/LinkCache.java (added)
+++ chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/LinkCache.java Fri Feb 24 21:46:54 2012
@@ -0,0 +1,343 @@
+/*
+ * 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 java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.chemistry.opencmis.client.bindings.cache.Cache;
+import org.apache.chemistry.opencmis.client.bindings.cache.impl.CacheImpl;
+import org.apache.chemistry.opencmis.client.bindings.cache.impl.ContentTypeCacheLevelImpl;
+import org.apache.chemistry.opencmis.client.bindings.cache.impl.LruCacheLevelImpl;
+import org.apache.chemistry.opencmis.client.bindings.cache.impl.MapCacheLevelImpl;
+import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
+import org.apache.chemistry.opencmis.commons.SessionParameter;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
+import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
+
+/**
+ * Link cache.
+ */
+public class LinkCache implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final Set<String> KNOWN_LINKS = new HashSet<String>();
+
+    static {
+        KNOWN_LINKS.add(Constants.REL_ACL);
+        KNOWN_LINKS.add(Constants.REL_DOWN);
+        KNOWN_LINKS.add(Constants.REL_UP);
+        KNOWN_LINKS.add(Constants.REL_FOLDERTREE);
+        KNOWN_LINKS.add(Constants.REL_RELATIONSHIPS);
+        KNOWN_LINKS.add(Constants.REL_SELF);
+        KNOWN_LINKS.add(Constants.REL_ALLOWABLEACTIONS);
+        KNOWN_LINKS.add(Constants.REL_EDITMEDIA);
+        KNOWN_LINKS.add(Constants.REL_POLICIES);
+        KNOWN_LINKS.add(Constants.REL_VERSIONHISTORY);
+        KNOWN_LINKS.add(Constants.REL_WORKINGCOPY);
+        KNOWN_LINKS.add(AtomPubParser.LINK_REL_CONTENT);
+    }
+
+    private static final int CACHE_SIZE_REPOSITORIES = 10;
+    private static final int CACHE_SIZE_TYPES = 100;
+    private static final int CACHE_SIZE_OBJECTS = 400;
+
+    private final Cache linkCache;
+    private final Cache typeLinkCache;
+    private final Cache collectionLinkCache;
+    private final Cache templateCache;
+    private final Cache repositoryLinkCache;
+
+    /**
+     * Constructor.
+     */
+    public LinkCache(BindingSession session) {
+        int repCount = session.get(SessionParameter.CACHE_SIZE_REPOSITORIES, CACHE_SIZE_REPOSITORIES);
+        if (repCount < 1) {
+            repCount = CACHE_SIZE_REPOSITORIES;
+        }
+
+        int typeCount = session.get(SessionParameter.CACHE_SIZE_TYPES, CACHE_SIZE_TYPES);
+        if (typeCount < 1) {
+            typeCount = CACHE_SIZE_TYPES;
+        }
+
+        int objCount = session.get(SessionParameter.CACHE_SIZE_LINKS, CACHE_SIZE_OBJECTS);
+        if (objCount < 1) {
+            objCount = CACHE_SIZE_OBJECTS;
+        }
+
+        linkCache = new CacheImpl("Link Cache");
+        linkCache.initialize(new String[] {
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount, // repository
+                LruCacheLevelImpl.class.getName() + " " + LruCacheLevelImpl.MAX_ENTRIES + "=" + objCount, // id
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=12", // rel
+                ContentTypeCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=3,"
+                        + MapCacheLevelImpl.SINGLE_VALUE + "=true" // type
+        });
+
+        typeLinkCache = new CacheImpl("Type Link Cache");
+        typeLinkCache.initialize(new String[] {
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount, // repository
+                LruCacheLevelImpl.class.getName() + " " + LruCacheLevelImpl.MAX_ENTRIES + "=" + typeCount, // id
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=12", // rel
+                ContentTypeCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=3,"
+                        + MapCacheLevelImpl.SINGLE_VALUE + "=true"// type
+        });
+
+        collectionLinkCache = new CacheImpl("Collection Link Cache");
+        collectionLinkCache.initialize(new String[] {
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount, // repository
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=8" // collection
+        });
+
+        templateCache = new CacheImpl("URI Template Cache");
+        templateCache.initialize(new String[] {
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount, // repository
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=6" // type
+        });
+
+        repositoryLinkCache = new CacheImpl("Repository Link Cache");
+        repositoryLinkCache.initialize(new String[] {
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=" + repCount, // repository
+                MapCacheLevelImpl.class.getName() + " " + MapCacheLevelImpl.CAPACITY + "=6" // rel
+        });
+    }
+
+    /**
+     * Adds a link.
+     */
+    public void addLink(String repositoryId, String id, String rel, String type, String link) {
+        if (KNOWN_LINKS.contains(rel)) {
+            linkCache.put(link, repositoryId, id, rel, type);
+        } else if (Constants.REL_ALTERNATE.equals(rel)) {
+            // use streamId instead of type as discriminating parameter
+            String streamId = extractStreamId(link);
+            if (streamId != null) {
+                linkCache.put(link, repositoryId, id, rel, streamId);
+            }
+        }
+    }
+
+    /**
+     * Tries to extract a streamId from an alternate link.
+     */
+    // this is not strictly in the spec
+    protected String extractStreamId(String link) {
+        int i = link.lastIndexOf('?');
+        if (i > 0) {
+            String[] params = link.substring(i + 1).split("&");
+            for (String param : params) {
+                String[] parts = param.split("=", 2);
+                if (parts[0].equals(Constants.PARAM_STREAM_ID) && parts.length == 2) {
+                    return parts[1];
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Removes all links of an object.
+     */
+    public void removeLinks(String repositoryId, String id) {
+        linkCache.remove(repositoryId, id);
+    }
+
+    /**
+     * Gets a link.
+     */
+    public String getLink(String repositoryId, String id, String rel, String type) {
+        return (String) linkCache.get(repositoryId, id, rel, type);
+    }
+
+    /**
+     * Gets a link.
+     */
+    public String getLink(String repositoryId, String id, String rel) {
+        return getLink(repositoryId, id, rel, null);
+    }
+
+    /**
+     * Checks a link.
+     */
+    public int checkLink(String repositoryId, String id, String rel, String type) {
+        return linkCache.check(repositoryId, id, rel, type);
+    }
+
+    /**
+     * Locks the link cache.
+     */
+    public void lockLinks() {
+        linkCache.writeLock();
+    }
+
+    /**
+     * Unlocks the link cache.
+     */
+    public void unlockLinks() {
+        linkCache.writeUnlock();
+    }
+
+    /**
+     * Adds a type link.
+     */
+    public void addTypeLink(String repositoryId, String id, String rel, String type, String link) {
+        if (KNOWN_LINKS.contains(rel)) {
+            typeLinkCache.put(link, repositoryId, id, rel, type);
+        }
+    }
+
+    /**
+     * Removes all links of a type.
+     */
+    public void removeTypeLinks(String repositoryId, String id) {
+        typeLinkCache.remove(repositoryId, id);
+    }
+
+    /**
+     * Gets a type link.
+     */
+    public String getTypeLink(String repositoryId, String id, String rel, String type) {
+        return (String) typeLinkCache.get(repositoryId, id, rel, type);
+    }
+
+    /**
+     * Locks the type link cache.
+     */
+    public void lockTypeLinks() {
+        typeLinkCache.writeLock();
+    }
+
+    /**
+     * Unlocks the type link cache.
+     */
+    public void unlockTypeLinks() {
+        typeLinkCache.writeUnlock();
+    }
+
+    /**
+     * Adds a collection.
+     */
+    public void addCollection(String repositoryId, String collection, String link) {
+        collectionLinkCache.put(link, repositoryId, collection);
+    }
+
+    /**
+     * Gets a collection.
+     */
+    public String getCollection(String repositoryId, String collection) {
+        return (String) collectionLinkCache.get(repositoryId, collection);
+    }
+
+    /**
+     * Adds an URI template.
+     */
+    public void addTemplate(String repositoryId, String type, String link) {
+        templateCache.put(link, repositoryId, type);
+    }
+
+    /**
+     * Gets an URI template and replaces place holders with the given
+     * parameters.
+     */
+    public String getTemplateLink(String repositoryId, String type, Map<String, Object> parameters) {
+        String template = (String) templateCache.get(repositoryId, type);
+        if (template == null) {
+            return null;
+        }
+
+        StringBuilder result = new StringBuilder();
+        StringBuilder param = new StringBuilder();
+
+        boolean paramMode = false;
+        for (int i = 0; i < template.length(); i++) {
+            char c = template.charAt(i);
+
+            if (paramMode) {
+                if (c == '}') {
+                    paramMode = false;
+
+                    String paramValue = UrlBuilder.normalizeParameter(parameters.get(param.toString()));
+                    if (paramValue != null) {
+                        try {
+                            result.append(URLEncoder.encode(paramValue, "UTF-8"));
+                        } catch (UnsupportedEncodingException e) {
+                            result.append(paramValue);
+                        }
+                    }
+
+                    param = new StringBuilder();
+                } else {
+                    param.append(c);
+                }
+            } else {
+                if (c == '{') {
+                    paramMode = true;
+                } else {
+                    result.append(c);
+                }
+            }
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Adds a collection.
+     */
+    public void addRepositoryLink(String repositoryId, String rel, String link) {
+        repositoryLinkCache.put(link, repositoryId, rel);
+    }
+
+    /**
+     * Gets a collection.
+     */
+    public String getRepositoryLink(String repositoryId, String rel) {
+        return (String) repositoryLinkCache.get(repositoryId, rel);
+    }
+
+    /**
+     * Removes all entries of the given repository from the caches.
+     */
+    public void clearRepository(String repositoryId) {
+        linkCache.remove(repositoryId);
+        typeLinkCache.remove(repositoryId);
+        collectionLinkCache.remove(repositoryId);
+        templateCache.remove(repositoryId);
+        repositoryLinkCache.remove(repositoryId);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        return "Link Cache [link cache=" + linkCache + ", type link cache=" + typeLinkCache
+                + ", collection link cache=" + collectionLinkCache + ", repository link cache=" + repositoryLinkCache
+                + ",  template cache=" + templateCache + "]";
+    }
+}

Propchange: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/LinkCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/MultiFilingServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/MultiFilingServiceImpl.java?rev=1293440&view=auto
==============================================================================
--- chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/MultiFilingServiceImpl.java (added)
+++ chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/MultiFilingServiceImpl.java Fri Feb 24 21:46:54 2012
@@ -0,0 +1,96 @@
+/*
+ * 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 java.io.OutputStream;
+
+import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
+import org.apache.chemistry.opencmis.client.bindings.spi.http.HttpUtils;
+import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
+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.spi.MultiFilingService;
+
+/**
+ * MultiFiling Service AtomPub client.
+ */
+public class MultiFilingServiceImpl extends AbstractAtomPubService implements MultiFilingService {
+
+    /**
+     * Constructor.
+     */
+    public MultiFilingServiceImpl(BindingSession session) {
+        setSession(session);
+    }
+
+    public void addObjectToFolder(String repositoryId, String objectId, String folderId, Boolean allVersions,
+            ExtensionsData extension) {
+        if (objectId == null) {
+            throw new CmisInvalidArgumentException("Object id must be set!");
+        }
+
+        // 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_ALL_VERSIONS, allVersions);
+
+        // set up object and writer
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createIdObject(objectId));
+
+        // post addObjectToFolder request
+        post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+            public void write(OutputStream out) throws Exception {
+                entryWriter.write(out);
+            }
+        });
+    }
+
+    public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, ExtensionsData extension) {
+        if (objectId == null) {
+            throw new CmisInvalidArgumentException("Object id must be set!");
+        }
+
+        // find the link
+        String link = loadCollection(repositoryId, Constants.COLLECTION_UNFILED);
+
+        if (link == null) {
+            throw new CmisObjectNotFoundException("Unknown repository or unfiling not supported!");
+        }
+
+        UrlBuilder url = new UrlBuilder(link);
+        url.addParameter(Constants.PARAM_REMOVE_FROM, folderId);
+
+        // set up object and writer
+        final AtomEntryWriter entryWriter = new AtomEntryWriter(createIdObject(objectId));
+
+        // post removeObjectFromFolder request
+        post(url, Constants.MEDIATYPE_ENTRY, new HttpUtils.Output() {
+            public void write(OutputStream out) throws Exception {
+                entryWriter.write(out);
+            }
+        });
+    }
+}

Propchange: chemistry/opencmis/branches/android/chemistry-opencmis-android/chemistry-opencmis-android-client/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/MultiFilingServiceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native