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 2010/11/11 13:46:31 UTC

svn commit: r1033918 [2/3] - in /incubator/chemistry/opencmis/branches/client-api-refactoring: chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/ chemistry-opencmis-client/chemistry-opencmis-...

Added: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/FolderImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/FolderImpl.java?rev=1033918&view=auto
==============================================================================
--- incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/FolderImpl.java (added)
+++ incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/FolderImpl.java Thu Nov 11 12:46:30 2010
@@ -0,0 +1,463 @@
+/*
+ * 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.runtime;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.chemistry.opencmis.client.api.CmisObject;
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.FileableCmisObject;
+import org.apache.chemistry.opencmis.client.api.Folder;
+import org.apache.chemistry.opencmis.client.api.ObjectFactory;
+import org.apache.chemistry.opencmis.client.api.ObjectId;
+import org.apache.chemistry.opencmis.client.api.ObjectType;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.client.api.ItemIterable;
+import org.apache.chemistry.opencmis.client.api.Policy;
+import org.apache.chemistry.opencmis.client.api.Tree;
+import org.apache.chemistry.opencmis.client.runtime.util.AbstractPageFetcher;
+import org.apache.chemistry.opencmis.client.runtime.util.CollectionIterable;
+import org.apache.chemistry.opencmis.client.runtime.util.TreeImpl;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.Ace;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.ObjectInFolderContainer;
+import org.apache.chemistry.opencmis.commons.data.ObjectInFolderData;
+import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
+import org.apache.chemistry.opencmis.commons.data.ObjectList;
+import org.apache.chemistry.opencmis.commons.data.PropertyData;
+import org.apache.chemistry.opencmis.commons.data.PropertyString;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.enums.UnfileObject;
+import org.apache.chemistry.opencmis.commons.enums.Updatability;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.spi.NavigationService;
+
+public class FolderImpl extends AbstractFilableCmisObject implements Folder {
+
+    private static final Set<Updatability> CREATE_UPDATABILITY = new HashSet<Updatability>();
+    static {
+        CREATE_UPDATABILITY.add(Updatability.ONCREATE);
+        CREATE_UPDATABILITY.add(Updatability.READWRITE);
+    }
+
+    /**
+     * Constructor.
+     */
+    public FolderImpl(SessionImpl session, ObjectType objectType, ObjectData objectData,
+            OperationContext context) {
+        initialize(session, objectType, objectData, context);
+    }
+
+    public Document createDocument(Map<String, ?> properties, ContentStream contentStream,
+            VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces,
+            OperationContext context) {
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String objectId = getObjectId();
+
+        ObjectFactory of = getObjectFactory();
+
+        String newId = getBinding().getObjectService().createDocument(getRepositoryId(),
+                of.convertProperties(properties, null, CREATE_UPDATABILITY), objectId,
+                of.convertContentStream(contentStream), versioningState, of.convertPolicies(policies),
+                of.convertAces(addAces), of.convertAces(removeAces), null);
+
+        // if no context is provided the object will not be fetched
+        if ((context == null) || (newId == null)) {
+            return null;
+        }
+
+        // get the new object
+        CmisObject object = getSession().getObject(getSession().createObjectId(newId), context);
+        if (!(object instanceof Document)) {
+            throw new CmisRuntimeException("Newly created object is not a document! New id: " + newId);
+        }
+
+        return (Document) object;
+    }
+
+    public Document createDocumentFromSource(ObjectId source, Map<String, ?> properties,
+            VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces,
+            OperationContext context) {
+        if ((source == null) || (source.getId() == null)) {
+            throw new IllegalArgumentException("Source must be set!");
+        }
+
+        String objectId = getObjectId();
+
+        // get the type of the source document
+        ObjectType type = null;
+        if (source instanceof CmisObject) {
+            type = ((CmisObject) source).getType();
+        } else {
+            CmisObject sourceObj = getSession().getObject(source);
+            type = sourceObj.getType();
+        }
+
+        if (type.getBaseTypeId() != BaseTypeId.CMIS_DOCUMENT) {
+            throw new IllegalArgumentException("Source object must be a document!");
+        }
+
+        ObjectFactory of = getObjectFactory();
+
+        Set<Updatability> updatebility = new HashSet<Updatability>();
+        updatebility.add(Updatability.READWRITE);
+
+        String newId = getBinding().getObjectService().createDocumentFromSource(getRepositoryId(), source.getId(),
+                of.convertProperties(properties, type, updatebility), objectId, versioningState,
+                of.convertPolicies(policies), of.convertAces(addAces), of.convertAces(removeAces), null);
+
+        // if no context is provided the object will not be fetched
+        if ((context == null) || (newId == null)) {
+            return null;
+        }
+
+        // get the new object
+        CmisObject object = getSession().getObject(getSession().createObjectId(newId), context);
+        if (!(object instanceof Document)) {
+            throw new CmisRuntimeException("Newly created object is not a document! New id: " + newId);
+        }
+
+        return (Document) object;
+    }
+
+    public Folder createFolder(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces,
+            List<Ace> removeAces, OperationContext context) {
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String objectId = getObjectId();
+
+        ObjectFactory of = getObjectFactory();
+
+        String newId = getBinding().getObjectService().createFolder(getRepositoryId(),
+                of.convertProperties(properties, null, CREATE_UPDATABILITY), objectId, of.convertPolicies(policies),
+                of.convertAces(addAces), of.convertAces(removeAces), null);
+
+        // if no context is provided the object will not be fetched
+        if ((context == null) || (newId == null)) {
+            return null;
+        }
+
+        // get the new object
+        CmisObject object = getSession().getObject(getSession().createObjectId(newId), context);
+        if (!(object instanceof Folder)) {
+            throw new CmisRuntimeException("Newly created object is not a folder! New id: " + newId);
+        }
+
+        return (Folder) object;
+    }
+
+    public Policy createPolicy(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces,
+            List<Ace> removeAces, OperationContext context) {
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String objectId = getObjectId();
+
+        ObjectFactory of = getObjectFactory();
+
+        String newId = getBinding().getObjectService().createPolicy(getRepositoryId(),
+                of.convertProperties(properties, null, CREATE_UPDATABILITY), objectId, of.convertPolicies(policies),
+                of.convertAces(addAces), of.convertAces(removeAces), null);
+
+        // if no context is provided the object will not be fetched
+        if ((context == null) || (newId == null)) {
+            return null;
+        }
+
+        // get the new object
+        CmisObject object = getSession().getObject(getSession().createObjectId(newId), context);
+        if (!(object instanceof Policy)) {
+            throw new CmisRuntimeException("Newly created object is not a policy! New id: " + newId);
+        }
+
+        return (Policy) object;
+    }
+
+    public List<String> deleteTree(boolean allVersions, UnfileObject unfile, boolean continueOnFailure) {
+        String repositoryId = getRepositoryId();
+        String objectId = getObjectId();
+
+        FailedToDeleteData failed = getBinding().getObjectService().deleteTree(repositoryId, objectId, allVersions,
+                unfile, continueOnFailure, null);
+
+        return failed.getIds();
+    }
+
+    public List<ObjectType> getAllowedChildObjectTypes() {
+        List<ObjectType> result = new ArrayList<ObjectType>();
+
+        readLock();
+        try {
+            List<String> otids = getPropertyValue(PropertyIds.ALLOWED_CHILD_OBJECT_TYPE_IDS);
+            if (otids == null) {
+                return result;
+            }
+
+            for (String otid : otids) {
+                result.add(getSession().getTypeDefinition(otid));
+            }
+        } finally {
+            readUnlock();
+        }
+
+        return result;
+    }
+
+    public ItemIterable<Document> getCheckedOutDocs() {
+        return getCheckedOutDocs(getSession().getDefaultContext());
+    }
+
+    public ItemIterable<Document> getCheckedOutDocs(OperationContext context) {
+        final String objectId = getObjectId();
+        final NavigationService navigationService = getBinding().getNavigationService();
+        final ObjectFactory objectFactory = getSession().getObjectFactory();
+        final OperationContext ctxt = new OperationContextImpl(context);
+
+        return new CollectionIterable<Document>(new AbstractPageFetcher<Document>(ctxt.getMaxItemsPerPage()) {
+
+            @Override
+            protected AbstractPageFetcher.Page<Document> fetchPage(long skipCount) {
+
+                // get checked out documents for this folder
+                ObjectList checkedOutDocs = navigationService.getCheckedOutDocs(getRepositoryId(), objectId, ctxt
+                        .getFilterString(), ctxt.getOrderBy(), ctxt.isIncludeAllowableActions(), ctxt
+                        .getIncludeRelationships(), ctxt.getRenditionFilterString(), BigInteger
+                        .valueOf(this.maxNumItems), BigInteger.valueOf(skipCount), null);
+
+                // convert objects
+                List<Document> page = new ArrayList<Document>();
+                if (checkedOutDocs.getObjects() != null) {
+                    for (ObjectData objectData : checkedOutDocs.getObjects()) {
+                        CmisObject doc = objectFactory.convertObject(objectData, ctxt);
+                        if (!(doc instanceof Document)) {
+                            // should not happen...
+                            continue;
+                        }
+
+                        page.add((Document) doc);
+                    }
+                }
+
+                return new AbstractPageFetcher.Page<Document>(page, checkedOutDocs.getNumItems(),
+                        checkedOutDocs.hasMoreItems());
+            }
+        });
+    }
+
+    public ItemIterable<CmisObject> getChildren() {
+        return getChildren(getSession().getDefaultContext());
+    }
+
+    public ItemIterable<CmisObject> getChildren(OperationContext context) {
+        final String objectId = getObjectId();
+        final NavigationService navigationService = getBinding().getNavigationService();
+        final ObjectFactory objectFactory = getSession().getObjectFactory();
+        final OperationContext ctxt = new OperationContextImpl(context);
+
+        return new CollectionIterable<CmisObject>(new AbstractPageFetcher<CmisObject>(ctxt.getMaxItemsPerPage()) {
+
+            @Override
+            protected AbstractPageFetcher.Page<CmisObject> fetchPage(long skipCount) {
+
+                // get the children
+                ObjectInFolderList children = navigationService.getChildren(getRepositoryId(), objectId, ctxt
+                        .getFilterString(), ctxt.getOrderBy(), ctxt.isIncludeAllowableActions(), ctxt
+                        .getIncludeRelationships(), ctxt.getRenditionFilterString(), ctxt.isIncludePathSegments(),
+                        BigInteger.valueOf(this.maxNumItems), BigInteger.valueOf(skipCount), null);
+
+                // convert objects
+                List<CmisObject> page = new ArrayList<CmisObject>();
+                List<ObjectInFolderData> childObjects = children.getObjects();
+                if (childObjects != null) {
+                    for (ObjectInFolderData objectData : childObjects) {
+                        if (objectData.getObject() != null) {
+                            page.add(objectFactory.convertObject(objectData.getObject(), ctxt));
+                        }
+                    }
+                }
+
+                return new AbstractPageFetcher.Page<CmisObject>(page, children.getNumItems(), children
+                        .hasMoreItems());
+            }
+        });
+    }
+
+    public List<Tree<FileableCmisObject>> getDescendants(int depth) {
+        return getDescendants(depth, getSession().getDefaultContext());
+    }
+
+    public List<Tree<FileableCmisObject>> getDescendants(int depth, OperationContext context) {
+        String objectId = getObjectId();
+
+        // get the descendants
+        List<ObjectInFolderContainer> providerContainerList = getBinding().getNavigationService().getDescendants(
+                getRepositoryId(), objectId, BigInteger.valueOf(depth), context.getFilterString(),
+                context.isIncludeAllowableActions(), context.getIncludeRelationships(),
+                context.getRenditionFilterString(), context.isIncludePathSegments(), null);
+
+        return convertProviderContainer(providerContainerList, context);
+    }
+
+    public List<Tree<FileableCmisObject>> getFolderTree(int depth) {
+        return getFolderTree(depth, getSession().getDefaultContext());
+    }
+
+    public List<Tree<FileableCmisObject>> getFolderTree(int depth, OperationContext context) {
+        String objectId = getObjectId();
+
+        // get the folder tree
+        List<ObjectInFolderContainer> providerContainerList = getBinding().getNavigationService().getFolderTree(
+                getRepositoryId(), objectId, BigInteger.valueOf(depth), context.getFilterString(),
+                context.isIncludeAllowableActions(), context.getIncludeRelationships(),
+                context.getRenditionFilterString(), context.isIncludePathSegments(), null);
+
+        return convertProviderContainer(providerContainerList, context);
+    }
+
+    /**
+     * Converts a provider container into an API container.
+     */
+    private List<Tree<FileableCmisObject>> convertProviderContainer(
+            List<ObjectInFolderContainer> providerContainerList, OperationContext context) {
+        if (providerContainerList == null) {
+            return null;
+        }
+
+        ObjectFactory of = getSession().getObjectFactory();
+
+        List<Tree<FileableCmisObject>> result = new ArrayList<Tree<FileableCmisObject>>();
+        for (ObjectInFolderContainer oifc : providerContainerList) {
+            if ((oifc.getObject() == null) || (oifc.getObject().getObject() == null)) {
+                // shouldn't happen ...
+                continue;
+            }
+
+            // convert the object
+            CmisObject object = of.convertObject(oifc.getObject().getObject(), context);
+            if (!(object instanceof FileableCmisObject)) {
+                // the repository must not return objects that are not fileable,
+                // but you never know...
+                continue;
+            }
+
+            // convert the children
+            List<Tree<FileableCmisObject>> children = convertProviderContainer(oifc.getChildren(), context);
+
+            // add both to current container
+            result.add(new TreeImpl<FileableCmisObject>((FileableCmisObject) object, children));
+        }
+
+        return result;
+    }
+
+    public boolean isRootFolder() {
+        String objectId = getObjectId();
+        String rootFolderId = getSession().getRepositoryInfo().getRootFolderId();
+
+        return objectId.equals(rootFolderId);
+    }
+
+    public Folder getFolderParent() {
+        if (isRootFolder()) {
+            return null;
+        }
+
+        List<Folder> parents = super.getParents();
+        if ((parents == null) || (parents.isEmpty())) {
+            return null;
+        }
+
+        return parents.get(0);
+    }
+
+    public String getPath() {
+        String path;
+
+        readLock();
+        try {
+            // get the path property
+            path = getPropertyValue(PropertyIds.PATH);
+
+            // if the path property isn't set, get it
+            if (path == null) {
+                String objectId = getObjectId();
+                ObjectData objectData = getBinding().getObjectService().getObject(getRepositoryId(), objectId,
+                        getPropertyQueryName(PropertyIds.PATH), false, IncludeRelationships.NONE, "cmis:none", false,
+                        false, null);
+
+                if ((objectData.getProperties() != null) && (objectData.getProperties().getProperties() != null)) {
+                    PropertyData<?> pathProperty = objectData.getProperties().getProperties().get(PropertyIds.PATH);
+
+                    if (pathProperty instanceof PropertyString) {
+                        path = ((PropertyString) pathProperty).getFirstValue();
+                    }
+                }
+            }
+        } finally {
+            readUnlock();
+        }
+
+        // we still don't know the path ... it's not a CMIS compliant repository
+        if (path == null) {
+            throw new CmisRuntimeException("Repository didn't return " + PropertyIds.PATH + "!");
+        }
+
+        return path;
+    }
+
+    @Override
+    public List<String> getPaths() {
+        return Collections.singletonList(getPath());
+    }
+
+    public Document createDocument(Map<String, ?> properties, ContentStream contentStream,
+            VersioningState versioningState) {
+        return this.createDocument(properties, contentStream, versioningState, null, null, null, getSession().getDefaultContext());
+    }
+
+    public Document createDocumentFromSource(ObjectId source, Map<String, ?> properties,
+            VersioningState versioningState) {
+        return this.createDocumentFromSource(source, properties, versioningState, null, null, null, getSession().getDefaultContext());
+    }
+
+    public Folder createFolder(Map<String, ?> properties) {
+        return this.createFolder(properties, null, null, null, getSession().getDefaultContext());
+    }
+
+    public Policy createPolicy(Map<String, ?> properties) {
+        return this.createPolicy(properties, null, null, null, getSession().getDefaultContext());
+    }
+}

