blob: 8ef29002a5a658f4db0e4cb9e0ae89dae1bcce04 [file] [log] [blame]
/*
* 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using DotCMIS.Binding;
using DotCMIS.Binding.Services;
using DotCMIS.Data;
using DotCMIS.Data.Extensions;
using DotCMIS.Data.Impl;
using DotCMIS.Enums;
using DotCMIS.Exceptions;
namespace DotCMIS.Client.Impl
{
/// <summary>
/// CMIS object base class.
/// </summary>
public abstract class AbstractCmisObject : ICmisObject
{
protected ISession Session { get; private set; }
protected string RepositoryId { get { return Session.RepositoryInfo.Id; } }
protected ICmisBinding Binding { get { return Session.Binding; } }
private IObjectType objectType;
public IObjectType ObjectType
{
get
{
Lock();
try
{
return objectType;
}
finally
{
Unlock();
}
}
}
protected string ObjectId
{
get
{
string objectId = Id;
if (objectId == null)
{
throw new CmisRuntimeException("Object Id is unknown!");
}
return objectId;
}
}
protected IOperationContext CreationContext { get; private set; }
private IDictionary<string, IProperty> properties;
private IAllowableActions allowableActions;
private IList<IRendition> renditions;
private IAcl acl;
private IList<IPolicy> policies;
private IList<IRelationship> relationships;
private IDictionary<ExtensionLevel, IList<ICmisExtensionElement>> extensions;
private object objectLock = new object();
protected void Initialize(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
{
if (session == null)
{
throw new ArgumentNullException("session");
}
if (objectType == null)
{
throw new ArgumentNullException("objectType");
}
if (objectType.PropertyDefintions == null || objectType.PropertyDefintions.Count < 9)
{
// there must be at least the 9 standard properties that all objects have
throw new ArgumentException("Object type must have property defintions!");
}
this.Session = session;
this.objectType = objectType;
this.extensions = new Dictionary<ExtensionLevel, IList<ICmisExtensionElement>>();
this.CreationContext = new OperationContext(context);
this.RefreshTimestamp = DateTime.UtcNow;
IObjectFactory of = Session.ObjectFactory;
if (objectData != null)
{
// handle properties
if (objectData.Properties != null)
{
properties = of.ConvertProperties(objectType, objectData.Properties);
extensions[ExtensionLevel.Properties] = objectData.Properties.Extensions;
}
// handle allowable actions
if (objectData.AllowableActions != null)
{
allowableActions = objectData.AllowableActions;
extensions[ExtensionLevel.AllowableActions] = objectData.AllowableActions.Extensions;
}
// handle renditions
if (objectData.Renditions != null)
{
renditions = new List<IRendition>();
foreach (IRenditionData rd in objectData.Renditions)
{
renditions.Add(of.ConvertRendition(Id, rd));
}
}
// handle ACL
if (objectData.Acl != null)
{
acl = objectData.Acl;
extensions[ExtensionLevel.Acl] = objectData.Acl.Extensions;
}
// handle policies
if (objectData.PolicyIds != null && objectData.PolicyIds.PolicyIds != null)
{
policies = new List<IPolicy>();
foreach (string pid in objectData.PolicyIds.PolicyIds)
{
IPolicy policy = Session.GetObject(Session.CreateObjectId(pid)) as IPolicy;
if (policy != null)
{
policies.Add(policy);
}
}
extensions[ExtensionLevel.Policies] = objectData.PolicyIds.Extensions;
}
// handle relationships
if (objectData.Relationships != null)
{
relationships = new List<IRelationship>();
foreach (IObjectData rod in objectData.Relationships)
{
IRelationship relationship = of.ConvertObject(rod, CreationContext) as IRelationship;
if (relationship != null)
{
relationships.Add(relationship);
}
}
}
extensions[ExtensionLevel.Object] = objectData.Extensions;
}
}
protected string GetPropertyQueryName(string propertyId)
{
Lock();
try
{
IPropertyDefinition propDef = objectType[propertyId];
if (propDef == null)
{
return null;
}
return propDef.QueryName;
}
finally
{
Unlock();
}
}
// --- object ---
public void Delete(bool allVersions)
{
Lock();
try
{
Binding.GetObjectService().DeleteObject(RepositoryId, ObjectId, allVersions, null);
}
finally
{
Unlock();
}
}
public ICmisObject UpdateProperties(IDictionary<string, object> properties)
{
IObjectId objectId = UpdateProperties(properties, true);
if (objectId == null)
{
return null;
}
if (ObjectId != objectId.Id)
{
return Session.GetObject(objectId, CreationContext);
}
return this;
}
public IObjectId UpdateProperties(IDictionary<String, object> properties, bool refresh)
{
if (properties == null || properties.Count == 0)
{
throw new ArgumentException("Properties must not be empty!");
}
string newObjectId = null;
Lock();
try
{
string objectId = ObjectId;
string changeToken = ChangeToken;
HashSet<Updatability> updatebility = new HashSet<Updatability>();
updatebility.Add(Updatability.ReadWrite);
// check if checked out
bool? isCheckedOut = GetPropertyValue(PropertyIds.IsVersionSeriesCheckedOut) as bool?;
if (isCheckedOut.HasValue && isCheckedOut.Value)
{
updatebility.Add(Updatability.WhenCheckedOut);
}
// it's time to update
Binding.GetObjectService().UpdateProperties(RepositoryId, ref objectId, ref changeToken,
Session.ObjectFactory.ConvertProperties(properties, this.objectType, updatebility), null);
newObjectId = objectId;
}
finally
{
Unlock();
}
if (refresh)
{
Refresh();
}
if (newObjectId == null)
{
return null;
}
return Session.CreateObjectId(newObjectId);
}
// --- properties ---
public IObjectType BaseType { get { return Session.GetTypeDefinition(GetPropertyValue(PropertyIds.BaseTypeId) as string); } }
public BaseTypeId BaseTypeId
{
get
{
string baseType = GetPropertyValue(PropertyIds.BaseTypeId) as string;
if (baseType == null) { throw new CmisRuntimeException("Base type not set!"); }
return baseType.GetCmisEnum<BaseTypeId>();
}
}
public string Id { get { return GetPropertyValue(PropertyIds.ObjectId) as string; } }
public string Name { get { return GetPropertyValue(PropertyIds.Name) as string; } }
public string CreatedBy { get { return GetPropertyValue(PropertyIds.CreatedBy) as string; } }
public DateTime? CreationDate { get { return GetPropertyValue(PropertyIds.CreationDate) as DateTime?; } }
public string LastModifiedBy { get { return GetPropertyValue(PropertyIds.LastModifiedBy) as string; } }
public DateTime? LastModificationDate { get { return GetPropertyValue(PropertyIds.LastModificationDate) as DateTime?; } }
public string ChangeToken { get { return GetPropertyValue(PropertyIds.ChangeToken) as string; } }
public IList<IProperty> Properties
{
get
{
Lock();
try
{
return new List<IProperty>(properties.Values);
}
finally
{
Unlock();
}
}
}
public IProperty this[string propertyId]
{
get
{
if (propertyId == null)
{
throw new ArgumentNullException("propertyId");
}
Lock();
try
{
IProperty property;
if (properties.TryGetValue(propertyId, out property))
{
return property;
}
return null;
}
finally
{
Unlock();
}
}
}
public object GetPropertyValue(string propertyId)
{
IProperty property = this[propertyId];
if (property == null) { return null; }
return property.Value;
}
// --- allowable actions ---
public IAllowableActions AllowableActions
{
get
{
Lock();
try
{
return allowableActions;
}
finally
{
Unlock();
}
}
}
// --- renditions ---
public IList<IRendition> Renditions
{
get
{
Lock();
try
{
return renditions;
}
finally
{
Unlock();
}
}
}
// --- ACL ---
public IAcl getAcl(bool onlyBasicPermissions)
{
return Binding.GetAclService().GetAcl(RepositoryId, ObjectId, onlyBasicPermissions, null);
}
public IAcl ApplyAcl(IList<IAce> addAces, IList<IAce> removeAces, AclPropagation? aclPropagation)
{
IAcl result = Session.ApplyAcl(this, addAces, removeAces, aclPropagation);
Refresh();
return result;
}
public IAcl AddAcl(IList<IAce> addAces, AclPropagation? aclPropagation)
{
return ApplyAcl(addAces, null, aclPropagation);
}
public IAcl RemoveAcl(IList<IAce> removeAces, AclPropagation? aclPropagation)
{
return ApplyAcl(null, removeAces, aclPropagation);
}
public IAcl Acl
{
get
{
Lock();
try
{
return acl;
}
finally
{
Unlock();
}
}
}
// --- policies ---
public void ApplyPolicy(params IObjectId[] policyId)
{
Lock();
try
{
Session.ApplyPolicy(this, policyId);
}
finally
{
Unlock();
}
Refresh();
}
public void RemovePolicy(params IObjectId[] policyId)
{
Lock();
try
{
Session.RemovePolicy(this, policyId);
}
finally
{
Unlock();
}
Refresh();
}
public IList<IPolicy> Policies
{
get
{
Lock();
try
{
return policies;
}
finally
{
Unlock();
}
}
}
// --- relationships ---
public IList<IRelationship> Relationships
{
get
{
Lock();
try
{
return relationships;
}
finally
{
Unlock();
}
}
}
// --- extensions ---
public IList<ICmisExtensionElement> GetExtensions(ExtensionLevel level)
{
IList<ICmisExtensionElement> ext;
if (extensions.TryGetValue(level, out ext))
{
return ext;
}
return null;
}
// --- other ---
public DateTime RefreshTimestamp { get; private set; }
public void Refresh()
{
Lock();
try
{
IOperationContext oc = CreationContext;
// get the latest data from the repository
IObjectData objectData = Binding.GetObjectService().GetObject(RepositoryId, ObjectId, oc.FilterString, oc.IncludeAllowableActions,
oc.IncludeRelationships, oc.RenditionFilterString, oc.IncludePolicies, oc.IncludeAcls, null);
// reset this object
Initialize(Session, ObjectType, objectData, CreationContext);
}
finally
{
Unlock();
}
}
public void RefreshIfOld(long durationInMillis)
{
Lock();
try
{
if (((DateTime.UtcNow - RefreshTimestamp).Ticks / 10000) > durationInMillis)
{
Refresh();
}
}
finally
{
Unlock();
}
}
protected void Lock()
{
Monitor.Enter(objectLock);
}
protected void Unlock()
{
Monitor.Exit(objectLock);
}
}
/// <summary>
/// Fileable object base class.
/// </summary>
public abstract class AbstractFileableCmisObject : AbstractCmisObject, IFileableCmisObject
{
public IFileableCmisObject Move(IObjectId sourceFolderId, IObjectId targetFolderId)
{
string objectId = ObjectId;
if (sourceFolderId == null || sourceFolderId.Id == null)
{
throw new ArgumentException("Source folder id must be set!");
}
if (targetFolderId == null || targetFolderId.Id == null)
{
throw new ArgumentException("Target folder id must be set!");
}
Binding.GetObjectService().MoveObject(RepositoryId, ref objectId, targetFolderId.Id, sourceFolderId.Id, null);
if (objectId == null)
{
return null;
}
IFileableCmisObject movedObject = Session.GetObject(Session.CreateObjectId(objectId)) as IFileableCmisObject;
if (movedObject == null)
{
throw new CmisRuntimeException("Moved object is invalid!");
}
return movedObject;
}
public virtual IList<IFolder> Parents
{
get
{
// get object ids of the parent folders
IList<IObjectParentData> bindingParents = Binding.GetNavigationService().GetObjectParents(RepositoryId, ObjectId,
GetPropertyQueryName(PropertyIds.ObjectId), false, IncludeRelationshipsFlag.None, null, false, null);
IList<IFolder> parents = new List<IFolder>();
foreach (IObjectParentData p in bindingParents)
{
if (p == null || p.Object == null || p.Object.Properties == null)
{
// should not happen...
throw new CmisRuntimeException("Repository sent invalid data!");
}
// get id property
IPropertyData idProperty = p.Object.Properties[PropertyIds.ObjectId];
if (idProperty == null || idProperty.PropertyType != PropertyType.Id)
{
// the repository sent an object without a valid object id...
throw new CmisRuntimeException("Repository sent invalid data! No object id!");
}
// fetch the object and make sure it is a folder
IObjectId parentId = Session.CreateObjectId(idProperty.FirstValue as string);
IFolder parentFolder = Session.GetObject(parentId) as IFolder;
if (parentFolder == null)
{
// the repository sent an object that is not a folder...
throw new CmisRuntimeException("Repository sent invalid data! Object is not a folder!");
}
parents.Add(parentFolder);
}
return parents;
}
}
public virtual IList<string> Paths
{
get
{
// get object paths of the parent folders
IList<IObjectParentData> parents = Binding.GetNavigationService().GetObjectParents(
RepositoryId, ObjectId, GetPropertyQueryName(PropertyIds.Path), false, IncludeRelationshipsFlag.None,
null, true, null);
IList<string> paths = new List<string>();
foreach (IObjectParentData p in parents)
{
if (p == null || p.Object == null || p.Object.Properties == null)
{
// should not happen...
throw new CmisRuntimeException("Repository sent invalid data!");
}
// get path property
IPropertyData pathProperty = p.Object.Properties[PropertyIds.Path];
if (pathProperty == null || pathProperty.PropertyType != PropertyType.String)
{
// the repository sent a folder without a valid path...
throw new CmisRuntimeException("Repository sent invalid data! No path property!");
}
if (p.RelativePathSegment == null)
{
// the repository didn't send a relative path segment
throw new CmisRuntimeException("Repository sent invalid data! No relative path segement!");
}
string folderPath = pathProperty.FirstValue as string;
paths.Add(folderPath + (folderPath.EndsWith("/") ? "" : "/") + p.RelativePathSegment);
}
return paths;
}
}
public void AddToFolder(IObjectId folderId, bool allVersions)
{
if (folderId == null || folderId.Id == null)
{
throw new ArgumentException("Folder Id must be set!");
}
Binding.GetMultiFilingService().AddObjectToFolder(RepositoryId, ObjectId, folderId.Id, allVersions, null);
}
public void RemoveFromFolder(IObjectId folderId)
{
if (folderId == null || folderId.Id == null)
{
throw new ArgumentException("Folder Id must be set!");
}
Binding.GetMultiFilingService().RemoveObjectFromFolder(RepositoryId, ObjectId, folderId.Id, null);
}
}
/// <summary>
/// Document implemetation.
/// </summary>
public class Document : AbstractFileableCmisObject, IDocument
{
public Document(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
{
Initialize(session, objectType, objectData, context);
}
// properties
public bool? IsImmutable { get { return GetPropertyValue(PropertyIds.IsImmutable) as bool?; } }
public bool? IsLatestVersion { get { return GetPropertyValue(PropertyIds.IsLatestVersion) as bool?; } }
public bool? IsMajorVersion { get { return GetPropertyValue(PropertyIds.IsMajorVersion) as bool?; } }
public bool? IsLatestMajorVersion { get { return GetPropertyValue(PropertyIds.IsLatestMajorVersion) as bool?; } }
public string VersionLabel { get { return GetPropertyValue(PropertyIds.VersionLabel) as string; } }
public string VersionSeriesId { get { return GetPropertyValue(PropertyIds.VersionSeriesId) as string; } }
public bool? IsVersionSeriesCheckedOut { get { return GetPropertyValue(PropertyIds.IsVersionSeriesCheckedOut) as bool?; } }
public string VersionSeriesCheckedOutBy { get { return GetPropertyValue(PropertyIds.VersionSeriesCheckedOutBy) as string; } }
public string VersionSeriesCheckedOutId { get { return GetPropertyValue(PropertyIds.VersionSeriesCheckedOutId) as string; } }
public string CheckinComment { get { return GetPropertyValue(PropertyIds.CheckinComment) as string; } }
public long? ContentStreamLength { get { return GetPropertyValue(PropertyIds.ContentStreamLength) as long?; } }
public string ContentStreamMimeType { get { return GetPropertyValue(PropertyIds.ContentStreamMimeType) as string; } }
public string ContentStreamFileName { get { return GetPropertyValue(PropertyIds.ContentStreamFileName) as string; } }
public string ContentStreamId { get { return GetPropertyValue(PropertyIds.ContentStreamId) as string; } }
// operations
public IDocument Copy(IObjectId targetFolderId, IDictionary<string, object> properties, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
IObjectId newId = Session.CreateDocumentFromSource(this, properties, targetFolderId, versioningState, policies, addAces, removeAces);
// if no context is provided the object will not be fetched
if (context == null || newId == null)
{
return null;
}
// get the new object
IDocument newDoc = Session.GetObject(newId, context) as IDocument;
if (newDoc == null)
{
throw new CmisRuntimeException("Newly created object is not a document! New id: " + newId);
}
return newDoc;
}
public IDocument Copy(IObjectId targetFolderId)
{
return Copy(targetFolderId, null, null, null, null, null, Session.DefaultContext);
}
public void DeleteAllVersions()
{
Delete(true);
}
// versioning
public IObjectId CheckOut()
{
string newObjectId = null;
Lock();
try
{
string objectId = ObjectId;
bool? contentCopied;
Binding.GetVersioningService().CheckOut(RepositoryId, ref objectId, null, out contentCopied);
newObjectId = objectId;
}
finally
{
Unlock();
}
if (newObjectId == null)
{
return null;
}
return Session.CreateObjectId(newObjectId);
}
public void CancelCheckOut()
{
Binding.GetVersioningService().CancelCheckOut(RepositoryId, ObjectId, null);
}
public IObjectId CheckIn(bool major, IDictionary<string, object> properties, IContentStream contentStream,
string checkinComment, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces)
{
String newObjectId = null;
Lock();
try
{
string objectId = ObjectId;
IObjectFactory of = Session.ObjectFactory;
HashSet<Updatability> updatebility = new HashSet<Updatability>();
updatebility.Add(Updatability.ReadWrite);
updatebility.Add(Updatability.WhenCheckedOut);
Binding.GetVersioningService().CheckIn(RepositoryId, ref objectId, major, of.ConvertProperties(properties, ObjectType, updatebility),
contentStream, checkinComment, of.ConvertPolicies(policies), of.ConvertAces(addAces), of.ConvertAces(removeAces), null);
newObjectId = objectId;
}
finally
{
Unlock();
}
if (newObjectId == null)
{
return null;
}
return Session.CreateObjectId(newObjectId);
}
public IList<IDocument> GetAllVersions()
{
return GetAllVersions(Session.DefaultContext);
}
public IList<IDocument> GetAllVersions(IOperationContext context)
{
string objectId;
string versionSeriesId;
Lock();
try
{
objectId = ObjectId;
versionSeriesId = VersionSeriesId;
}
finally
{
Unlock();
}
IList<IObjectData> versions = Binding.GetVersioningService().GetAllVersions(RepositoryId, objectId, versionSeriesId,
context.FilterString, context.IncludeAllowableActions, null);
IObjectFactory of = Session.ObjectFactory;
IList<IDocument> result = new List<IDocument>();
if (versions != null)
{
foreach (IObjectData objectData in versions)
{
IDocument doc = of.ConvertObject(objectData, context) as IDocument;
if (doc == null)
{
// should not happen...
continue;
}
result.Add(doc);
}
}
return result;
}
public IDocument GetObjectOfLatestVersion(bool major)
{
return GetObjectOfLatestVersion(major, Session.DefaultContext);
}
public IDocument GetObjectOfLatestVersion(bool major, IOperationContext context)
{
string objectId;
string versionSeriesId;
Lock();
try
{
objectId = ObjectId;
versionSeriesId = VersionSeriesId;
}
finally
{
Unlock();
}
if (versionSeriesId == null)
{
throw new CmisRuntimeException("Version series id is unknown!");
}
IObjectData objectData = Binding.GetVersioningService().GetObjectOfLatestVersion(RepositoryId, objectId, versionSeriesId, major,
context.FilterString, context.IncludeAllowableActions, context.IncludeRelationships, context.RenditionFilterString,
context.IncludePolicies, context.IncludeAcls, null);
IDocument result = Session.ObjectFactory.ConvertObject(objectData, context) as IDocument;
if (result == null)
{
throw new CmisRuntimeException("Latest version is not a document!");
}
return result;
}
// content operations
public IContentStream GetContentStream()
{
return GetContentStream(null);
}
public IContentStream GetContentStream(String streamId)
{
IContentStream contentStream;
try
{
contentStream = Binding.GetObjectService().GetContentStream(RepositoryId, ObjectId, streamId, null, null, null);
}
catch (CmisConstraintException)
{
// no content stream
return null;
}
// the AtomPub binding doesn't return a file name
// -> get the file name from properties, if present
if (contentStream.FileName == null && ContentStreamFileName != null)
{
ContentStream newContentStream = new ContentStream();
newContentStream.FileName = ContentStreamFileName;
newContentStream.Length = contentStream.Length;
newContentStream.MimeType = contentStream.MimeType;
newContentStream.Stream = contentStream.Stream;
newContentStream.Extensions = contentStream.Extensions;
contentStream = newContentStream;
}
return contentStream;
}
public IDocument SetContentStream(IContentStream contentStream, bool overwrite)
{
IObjectId objectId = SetContentStream(contentStream, overwrite, true);
if (objectId == null)
{
return null;
}
if (ObjectId != objectId.Id)
{
return (IDocument)Session.GetObject(objectId, CreationContext);
}
return this;
}
public IObjectId SetContentStream(IContentStream contentStream, bool overwrite, bool refresh)
{
string newObjectId = null;
Lock();
try
{
string objectId = ObjectId;
string changeToken = ChangeToken;
Binding.GetObjectService().SetContentStream(RepositoryId, ref objectId, overwrite, ref changeToken, contentStream, null);
newObjectId = objectId;
}
finally
{
Unlock();
}
if (refresh)
{
Refresh();
}
if (newObjectId == null)
{
return null;
}
return Session.CreateObjectId(newObjectId);
}
public IDocument DeleteContentStream()
{
IObjectId objectId = DeleteContentStream(true);
if (objectId == null)
{
return null;
}
if (ObjectId != objectId.Id)
{
return (IDocument)Session.GetObject(objectId, CreationContext);
}
return this;
}
public IObjectId DeleteContentStream(bool refresh)
{
string newObjectId = null;
Lock();
try
{
string objectId = ObjectId;
string changeToken = ChangeToken;
Binding.GetObjectService().DeleteContentStream(RepositoryId, ref objectId, ref changeToken, null);
newObjectId = objectId;
}
finally
{
Unlock();
}
if (refresh)
{
Refresh();
}
if (newObjectId == null)
{
return null;
}
return Session.CreateObjectId(newObjectId);
}
public IObjectId CheckIn(bool major, IDictionary<String, object> properties, IContentStream contentStream, string checkinComment)
{
return this.CheckIn(major, properties, contentStream, checkinComment, null, null, null);
}
}
/// <summary>
/// Folder implemetation.
/// </summary>
public class Folder : AbstractFileableCmisObject, IFolder
{
public Folder(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
{
Initialize(session, objectType, objectData, context);
}
public IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
IObjectId newId = Session.CreateDocument(properties, this, contentStream, versioningState, policies, addAces, removeAces);
// if no context is provided the object will not be fetched
if (context == null || newId == null)
{
return null;
}
// get the new object
IDocument newDoc = Session.GetObject(newId, context) as IDocument;
if (newDoc == null)
{
throw new CmisRuntimeException("Newly created object is not a document! New id: " + newId);
}
return newDoc;
}
public IDocument CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, VersioningState? versioningState,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
IObjectId newId = Session.CreateDocumentFromSource(source, properties, this, versioningState, policies, addAces, removeAces);
// if no context is provided the object will not be fetched
if (context == null || newId == null)
{
return null;
}
// get the new object
IDocument newDoc = Session.GetObject(newId, context) as IDocument;
if (newDoc == null)
{
throw new CmisRuntimeException("Newly created object is not a document! New id: " + newId);
}
return newDoc;
}
public IFolder CreateFolder(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
IObjectId newId = Session.CreateFolder(properties, this, policies, addAces, removeAces);
// if no context is provided the object will not be fetched
if (context == null || newId == null)
{
return null;
}
// get the new object
IFolder newFolder = Session.GetObject(newId, context) as IFolder;
if (newFolder == null)
{
throw new CmisRuntimeException("Newly created object is not a folder! New id: " + newId);
}
return newFolder;
}
public IPolicy CreatePolicy(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces, IOperationContext context)
{
IObjectId newId = Session.CreatePolicy(properties, this, policies, addAces, removeAces);
// if no context is provided the object will not be fetched
if (context == null || newId == null)
{
return null;
}
// get the new object
IPolicy newPolicy = Session.GetObject(newId, context) as IPolicy;
if (newPolicy == null)
{
throw new CmisRuntimeException("Newly created object is not a policy! New id: " + newId);
}
return newPolicy;
}
public IList<string> DeleteTree(bool allVersions, UnfileObject? unfile, bool continueOnFailure)
{
IFailedToDeleteData failed = Binding.GetObjectService().DeleteTree(RepositoryId, ObjectId, allVersions, unfile, continueOnFailure, null);
return failed.Ids;
}
public IList<IObjectType> AllowedChildObjectTypes
{
get
{
IList<IObjectType> result = new List<IObjectType>();
Lock();
try
{
IList<string> otids = GetPropertyValue(PropertyIds.AllowedChildObjectTypeIds) as IList<string>;
if (otids == null)
{
return result;
}
foreach (string otid in otids)
{
result.Add(Session.GetTypeDefinition(otid));
}
}
finally
{
Unlock();
}
return result;
}
}
public IItemEnumerable<IDocument> GetCheckedOutDocs()
{
return GetCheckedOutDocs(Session.DefaultContext);
}
public IItemEnumerable<IDocument> GetCheckedOutDocs(IOperationContext context)
{
string objectId = ObjectId;
INavigationService service = Binding.GetNavigationService();
IObjectFactory of = Session.ObjectFactory;
IOperationContext ctxt = new OperationContext(context);
PageFetcher<IDocument>.FetchPage fetchPageDelegate = delegate(long maxNumItems, long skipCount)
{
// get checked out documents for this folder
IObjectList checkedOutDocs = service.GetCheckedOutDocs(RepositoryId, objectId, ctxt.FilterString, ctxt.OrderBy, ctxt.IncludeAllowableActions,
ctxt.IncludeRelationships, ctxt.RenditionFilterString, maxNumItems, skipCount, null);
IList<IDocument> page = new List<IDocument>();
if (checkedOutDocs.Objects != null)
{
foreach (IObjectData objectData in checkedOutDocs.Objects)
{
IDocument doc = of.ConvertObject(objectData, ctxt) as IDocument;
if (doc == null)
{
// should not happen...
continue;
}
page.Add(doc);
}
}
return new PageFetcher<IDocument>.Page<IDocument>(page, checkedOutDocs.NumItems, checkedOutDocs.HasMoreItems);
};
return new CollectionEnumerable<IDocument>(new PageFetcher<IDocument>(ctxt.MaxItemsPerPage, fetchPageDelegate));
}
public IItemEnumerable<ICmisObject> GetChildren()
{
return GetChildren(Session.DefaultContext);
}
public IItemEnumerable<ICmisObject> GetChildren(IOperationContext context)
{
string objectId = ObjectId;
INavigationService service = Binding.GetNavigationService();
IObjectFactory of = Session.ObjectFactory;
IOperationContext ctxt = new OperationContext(context);
PageFetcher<ICmisObject>.FetchPage fetchPageDelegate = delegate(long maxNumItems, long skipCount)
{
// get the children
IObjectInFolderList children = service.GetChildren(RepositoryId, objectId, ctxt.FilterString, ctxt.OrderBy, ctxt.IncludeAllowableActions,
ctxt.IncludeRelationships, ctxt.RenditionFilterString, ctxt.IncludePathSegments, maxNumItems, skipCount, null);
// convert objects
IList<ICmisObject> page = new List<ICmisObject>();
if (children.Objects != null)
{
foreach (IObjectInFolderData objectData in children.Objects)
{
if (objectData.Object != null)
{
page.Add(of.ConvertObject(objectData.Object, ctxt));
}
}
}
return new PageFetcher<ICmisObject>.Page<ICmisObject>(page, children.NumItems, children.HasMoreItems);
};
return new CollectionEnumerable<ICmisObject>(new PageFetcher<ICmisObject>(ctxt.MaxItemsPerPage, fetchPageDelegate));
}
public IList<ITree<IFileableCmisObject>> GetDescendants(int depth)
{
return GetDescendants(depth, Session.DefaultContext);
}
public IList<ITree<IFileableCmisObject>> GetDescendants(int depth, IOperationContext context)
{
IList<IObjectInFolderContainer> bindingContainerList = Binding.GetNavigationService().GetDescendants(RepositoryId, ObjectId, depth,
context.FilterString, context.IncludeAllowableActions, context.IncludeRelationships, context.RenditionFilterString,
context.IncludePathSegments, null);
return ConvertProviderContainer(bindingContainerList, context);
}
public IList<ITree<IFileableCmisObject>> GetFolderTree(int depth)
{
return GetFolderTree(depth, Session.DefaultContext);
}
public IList<ITree<IFileableCmisObject>> GetFolderTree(int depth, IOperationContext context)
{
IList<IObjectInFolderContainer> bindingContainerList = Binding.GetNavigationService().GetFolderTree(RepositoryId, ObjectId, depth,
context.FilterString, context.IncludeAllowableActions, context.IncludeRelationships, context.RenditionFilterString,
context.IncludePathSegments, null);
return ConvertProviderContainer(bindingContainerList, context);
}
private IList<ITree<IFileableCmisObject>> ConvertProviderContainer(IList<IObjectInFolderContainer> bindingContainerList, IOperationContext context)
{
if (bindingContainerList == null)
{
return null;
}
IList<ITree<IFileableCmisObject>> result = new List<ITree<IFileableCmisObject>>();
foreach (IObjectInFolderContainer oifc in bindingContainerList)
{
if (oifc.Object == null || oifc.Object.Object == null)
{
// shouldn't happen ...
continue;
}
// convert the object
IFileableCmisObject cmisObject = Session.ObjectFactory.ConvertObject(oifc.Object.Object, context) as IFileableCmisObject;
if (cmisObject == null)
{
// the repository must not return objects that are not fileable, but you never know...
continue;
}
// convert the children
IList<ITree<IFileableCmisObject>> children = ConvertProviderContainer(oifc.Children, context);
// add both to current container
Tree<IFileableCmisObject> tree = new Tree<IFileableCmisObject>();
tree.Item = cmisObject;
tree.Children = children;
result.Add(tree);
}
return result;
}
public bool IsRootFolder { get { return ObjectId == Session.RepositoryInfo.RootFolderId; } }
public IFolder FolderParent
{
get
{
if (IsRootFolder)
{
return null;
}
IList<IFolder> parents = Parents;
if (parents == null || parents.Count == 0)
{
return null;
}
return parents[0];
}
}
public string Path
{
get
{
string path;
Lock();
try
{
// get the path property
path = GetPropertyValue(PropertyIds.Path) as string;
// if the path property isn't set, get it
if (path == null)
{
IObjectData objectData = Binding.GetObjectService().GetObject(RepositoryId, ObjectId,
GetPropertyQueryName(PropertyIds.Path), false, IncludeRelationshipsFlag.None, "cmis:none", false,
false, null);
if (objectData.Properties != null)
{
IPropertyData pathProperty = objectData.Properties[PropertyIds.Path];
if (pathProperty != null && pathProperty.PropertyType == PropertyType.String)
{
path = pathProperty.FirstValue as string;
}
}
}
}
finally
{
Unlock();
}
// 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;
}
}
public override IList<string> Paths
{
get
{
IList<string> result = new List<string>();
result.Add(Path);
return result;
}
}
public IDocument CreateDocument(IDictionary<string, object> properties, IContentStream contentStream, VersioningState? versioningState)
{
return CreateDocument(properties, contentStream, versioningState, null, null, null, Session.DefaultContext);
}
public IDocument CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, VersioningState? versioningState)
{
return CreateDocumentFromSource(source, properties, versioningState, null, null, null, Session.DefaultContext);
}
public IFolder CreateFolder(IDictionary<string, object> properties)
{
return CreateFolder(properties, null, null, null, Session.DefaultContext);
}
public IPolicy CreatePolicy(IDictionary<string, object> properties)
{
return CreatePolicy(properties, null, null, null, Session.DefaultContext);
}
}
/// <summary>
/// Policy implemetation.
/// </summary>
public class Policy : AbstractFileableCmisObject, IPolicy
{
public Policy(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
{
Initialize(session, objectType, objectData, context);
}
public string PolicyText { get { return GetPropertyValue(PropertyIds.PolicyText) as string; } }
}
/// <summary>
/// Relationship implemetation.
/// </summary>
public class Relationship : AbstractCmisObject, IRelationship
{
public Relationship(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
{
Initialize(session, objectType, objectData, context);
}
public ICmisObject GetSource()
{
return GetSource(Session.DefaultContext);
}
public ICmisObject GetSource(IOperationContext context)
{
Lock();
try
{
IObjectId sourceId = SourceId;
if (sourceId == null)
{
return null;
}
return Session.GetObject(sourceId, context);
}
finally
{
Unlock();
}
}
public IObjectId SourceId
{
get
{
string sourceId = GetPropertyValue(PropertyIds.SourceId) as string;
if (sourceId == null || sourceId.Length == 0)
{
return null;
}
return Session.CreateObjectId(sourceId);
}
}
public ICmisObject GetTarget()
{
return GetTarget(Session.DefaultContext);
}
public ICmisObject GetTarget(IOperationContext context)
{
Lock();
try
{
IObjectId targetId = TargetId;
if (targetId == null)
{
return null;
}
return Session.GetObject(targetId, context);
}
finally
{
Unlock();
}
}
public IObjectId TargetId
{
get
{
string targetId = GetPropertyValue(PropertyIds.TargetId) as string;
if (targetId == null || targetId.Length == 0)
{
return null;
}
return Session.CreateObjectId(targetId);
}
}
}
public class Property : IProperty
{
public Property(IPropertyDefinition propertyDefinition, IList<object> values)
{
PropertyDefinition = propertyDefinition;
Values = values;
}
public string Id { get { return PropertyDefinition.Id; } }
public string LocalName { get { return PropertyDefinition.LocalName; } }
public string DisplayName { get { return PropertyDefinition.DisplayName; } }
public string QueryName { get { return PropertyDefinition.QueryName; } }
public bool IsMultiValued { get { return PropertyDefinition.Cardinality == Cardinality.Multi; } }
public PropertyType? PropertyType { get { return PropertyDefinition.PropertyType; } }
public IPropertyDefinition PropertyDefinition { get; protected set; }
public object Value
{
get
{
if (PropertyDefinition.Cardinality == Cardinality.Single)
{
return Values == null || Values.Count == 0 ? null : Values[0];
}
else
{
return Values;
}
}
}
public IList<object> Values { get; protected set; }
public object FirstValue { get { return Values == null || Values.Count == 0 ? null : Values[0]; } }
public string ValueAsString { get { return FormatValue(FirstValue); } }
public string ValuesAsString
{
get
{
StringBuilder result = new StringBuilder();
foreach (object value in Values)
{
if (result.Length > 0)
{
result.Append(", ");
}
result.Append(FormatValue(value));
}
return "[" + result.ToString() + "]";
}
}
private string FormatValue(object value)
{
if (value == null)
{
return null;
}
// for future formating
return value.ToString();
}
}
public class Rendition : RenditionData, IRendition
{
private ISession session;
private string objectId;
public Rendition(ISession session, string objectId, string streamId, string mimeType, long? length, string kind,
string title, long? height, long? width, string renditionDocumentId)
{
this.session = session;
this.objectId = objectId;
StreamId = streamId;
MimeType = mimeType;
Length = length;
Kind = kind;
Title = title;
Height = height;
Width = width;
RenditionDocumentId = renditionDocumentId;
}
public IDocument GetRenditionDocument()
{
return GetRenditionDocument(session.DefaultContext);
}
public IDocument GetRenditionDocument(IOperationContext context)
{
if (RenditionDocumentId == null)
{
return null;
}
return session.GetObject(session.CreateObjectId(RenditionDocumentId), context) as IDocument;
}
public IContentStream GetContentStream()
{
if (objectId == null || StreamId == null)
{
return null;
}
return session.Binding.GetObjectService().GetContentStream(session.RepositoryInfo.Id, objectId, StreamId, null, null, null);
}
}
public class QueryResult : IQueryResult
{
private IDictionary<string, IPropertyData> propertiesById;
private IDictionary<string, IPropertyData> propertiesByQueryName;
public QueryResult(ISession session, IObjectData objectData)
{
if (objectData != null)
{
IObjectFactory of = session.ObjectFactory;
// handle properties
if (objectData.Properties != null)
{
Properties = new List<IPropertyData>();
propertiesById = new Dictionary<string, IPropertyData>();
propertiesByQueryName = new Dictionary<string, IPropertyData>();
IList<IPropertyData> queryProperties = of.ConvertQueryProperties(objectData.Properties);
foreach (IPropertyData property in queryProperties)
{
Properties.Add(property);
if (property.Id != null)
{
propertiesById[property.Id] = property;
}
if (property.QueryName != null)
{
propertiesByQueryName[property.QueryName] = property;
}
}
}
// handle allowable actions
AllowableActions = objectData.AllowableActions;
// handle relationships
if (objectData.Relationships != null)
{
Relationships = new List<IRelationship>();
foreach (IObjectData rod in objectData.Relationships)
{
IRelationship relationship = of.ConvertObject(rod, session.DefaultContext) as IRelationship;
if (relationship != null)
{
Relationships.Add(relationship);
}
}
}
// handle renditions
if (objectData.Renditions != null)
{
Renditions = new List<IRendition>();
foreach (IRenditionData rd in objectData.Renditions)
{
Renditions.Add(of.ConvertRendition(null, rd));
}
}
}
}
public IPropertyData this[string queryName]
{
get
{
if (queryName == null)
{
return null;
}
IPropertyData result;
if (propertiesByQueryName.TryGetValue(queryName, out result))
{
return result;
}
return null;
}
}
public IList<IPropertyData> Properties { get; protected set; }
public IPropertyData GetPropertyById(string propertyId)
{
if (propertyId == null)
{
return null;
}
IPropertyData result;
if (propertiesById.TryGetValue(propertyId, out result))
{
return result;
}
return null;
}
public object GetPropertyValueByQueryName(string queryName)
{
IPropertyData property = this[queryName];
if (property == null)
{
return null;
}
return property.FirstValue;
}
public object GetPropertyValueById(string propertyId)
{
IPropertyData property = GetPropertyById(propertyId);
if (property == null)
{
return null;
}
return property.FirstValue;
}
public IList<object> GetPropertyMultivalueByQueryName(string queryName)
{
IPropertyData property = this[queryName];
if (property == null)
{
return null;
}
return property.Values;
}
public IList<object> GetPropertyMultivalueById(string propertyId)
{
IPropertyData property = GetPropertyById(propertyId);
if (property == null)
{
return null;
}
return property.Values;
}
public IAllowableActions AllowableActions { get; protected set; }
public IList<IRelationship> Relationships { get; protected set; }
public IList<IRendition> Renditions { get; protected set; }
}
}