Propchange: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/FolderImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PolicyImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PolicyImpl.java?rev=1033918&view=auto
==============================================================================
--- incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PolicyImpl.java (added)
+++ incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PolicyImpl.java Thu Nov 11 12:46:30 2010
@@ -0,0 +1,41 @@
+/*
+ * 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.runtime;
+
+import org.apache.chemistry.opencmis.client.api.ObjectType;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.client.api.Policy;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+
+public class PolicyImpl extends AbstractFilableCmisObject implements Policy {
+
+    /**
+     * Constructor.
+     */
+    public PolicyImpl(SessionImpl session, ObjectType objectType, ObjectData objectData,
+            OperationContext context) {
+        initialize(session, objectType, objectData, context);
+    }
+
+    public String getPolicyText() {
+        return getPropertyValue(PropertyIds.POLICY_TEXT);
+    }
+
+}

Propchange: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PolicyImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PropertyImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PropertyImpl.java?rev=1033918&view=auto
==============================================================================
--- incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PropertyImpl.java (added)
+++ incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PropertyImpl.java Thu Nov 11 12:46:30 2010
@@ -0,0 +1,122 @@
+/*
+ * 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.runtime;
+
+import java.io.Serializable;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.apache.chemistry.opencmis.client.api.Property;
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.enums.Cardinality;
+import org.apache.chemistry.opencmis.commons.enums.PropertyType;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyData;
+
+/**
+ * Property Implementation.
+ */
+public class PropertyImpl<T> extends AbstractPropertyData<T> implements Property<T>, Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private PropertyDefinition<T> propertyDefinition;
+
+    protected void initialize(PropertyDefinition<?> pd) {
+        setId(pd.getId());
+        setDisplayName(pd.getDisplayName());
+        setLocalName(pd.getLocalName());
+        setQueryName(pd.getQueryName());
+    }
+
+    /**
+     * Constructs a property from a list of values.
+     */
+    public PropertyImpl(PropertyDefinition<T> pd, List<T> values) {
+        if (pd == null) {
+            throw new IllegalArgumentException("Type must be set!");
+        }
+        if (values == null) {
+            throw new IllegalArgumentException("Value must be set!");
+        }
+        propertyDefinition = pd;
+        initialize(pd);
+        setValues(values);
+    }
+
+    public PropertyDefinition<T> getDefinition() {
+        return propertyDefinition;
+    }
+
+    public PropertyType getType() {
+        return propertyDefinition.getPropertyType();
+    }
+
+    @SuppressWarnings("unchecked")
+    public <U> U getValue() {
+        List<T> values = getValues();
+        if (propertyDefinition.getCardinality() == Cardinality.SINGLE) {
+            return values.size() == 0 ? null : (U) values.get(0);
+        } else {
+            return (U) values;
+        }
+    }
+
+    public String getValueAsString() {
+        List<T> values = getValues();
+        if (values.size() == 0) {
+            return null;
+        }
+
+        return formatValue(values.get(0));
+    }
+
+    public String getValuesAsString() {
+        List<T> values = getValues();
+
+        StringBuilder result = new StringBuilder();
+        for (T value : values) {
+            if (result.length() > 0) {
+                result.append(", ");
+            }
+
+            result.append(formatValue(value));
+        }
+
+        return "[" + result.toString() + "]";
+    }
+
+    private String formatValue(T value) {
+        String result;
+
+        if (value == null) {
+            return null;
+        }
+
+        if (value instanceof GregorianCalendar) {
+            result = ((GregorianCalendar) value).getTime().toString();
+        } else {
+            result = value.toString();
+        }
+
+        return result;
+    }
+
+    public boolean isMultiValued() {
+        return propertyDefinition.getCardinality() == Cardinality.MULTI;
+    }
+}

Propchange: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/PropertyImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/RelationshipImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/RelationshipImpl.java?rev=1033918&view=auto
==============================================================================
--- incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/RelationshipImpl.java (added)
+++ incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/RelationshipImpl.java Thu Nov 11 12:46:30 2010
@@ -0,0 +1,92 @@
+/*
+ * 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.runtime;
+
+import org.apache.chemistry.opencmis.client.api.CmisObject;
+import org.apache.chemistry.opencmis.client.api.ObjectId;
+import org.apache.chemistry.opencmis.client.api.ObjectType;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.client.api.Relationship;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+
+public class RelationshipImpl extends AbstractCmisObject implements Relationship {
+
+    /**
+     * Constructor.
+     */
+    public RelationshipImpl(SessionImpl session, ObjectType objectType, ObjectData objectData,
+            OperationContext context) {
+        initialize(session, objectType, objectData, context);
+    }
+
+    public CmisObject getSource() {
+        return getSource(getSession().getDefaultContext());
+    }
+
+    public CmisObject getSource(OperationContext context) {
+        readLock();
+        try {
+            ObjectId sourceId = getSourceId();
+            if (sourceId == null) {
+                return null;
+            }
+
+            return getSession().getObject(sourceId, context);
+        } finally {
+            readUnlock();
+        }
+    }
+
+    public ObjectId getSourceId() {
+        String sourceId = getPropertyValue(PropertyIds.SOURCE_ID);
+        if ((sourceId == null) || (sourceId.length() == 0)) {
+            return null;
+        }
+
+        return getSession().createObjectId(sourceId);
+    }
+
+    public CmisObject getTarget() {
+        return getTarget(getSession().getDefaultContext());
+    }
+
+    public CmisObject getTarget(OperationContext context) {
+        readLock();
+        try {
+            ObjectId targetId = getTargetId();
+            if (targetId == null) {
+                return null;
+            }
+
+            return getSession().getObject(targetId, context);
+        } finally {
+            readUnlock();
+        }
+    }
+
+    public ObjectId getTargetId() {
+        String targetId = getPropertyValue(PropertyIds.TARGET_ID);
+        if ((targetId == null) || (targetId.length() == 0)) {
+            return null;
+        }
+
+        return getSession().createObjectId(targetId);
+    }
+}

Propchange: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/RelationshipImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionFactoryImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionFactoryImpl.java?rev=1033918&r1=1033917&r2=1033918&view=diff
==============================================================================
--- incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionFactoryImpl.java (original)
+++ incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionFactoryImpl.java Thu Nov 11 12:46:30 2010
@@ -26,11 +26,7 @@ import org.apache.chemistry.opencmis.cli
 import org.apache.chemistry.opencmis.client.api.Session;
 import org.apache.chemistry.opencmis.client.api.SessionFactory;
 import org.apache.chemistry.opencmis.client.runtime.repository.RepositoryImpl;
-import org.apache.chemistry.opencmis.commons.SessionParameter;
 import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
-import org.apache.chemistry.opencmis.commons.enums.SessionType;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
 import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
 
 /**
@@ -53,55 +49,20 @@ import org.apache.chemistry.opencmis.com
 public class SessionFactoryImpl implements SessionFactory {
 
     protected SessionFactoryImpl() {
-
     }
 
     public static SessionFactory newInstance() {
         return new SessionFactoryImpl();
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.apache.opencmis.client.api.SessionFactory#createSession(java.util
-     * .Map)
-     */
     @SuppressWarnings("unchecked")
     public <T extends Session> T createSession(Map<String, String> parameters) {
-        Session s = null;
-        SessionType t = null;
-
-        // determine session type
-        if (parameters.containsKey(SessionParameter.SESSION_TYPE)) {
-            t = SessionType.fromValue(parameters.get(SessionParameter.SESSION_TYPE));
-        } else {
-            // default session type if type is not set
-            t = SessionType.PERSISTENT;
-        }
+        SessionImpl session = new SessionImpl(parameters);
+        session.connect();
 
-        switch (t) {
-        case PERSISTENT:
-            PersistentSessionImpl ps = new PersistentSessionImpl(parameters);
-            ps.connect(); // connect session with provider
-            s = ps;
-            break;
-        case TRANSIENT:
-            throw new CmisNotSupportedException("SessionType " + t + "not implemented!");
-        default:
-            throw new CmisRuntimeException("SessionType " + t + "not known!");
-        }
-
-        return (T) s;
+        return (T) session;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.apache.opencmis.client.api.SessionFactory#getRepositories(java.util
-     * .Map)
-     */
     public List<Repository> getRepositories(Map<String, String> parameters) {
         CmisBinding binding = CmisBindingHelper.createProvider(parameters);
 
@@ -114,5 +75,4 @@ public class SessionFactoryImpl implemen
 
         return result;
     }
-
 }

Added: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionImpl.java?rev=1033918&view=auto
==============================================================================
--- incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionImpl.java (added)
+++ incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionImpl.java Thu Nov 11 12:46:30 2010
@@ -0,0 +1,810 @@
+/*
+ * 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.runtime;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.chemistry.opencmis.client.api.ChangeEvents;
+import org.apache.chemistry.opencmis.client.api.CmisObject;
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.ExtensionHandler;
+import org.apache.chemistry.opencmis.client.api.Folder;
+import org.apache.chemistry.opencmis.client.api.ItemIterable;
+import org.apache.chemistry.opencmis.client.api.ObjectFactory;
+import org.apache.chemistry.opencmis.client.api.ObjectId;
+import org.apache.chemistry.opencmis.client.api.ObjectType;
+import org.apache.chemistry.opencmis.client.api.OperationContext;
+import org.apache.chemistry.opencmis.client.api.Policy;
+import org.apache.chemistry.opencmis.client.api.QueryResult;
+import org.apache.chemistry.opencmis.client.api.Relationship;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.client.api.Tree;
+import org.apache.chemistry.opencmis.client.runtime.cache.Cache;
+import org.apache.chemistry.opencmis.client.runtime.cache.CacheImpl;
+import org.apache.chemistry.opencmis.client.runtime.repository.ObjectFactoryImpl;
+import org.apache.chemistry.opencmis.client.runtime.util.AbstractPageFetcher;
+import org.apache.chemistry.opencmis.client.runtime.util.CollectionIterable;
+import org.apache.chemistry.opencmis.client.runtime.util.TreeImpl;
+import org.apache.chemistry.opencmis.commons.SessionParameter;
+import org.apache.chemistry.opencmis.commons.data.Ace;
+import org.apache.chemistry.opencmis.commons.data.Acl;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.data.ObjectData;
+import org.apache.chemistry.opencmis.commons.data.ObjectList;
+import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
+import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
+import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.enums.RelationshipDirection;
+import org.apache.chemistry.opencmis.commons.enums.Updatability;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
+import org.apache.chemistry.opencmis.commons.spi.DiscoveryService;
+import org.apache.chemistry.opencmis.commons.spi.Holder;
+import org.apache.chemistry.opencmis.commons.spi.NavigationService;
+import org.apache.chemistry.opencmis.commons.spi.RelationshipService;
+import org.apache.chemistry.opencmis.commons.spi.RepositoryService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Persistent model session.
+ */
+public class SessionImpl implements Session, Serializable {
+
+    private static final OperationContext DEFAULT_CONTEXT = new OperationContextImpl(null, false, true, false,
+            IncludeRelationships.NONE, null, true, null, true, 100);
+
+    private static final Set<Updatability> CREATE_UPDATABILITY = new HashSet<Updatability>();
+    static {
+        CREATE_UPDATABILITY.add(Updatability.ONCREATE);
+        CREATE_UPDATABILITY.add(Updatability.READWRITE);
+    }
+
+    private static Log log = LogFactory.getLog(SessionImpl.class);
+
+    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+    /*
+     * default session context (serializable)
+     */
+    private OperationContext context = DEFAULT_CONTEXT;
+
+    /*
+     * session parameter (serializable)
+     */
+    private Map<String, String> parameters = null;
+
+    /*
+     * CMIS provider (serializable)
+     */
+    private CmisBinding binding = null;
+
+    /*
+     * Session Locale, determined from session parameter (serializable)
+     */
+    private Locale locale = null;
+
+    /*
+     * Object cache (serializable)
+     */
+    private Cache cache = null;
+
+    /*
+     * Lazy loaded repository info. Will be invalid after clear(). Access by
+     * getter always. (serializable)
+     */
+    private RepositoryInfo repositoryInfo;
+
+    /*
+     * helper factory (non serializable)
+     */
+    private final ObjectFactory objectFactory = ObjectFactoryImpl.newInstance(this);
+
+    /**
+     * required for serialization
+     */
+    private static final long serialVersionUID = -4287481628831198383L;
+
+    /**
+     * Constructor.
+     */
+    public SessionImpl(Map<String, String> parameters) {
+        this.parameters = parameters;
+        SessionImpl.log.info("Session Parameters: " + parameters);
+
+        this.locale = this.determineLocale(parameters);
+        SessionImpl.log.info("Session Locale: " + this.locale.toString());
+
+        int cacheSize = this.determineCacheSize(parameters);
+
+        if (cacheSize == -1) {
+            this.cache = CacheImpl.newInstance();
+        } else {
+            this.cache = CacheImpl.newInstance(cacheSize);
+        }
+        SessionImpl.log.info("Session Cache Size: " + this.cache.getCacheSize());
+    }
+
+    private int determineCacheSize(Map<String, String> parameters) {
+        int size = -1;
+
+        return size;
+    }
+
+    private String determineRepositoryId(Map<String, String> parameters) {
+        String repositoryId = parameters.get(SessionParameter.REPOSITORY_ID);
+        // if null then the provider will return a repository id (lazy)
+        return repositoryId;
+    }
+
+    private Locale determineLocale(Map<String, String> parameters) {
+        Locale locale = null;
+
+        String language = parameters.get(SessionParameter.LOCALE_ISO639_LANGUAGE);
+        String country = parameters.get(SessionParameter.LOCALE_ISO3166_COUNTRY);
+        String variant = parameters.get(SessionParameter.LOCALE_VARIANT);
+
+        if (variant != null) {
+            // all 3 parameter must not be null and valid
+            locale = new Locale(language, country, variant);
+        } else {
+            if (country != null) {
+                // 2 parameter must not be null and valid
+                locale = new Locale(language, country);
+            } else {
+                if (language != null) {
+                    // 1 parameter must not be null and valid
+                    locale = new Locale(language);
+                } else {
+                    locale = Locale.getDefault();
+                }
+            }
+        }
+
+        return locale;
+    }
+
+    public void clear() {
+        lock.writeLock().lock();
+        try {
+            int cacheSize = this.determineCacheSize(this.parameters);
+            if (cacheSize == -1) {
+                this.cache = CacheImpl.newInstance();
+            } else {
+                this.cache = CacheImpl.newInstance(cacheSize);
+            }
+            SessionImpl.log.info("Session Cache Size: " + this.cache.getCacheSize());
+
+            /*
+             * clear provider cache
+             */
+            getBinding().clearAllCaches();
+        } finally {
+            lock.writeLock().unlock();
+        }
+    }
+
+    public ObjectFactory getObjectFactory() {
+        return this.objectFactory;
+    }
+
+    public ItemIterable<Document> getCheckedOutDocs() {
+        return getCheckedOutDocs(getDefaultContext());
+    }
+
+    public ItemIterable<Document> getCheckedOutDocs(OperationContext context) {
+        final NavigationService navigationService = getBinding().getNavigationService();
+        final ObjectFactory objectFactory = getObjectFactory();
+        final OperationContext ctxt = new OperationContextImpl(context);
+
+        return new CollectionIterable<Document>(new AbstractPageFetcher<Document>(ctxt.getMaxItemsPerPage()) {
+
+            @Override
+            protected AbstractPageFetcher.Page<Document> fetchPage(long skipCount) {
+
+                // get all checked out documents
+                ObjectList checkedOutDocs = navigationService.getCheckedOutDocs(getRepositoryId(), null,
+                        ctxt.getFilterString(), ctxt.getOrderBy(), ctxt.isIncludeAllowableActions(),
+                        ctxt.getIncludeRelationships(), ctxt.getRenditionFilterString(),
+                        BigInteger.valueOf(this.maxNumItems), BigInteger.valueOf(skipCount), null);
+
+                // convert objects
+                List<Document> page = new ArrayList<Document>();
+                if (checkedOutDocs.getObjects() != null) {
+                    for (ObjectData objectData : checkedOutDocs.getObjects()) {
+                        CmisObject doc = objectFactory.convertObject(objectData, ctxt);
+                        if (!(doc instanceof Document)) {
+                            // should not happen...
+                            continue;
+                        }
+
+                        page.add((Document) doc);
+                    }
+                }
+
+                return new AbstractPageFetcher.Page<Document>(page, checkedOutDocs.getNumItems(),
+                        checkedOutDocs.hasMoreItems());
+            }
+        });
+    }
+
+    public ChangeEvents getContentChanges(String changeLogToken, boolean includeProperties, long maxNumItems) {
+        return getContentChanges(changeLogToken, includeProperties, maxNumItems, getDefaultContext());
+    }
+
+    public ChangeEvents getContentChanges(String changeLogToken, boolean includeProperties, long maxNumItems,
+            OperationContext context) {
+        lock.readLock().lock();
+        try {
+            Holder<String> changeLogTokenHolder = new Holder<String>(changeLogToken);
+
+            ObjectList objectList = getBinding().getDiscoveryService().getContentChanges(getRepositoryInfo().getId(),
+                    changeLogTokenHolder, includeProperties, context.getFilterString(), context.isIncludePolicies(),
+                    context.isIncludeAcls(), BigInteger.valueOf(maxNumItems), null);
+
+            return objectFactory.convertChangeEvents(changeLogTokenHolder.getValue(), objectList);
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    public OperationContext getDefaultContext() {
+        lock.readLock().lock();
+        try {
+            return this.context;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    public void setDefaultContext(OperationContext context) {
+        lock.writeLock().lock();
+        try {
+            this.context = (context == null ? DEFAULT_CONTEXT : context);
+        } finally {
+            lock.writeLock().unlock();
+        }
+    }
+
+    public OperationContext createOperationContext(Set<String> filter, boolean includeAcls,
+            boolean includeAllowableActions, boolean includePolicies, IncludeRelationships includeRelationships,
+            Set<String> renditionFilter, boolean includePathSegments, String orderBy, boolean cacheEnabled,
+            int maxItemsPerPage) {
+        return new OperationContextImpl(filter, includeAcls, includeAllowableActions, includePolicies,
+                includeRelationships, renditionFilter, includePathSegments, orderBy, cacheEnabled, maxItemsPerPage);
+    }
+
+    public OperationContext createOperationContext() {
+        return new OperationContextImpl();
+    }
+
+    public ObjectId createObjectId(String id) {
+        return new ObjectIdImpl(id);
+    }
+
+    public Locale getLocale() {
+        return this.locale;
+    }
+
+    public CmisObject getObject(ObjectId objectId) {
+        return getObject(objectId, getDefaultContext());
+    }
+
+    public CmisObject getObject(ObjectId objectId, OperationContext context) {
+        if ((objectId == null) || (objectId.getId() == null)) {
+            throw new IllegalArgumentException("Object Id must be set!");
+        }
+        if (context == null) {
+            throw new IllegalArgumentException("Operation context must be set!");
+        }
+
+        CmisObject result = null;
+
+        // ask the cache first
+        if (context.isCacheEnabled()) {
+            result = this.cache.getById(objectId.getId(), context.getCacheKey());
+            if (result != null) {
+                return result;
+            }
+        }
+
+        // get the object
+        ObjectData objectData = this.binding.getObjectService().getObject(getRepositoryId(), objectId.getId(),
+                context.getFilterString(), context.isIncludeAllowableActions(), context.getIncludeRelationships(),
+                context.getRenditionFilterString(), context.isIncludePolicies(), context.isIncludeAcls(), null);
+
+        result = getObjectFactory().convertObject(objectData, context);
+
+        // put into cache
+        if (context.isCacheEnabled()) {
+            this.cache.put(result, context.getCacheKey());
+        }
+
+        return result;
+    }
+
+    public CmisObject getObjectByPath(String path) {
+        return getObjectByPath(path, getDefaultContext());
+    }
+
+    public CmisObject getObjectByPath(String path, OperationContext context) {
+        if (path == null) {
+            throw new IllegalArgumentException("Path must be set!");
+        }
+        if (context == null) {
+            throw new IllegalArgumentException("Operation context must be set!");
+        }
+
+        CmisObject result = null;
+
+        // ask the cache first
+        if (context.isCacheEnabled()) {
+            result = this.cache.getByPath(path, context.getCacheKey());
+            if (result != null) {
+                return result;
+            }
+        }
+
+        // get the object
+        ObjectData objectData = this.binding.getObjectService().getObjectByPath(getRepositoryId(), path,
+                context.getFilterString(), context.isIncludeAllowableActions(), context.getIncludeRelationships(),
+                context.getRenditionFilterString(), context.isIncludePolicies(), context.isIncludeAcls(), null);
+
+        result = getObjectFactory().convertObject(objectData, context);
+
+        // put into cache
+        if (context.isCacheEnabled()) {
+            this.cache.putPath(path, result, context.getCacheKey());
+        }
+
+        return result;
+    }
+
+    public RepositoryInfo getRepositoryInfo() {
+        lock.readLock().lock();
+        try {
+            return this.repositoryInfo;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    public Folder getRootFolder() {
+        return getRootFolder(getDefaultContext());
+    }
+
+    public Folder getRootFolder(OperationContext context) {
+        String rootFolderId = getRepositoryInfo().getRootFolderId();
+
+        CmisObject rootFolder = getObject(createObjectId(rootFolderId), context);
+        if (!(rootFolder instanceof Folder)) {
+            throw new CmisRuntimeException("Root folder object is not a folder!");
+        }
+
+        return (Folder) rootFolder;
+    }
+
+    public ItemIterable<ObjectType> getTypeChildren(final String typeId, final boolean includePropertyDefinitions) {
+        final RepositoryService repositoryService = getBinding().getRepositoryService();
+        final ObjectFactory objectFactory = this.getObjectFactory();
+
+        return new CollectionIterable<ObjectType>(new AbstractPageFetcher<ObjectType>(this.getDefaultContext()
+                .getMaxItemsPerPage()) {
+
+            @Override
+            protected AbstractPageFetcher.Page<ObjectType> fetchPage(long skipCount) {
+
+                // fetch the data
+                TypeDefinitionList tdl = repositoryService.getTypeChildren(
+                        SessionImpl.this.getRepositoryId(), typeId, includePropertyDefinitions,
+                        BigInteger.valueOf(this.maxNumItems), BigInteger.valueOf(skipCount), null);
+
+                // convert type definitions
+                List<ObjectType> page = new ArrayList<ObjectType>(tdl.getList().size());
+                for (TypeDefinition typeDefinition : tdl.getList()) {
+                    page.add(objectFactory.convertTypeDefinition(typeDefinition));
+                }
+
+                return new AbstractPageFetcher.Page<ObjectType>(page, tdl.getNumItems(), tdl.hasMoreItems()) {
+                };
+            }
+        });
+    }
+
+    public ObjectType getTypeDefinition(String typeId) {
+        TypeDefinition typeDefinition = getBinding().getRepositoryService().getTypeDefinition(getRepositoryId(),
+                typeId, null);
+        return objectFactory.convertTypeDefinition(typeDefinition);
+    }
+
+    public List<Tree<ObjectType>> getTypeDescendants(String typeId, int depth, boolean includePropertyDefinitions) {
+        List<TypeDefinitionContainer> descendants = getBinding().getRepositoryService().getTypeDescendants(
+                getRepositoryId(), typeId, BigInteger.valueOf(depth), includePropertyDefinitions, null);
+
+        return convertTypeDescendants(descendants);
+    }
+
+    /**
+     * Converts provider <code>TypeDefinitionContainer</code> to API
+     * <code>Container</code>.
+     */
+    private List<Tree<ObjectType>> convertTypeDescendants(List<TypeDefinitionContainer> descendantsList) {
+        List<Tree<ObjectType>> result = new ArrayList<Tree<ObjectType>>();
+
+        for (TypeDefinitionContainer container : descendantsList) {
+            ObjectType objectType = objectFactory.convertTypeDefinition(container.getTypeDefinition());
+            List<Tree<ObjectType>> children = convertTypeDescendants(container.getChildren());
+
+            result.add(new TreeImpl<ObjectType>(objectType, children));
+        }
+
+        return result;
+    }
+
+    public ItemIterable<QueryResult> query(final String statement, final boolean searchAllVersions) {
+        return query(statement, searchAllVersions, getDefaultContext());
+    }
+
+    public ItemIterable<QueryResult> query(final String statement, final boolean searchAllVersions,
+            OperationContext context) {
+
+        final DiscoveryService discoveryService = getBinding().getDiscoveryService();
+        final ObjectFactory objectFactory = this.getObjectFactory();
+        final OperationContext ctxt = new OperationContextImpl(context);
+
+        return new CollectionIterable<QueryResult>(new AbstractPageFetcher<QueryResult>(ctxt.getMaxItemsPerPage()) {
+
+            @Override
+            protected AbstractPageFetcher.Page<QueryResult> fetchPage(long skipCount) {
+
+                // fetch the data
+                ObjectList resultList = discoveryService.query(getRepositoryId(), statement, searchAllVersions,
+                        ctxt.isIncludeAllowableActions(), ctxt.getIncludeRelationships(),
+                        ctxt.getRenditionFilterString(), BigInteger.valueOf(this.maxNumItems),
+                        BigInteger.valueOf(skipCount), null);
+
+                // convert type definitions
+                List<QueryResult> page = new ArrayList<QueryResult>();
+                if (resultList.getObjects() != null) {
+                    for (ObjectData objectData : resultList.getObjects()) {
+                        if (objectData == null) {
+                            continue;
+                        }
+
+                        page.add(objectFactory.convertQueryResult(objectData));
+                    }
+                }
+
+                return new AbstractPageFetcher.Page<QueryResult>(page, resultList.getNumItems(),
+                        resultList.hasMoreItems());
+            }
+        });
+
+    }
+
+    public String setExtensionContext(String context) {
+        throw new CmisRuntimeException("not implemented");
+    }
+
+    public ExtensionHandler setExtensionHandler(String context, ExtensionHandler extensionHandler) {
+        throw new CmisRuntimeException("not implemented");
+    }
+
+    /**
+     * Connect session object to the provider. This is the very first call after
+     * a session is created.
+     * <p>
+     * In dependency of the parameter set an {@code AtomPub}, a
+     * {@code WebService} or an {@code InMemory} provider is selected.
+     */
+    public void connect() {
+        lock.writeLock().lock();
+        try {
+            this.binding = CmisBindingHelper.createProvider(this.parameters);
+
+            /* get initial repository id from session parameter */
+            String repositoryId = this.determineRepositoryId(this.parameters);
+            if (repositoryId == null) {
+                throw new IllegalStateException("Repository Id is not set!");
+            }
+
+            repositoryInfo = getBinding().getRepositoryService().getRepositoryInfo(repositoryId, null);
+        } finally {
+            lock.writeLock().unlock();
+        }
+    }
+
+    public CmisBinding getBinding() {
+        lock.readLock().lock();
+        try {
+            return this.binding;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    public Cache getCache() {
+        lock.readLock().lock();
+        try {
+            return this.cache;
+        } finally {
+            lock.readLock().unlock();
+        }
+    }
+
+    /**
+     * Returns the repository id.
+     */
+    public String getRepositoryId() {
+        return getRepositoryInfo().getId();
+    }
+
+    // creates
+
+    public ObjectId createDocument(Map<String, ?> properties, ObjectId folderId, ContentStream contentStream,
+            VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) {
+        if ((folderId != null) && (folderId.getId() == null)) {
+            throw new IllegalArgumentException("Folder Id must be set!");
+        }
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String newId = getBinding().getObjectService().createDocument(getRepositoryId(),
+                objectFactory.convertProperties(properties, null, CREATE_UPDATABILITY),
+                (folderId == null ? null : folderId.getId()), objectFactory.convertContentStream(contentStream),
+                versioningState, objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces),
+                objectFactory.convertAces(removeAces), null);
+
+        if (newId == null) {
+            return null;
+        }
+
+        return createObjectId(newId);
+    }
+
+    public ObjectId createDocumentFromSource(ObjectId source, Map<String, ?> properties, ObjectId folderId,
+            VersioningState versioningState, List<Policy> policies, List<Ace> addAces, List<Ace> removeAces) {
+        // get the type of the source document
+        ObjectType type = null;
+        if (source instanceof CmisObject) {
+            type = ((CmisObject) source).getBaseType();
+        } else {
+            CmisObject sourceObj = getObject(source);
+            type = sourceObj.getType();
+        }
+
+        if (type.getBaseTypeId() != BaseTypeId.CMIS_DOCUMENT) {
+            throw new IllegalArgumentException("Source object must be a document!");
+        }
+
+        String newId = getBinding().getObjectService().createDocumentFromSource(getRepositoryId(), source.getId(),
+                objectFactory.convertProperties(properties, type, CREATE_UPDATABILITY),
+                (folderId == null ? null : folderId.getId()), versioningState, objectFactory.convertPolicies(policies),
+                objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), null);
+
+        if (newId == null) {
+            return null;
+        }
+
+        return createObjectId(newId);
+    }
+
+    public ObjectId createFolder(Map<String, ?> properties, ObjectId folderId, List<Policy> policies,
+            List<Ace> addAces, List<Ace> removeAces) {
+        if ((folderId != null) && (folderId.getId() == null)) {
+            throw new IllegalArgumentException("Folder Id must be set!");
+        }
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String newId = getBinding().getObjectService().createFolder(getRepositoryId(),
+                objectFactory.convertProperties(properties, null, CREATE_UPDATABILITY),
+                (folderId == null ? null : folderId.getId()), objectFactory.convertPolicies(policies),
+                objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), null);
+
+        if (newId == null) {
+            return null;
+        }
+
+        return createObjectId(newId);
+    }
+
+    public ObjectId createPolicy(Map<String, ?> properties, ObjectId folderId, List<Policy> policies,
+            List<Ace> addAces, List<Ace> removeAces) {
+        if ((folderId != null) && (folderId.getId() == null)) {
+            throw new IllegalArgumentException("Folder Id must be set!");
+        }
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String newId = getBinding().getObjectService().createPolicy(getRepositoryId(),
+                objectFactory.convertProperties(properties, null, CREATE_UPDATABILITY),
+                (folderId == null ? null : folderId.getId()), objectFactory.convertPolicies(policies),
+                objectFactory.convertAces(addAces), objectFactory.convertAces(removeAces), null);
+
+        if (newId == null) {
+            return null;
+        }
+
+        return createObjectId(newId);
+    }
+
+    public ObjectId createRelationship(Map<String, ?> properties, List<Policy> policies, List<Ace> addAces,
+            List<Ace> removeAces) {
+        if ((properties == null) || (properties.isEmpty())) {
+            throw new IllegalArgumentException("Properties must not be empty!");
+        }
+
+        String newId = getBinding().getObjectService().createRelationship(getRepositoryId(),
+                objectFactory.convertProperties(properties, null, CREATE_UPDATABILITY),
+                objectFactory.convertPolicies(policies), objectFactory.convertAces(addAces),
+                objectFactory.convertAces(removeAces), null);
+
+        if (newId == null) {
+            return null;
+        }
+
+        return createObjectId(newId);
+    }
+
+    public ObjectId createDocument(Map<String, ?> properties, ObjectId folderId, ContentStream contentStream,
+            VersioningState versioningState) {
+        return this.createDocument(properties, folderId, contentStream, versioningState, null, null, null);
+    }
+
+    public ObjectId createDocumentFromSource(ObjectId source, Map<String, ?> properties, ObjectId folderId,
+            VersioningState versioningState) {
+        return this.createDocumentFromSource(source, properties, folderId, versioningState, null, null, null);
+    }
+
+    public ObjectId createFolder(Map<String, ?> properties, ObjectId folderId) {
+        return this.createFolder(properties, folderId, null, null, null);
+    }
+
+    public ObjectId createPolicy(Map<String, ?> properties, ObjectId folderId) {
+        return this.createPolicy(properties, folderId, null, null, null);
+    }
+
+    public ObjectId createRelationship(Map<String, ?> properties) {
+        return this.createRelationship(properties, null, null, null);
+    }
+
+    public ItemIterable<Relationship> getRelationships(ObjectId objectId, final boolean includeSubRelationshipTypes,
+            final RelationshipDirection relationshipDirection, ObjectType type, OperationContext context) {
+        if ((objectId == null) || (objectId.getId() == null)) {
+            throw new IllegalArgumentException("Invalid object id!");
+        }
+
+        final String id = objectId.getId();
+        final String typeId = (type == null ? null : type.getId());
+        final RelationshipService relationshipService = getBinding().getRelationshipService();
+        final OperationContext ctxt = new OperationContextImpl(context);
+
+        return new CollectionIterable<Relationship>(new AbstractPageFetcher<Relationship>(ctxt.getMaxItemsPerPage()) {
+
+            @Override
+            protected AbstractPageFetcher.Page<Relationship> fetchPage(long skipCount) {
+
+                // fetch the relationships
+                ObjectList relList = relationshipService.getObjectRelationships(getRepositoryId(), id,
+                        includeSubRelationshipTypes, relationshipDirection, typeId, ctxt.getFilterString(),
+                        ctxt.isIncludeAllowableActions(), BigInteger.valueOf(this.maxNumItems),
+                        BigInteger.valueOf(skipCount), null);
+
+                // convert relationship objects
+                List<Relationship> page = new ArrayList<Relationship>();
+                if (relList.getObjects() != null) {
+                    for (ObjectData rod : relList.getObjects()) {
+                        CmisObject relationship = getObject(createObjectId(rod.getId()), ctxt);
+                        if (!(relationship instanceof Relationship)) {
+                            throw new CmisRuntimeException("Repository returned an object that is not a relationship!");
+                        }
+
+                        page.add((Relationship) relationship);
+                    }
+                }
+
+                return new AbstractPageFetcher.Page<Relationship>(page, relList.getNumItems(), relList.hasMoreItems());
+            }
+        });
+    }
+
+    public Acl getAcl(ObjectId objectId, boolean onlyBasicPermissions) {
+        if ((objectId == null) || (objectId.getId() == null)) {
+            throw new IllegalArgumentException("Invalid object id!");
+        }
+
+        String id = objectId.getId();
+
+        return getBinding().getAclService().getAcl(getRepositoryId(), id, onlyBasicPermissions, null);
+    }
+
+    public Acl applyAcl(ObjectId objectId, List<Ace> addAces, List<Ace> removeAces, AclPropagation aclPropagation) {
+        if ((objectId == null) || (objectId.getId() == null)) {
+            throw new IllegalArgumentException("Invalid object id!");
+        }
+
+        ObjectFactory of = getObjectFactory();
+
+        return getBinding().getAclService().applyAcl(getRepositoryId(), objectId.getId(), of.convertAces(addAces),
+                of.convertAces(removeAces), aclPropagation, null);
+    }
+
+    public void applyPolicy(ObjectId objectId, ObjectId... policyIds) {
+        if ((objectId == null) || (objectId.getId() == null)) {
+            throw new IllegalArgumentException("Invalid object id!");
+        }
+
+        if ((policyIds == null) || (policyIds.length == 0)) {
+            throw new IllegalArgumentException("No Policies provided!");
+        }
+
+        String[] ids = new String[policyIds.length];
+        for (int i = 0; i < policyIds.length; i++) {
+            if ((policyIds[i] == null) || (policyIds[i].getId() == null)) {
+                throw new IllegalArgumentException("A Policy Id is not set!");
+            }
+
+            ids[i] = policyIds[i].getId();
+        }
+
+        for (String id : ids) {
+            getBinding().getPolicyService().applyPolicy(getRepositoryId(), id, objectId.getId(), null);
+        }
+    }
+
+    public void removePolicy(ObjectId objectId, ObjectId... policyIds) {
+        if ((objectId == null) || (objectId.getId() == null)) {
+            throw new IllegalArgumentException("Invalid object id!");
+        }
+
+        if ((policyIds == null) || (policyIds.length == 0)) {
+            throw new IllegalArgumentException("No Policies provided!");
+        }
+
+        String[] ids = new String[policyIds.length];
+        for (int i = 0; i < policyIds.length; i++) {
+            if ((policyIds[i] == null) || (policyIds[i].getId() == null)) {
+                throw new IllegalArgumentException("A Policy Id is not set!");
+            }
+
+            ids[i] = policyIds[i].getId();
+        }
+
+        for (String id : ids) {
+            getBinding().getPolicyService().removePolicy(getRepositoryId(), id, objectId.getId(), null);
+        }
+    }
+}

Propchange: incubator/chemistry/opencmis/branches/client-api-refactoring/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/SessionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native