added CmisObject implementations
git-svn-id: https://svn.apache.org/repos/asf/incubator/chemistry/dotcmis/trunk@1067465 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/DotCMIS/binding/atompub/atompub.cs b/DotCMIS/binding/atompub/atompub.cs
index 4db125c..f7c9fed 100644
--- a/DotCMIS/binding/atompub/atompub.cs
+++ b/DotCMIS/binding/atompub/atompub.cs
@@ -113,7 +113,7 @@
// nothing to do
}
- public void Close()
+ public void Dispose()
{
// nothing to do
}
@@ -2118,7 +2118,7 @@
}
public void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
- IContentStream contentStream, string checkinComment, List<string> policies, IAcl addAces, IAcl removeAces,
+ IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
IExtensionsData extension)
{
// we need an object id
diff --git a/DotCMIS/binding/binding-impl.cs b/DotCMIS/binding/binding-impl.cs
index 450034a..ec3fa86 100644
--- a/DotCMIS/binding/binding-impl.cs
+++ b/DotCMIS/binding/binding-impl.cs
@@ -35,7 +35,6 @@
internal class CmisBinding : ICmisBinding
{
private BindingSession session;
- private BindingsObjectFactory objectFactory;
private BindingRepositoryService repositoryServiceWrapper;
public CmisBinding(IDictionary<string, string> sessionParameters)
@@ -57,9 +56,6 @@
session.PutValue(key, sessionParameters[key]);
}
- // set up object factory
- objectFactory = new BindingsObjectFactory();
-
// set up authentication provider
string authenticationProviderClass;
if (sessionParameters.TryGetValue(SessionParameter.AuthenticationProviderClass, out authenticationProviderClass))
@@ -149,11 +145,6 @@
return spi.GetPolicyService();
}
- public IBindingsObjectFactory GetObjectFactory()
- {
- return objectFactory;
- }
-
public void ClearAllCaches()
{
CheckSession();
@@ -200,14 +191,14 @@
}
}
- public void Close()
+ public void Dispose()
{
CheckSession();
session.Lock();
try
{
- GetSpi().Close();
+ GetSpi().Dispose();
}
finally
{
@@ -564,41 +555,21 @@
}
/// <summary>
- /// Object factory implementation.
- /// </summary>
- internal class BindingsObjectFactory : IBindingsObjectFactory
- {
- }
-
- /// <summary>
/// SPI interface.
/// </summary>
- internal interface ICmisSpi
+ internal interface ICmisSpi : IDisposable
{
void initialize(BindingSession session);
-
IRepositoryService GetRepositoryService();
-
INavigationService GetNavigationService();
-
IObjectService GetObjectService();
-
IVersioningService GetVersioningService();
-
IRelationshipService GetRelationshipService();
-
IDiscoveryService GetDiscoveryService();
-
IMultiFilingService GetMultiFilingService();
-
IAclService GetAclService();
-
IPolicyService GetPolicyService();
-
void ClearAllCaches();
-
void ClearRepositoryCache(string repositoryId);
-
- void Close();
}
}
diff --git a/DotCMIS/binding/binding-intf.cs b/DotCMIS/binding/binding-intf.cs
index 9b38241..ca3ba34 100644
--- a/DotCMIS/binding/binding-intf.cs
+++ b/DotCMIS/binding/binding-intf.cs
@@ -18,16 +18,14 @@
*/
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using DotCMIS.Binding.Services;
-using DotCMIS.Binding.Impl;
-using DotCMIS.CMISWebServicesReference;
using System.Net;
+using DotCMIS.Binding.Impl;
+using DotCMIS.Binding.Services;
+using DotCMIS.CMISWebServicesReference;
namespace DotCMIS.Binding
{
- public interface ICmisBinding
+ public interface ICmisBinding : IDisposable
{
IRepositoryService GetRepositoryService();
INavigationService GetNavigationService();
@@ -38,10 +36,8 @@
IMultiFilingService GetMultiFilingService();
IAclService GetAclService();
IPolicyService GetPolicyService();
- IBindingsObjectFactory GetObjectFactory();
void ClearAllCaches();
void ClearRepositoryCache(string repositoryId);
- void Close();
}
public interface IBindingSession
@@ -131,11 +127,6 @@
}
}
-
- public interface IBindingsObjectFactory
- {
- }
-
public class CmisBindingFactory
{
// Default CMIS AtomPub binding SPI implementation
diff --git a/DotCMIS/binding/converter.cs b/DotCMIS/binding/converter.cs
index c261cc8..2bdda14 100644
--- a/DotCMIS/binding/converter.cs
+++ b/DotCMIS/binding/converter.cs
@@ -424,9 +424,9 @@
result.DisplayName = propDef.displayName;
result.QueryName = propDef.queryName;
result.Description = propDef.description;
- result.PropertyType = (PropertyType?)CmisValue.SerializerToCmisEnum(propDef.propertyType);
- result.Cardinality = (Cardinality?)CmisValue.SerializerToCmisEnum(propDef.cardinality);
- result.Updatability = (Updatability?)CmisValue.SerializerToCmisEnum(propDef.updatability);
+ result.PropertyType = (PropertyType)CmisValue.SerializerToCmisEnum(propDef.propertyType);
+ result.Cardinality = (Cardinality)CmisValue.SerializerToCmisEnum(propDef.cardinality);
+ result.Updatability = (Updatability)CmisValue.SerializerToCmisEnum(propDef.updatability);
result.IsInherited = (propDef.inheritedSpecified ? (bool?)propDef.inherited : null);
result.IsRequired = propDef.required;
result.IsQueryable = propDef.queryable;
@@ -702,7 +702,7 @@
{
if (property == null) { return null; }
- PropertyData result = null;
+ AbstractPropertyData result = null;
if (property is cmisPropertyString)
{
result = new PropertyString();
diff --git a/DotCMIS/binding/services.cs b/DotCMIS/binding/services.cs
index f7b1844..ff0446a 100644
--- a/DotCMIS/binding/services.cs
+++ b/DotCMIS/binding/services.cs
@@ -123,7 +123,7 @@
void CancelCheckOut(string repositoryId, string objectId, IExtensionsData extension);
void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
- IContentStream contentStream, string checkinComment, List<string> policies, IAcl addAces, IAcl removeAces,
+ IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
IExtensionsData extension);
IObjectData GetObjectOfLatestVersion(string repositoryId, string objectId, string versionSeriesId, bool major,
diff --git a/DotCMIS/binding/webservices/webservices.cs b/DotCMIS/binding/webservices/webservices.cs
index 3b8efed..d27d297 100644
--- a/DotCMIS/binding/webservices/webservices.cs
+++ b/DotCMIS/binding/webservices/webservices.cs
@@ -114,7 +114,7 @@
// nothing to do
}
- public void Close()
+ public void Dispose()
{
// nothing to do
}
@@ -1110,7 +1110,7 @@
}
public void CheckIn(string repositoryId, ref string objectId, bool? major, IProperties properties,
- IContentStream contentStream, string checkinComment, List<string> policies, IAcl addAces, IAcl removeAces,
+ IContentStream contentStream, string checkinComment, IList<string> policies, IAcl addAces, IAcl removeAces,
IExtensionsData extension)
{
VersioningServicePortClient port = Provider.GetVersioningService();
diff --git a/DotCMIS/client/client-impl.cs b/DotCMIS/client/client-impl.cs
index 603b912..9319ab9 100644
--- a/DotCMIS/client/client-impl.cs
+++ b/DotCMIS/client/client-impl.cs
@@ -243,15 +243,15 @@
cacheType = typeof(NoCache);
}
- object cacheObject = Activator.CreateInstance(cacheType);
- if (!(cacheObject is ICache))
+ ICache cacheObject = Activator.CreateInstance(cacheType) as ICache;
+ if (cacheObject == null)
{
throw new Exception("Class does not implement ICache!");
}
- ((ICache)cacheObject).Initialize(this, parameters);
+ cacheObject.Initialize(this, parameters);
- return (ICache)cacheObject;
+ return cacheObject;
}
catch (Exception e)
{
@@ -275,15 +275,15 @@
ofType = typeof(ObjectFactory);
}
- object ofObject = Activator.CreateInstance(ofType);
- if (!(ofObject is IObjectFactory))
+ IObjectFactory ofObject = Activator.CreateInstance(ofType) as IObjectFactory;
+ if (ofObject == null)
{
throw new Exception("Class does not implement IObjectFactory!");
}
- ((IObjectFactory)ofObject).Initialize(this, parameters);
+ ofObject.Initialize(this, parameters);
- return (IObjectFactory)ofObject;
+ return ofObject;
}
catch (Exception e)
{
@@ -335,12 +335,12 @@
public IItemEnumerable<IObjectType> GetTypeChildren(string typeId, bool includePropertyDefinitions)
{
- IRepositoryService repositoryService = Binding.GetRepositoryService();
+ IRepositoryService service = Binding.GetRepositoryService();
PageFetcher<IObjectType>.FetchPage fetchPageDelegate = delegate(long maxNumItems, long skipCount)
{
// fetch the data
- ITypeDefinitionList tdl = repositoryService.GetTypeChildren(RepositoryId, typeId, includePropertyDefinitions, maxNumItems, skipCount, null);
+ ITypeDefinitionList tdl = service.GetTypeChildren(RepositoryId, typeId, includePropertyDefinitions, maxNumItems, skipCount, null);
// convert type definitions
IList<IObjectType> page = new List<IObjectType>(tdl.List.Count);
@@ -388,13 +388,13 @@
public IFolder GetRootFolder(IOperationContext context)
{
- ICmisObject rootFolder = GetObject(CreateObjectId(RepositoryInfo.RootFolderId), context);
- if (!(rootFolder is IFolder))
+ IFolder rootFolder = GetObject(CreateObjectId(RepositoryInfo.RootFolderId), context) as IFolder;
+ if (rootFolder == null)
{
throw new CmisRuntimeException("Root folder object is not a folder!");
}
- return (IFolder)rootFolder;
+ return rootFolder;
}
public IItemEnumerable<IDocument> GetCheckedOutDocs()
diff --git a/DotCMIS/client/client-intf.cs b/DotCMIS/client/client-intf.cs
index f551d5b..dbe44ce 100644
--- a/DotCMIS/client/client-intf.cs
+++ b/DotCMIS/client/client-intf.cs
@@ -120,7 +120,7 @@
// ACL and ACE
IAcl ConvertAces(IList<IAce> aces);
IAcl CreateAcl(IList<IAce> aces);
- IAce CreateAce(string principal, List<string> permissions);
+ IAce CreateAce(string principal, IList<string> permissions);
// policies
IList<string> ConvertPolicies(IList<IPolicy> policies);
@@ -130,14 +130,13 @@
// content stream
IContentStream CreateContentStream(string filename, long length, string mimetype, Stream stream);
- IContentStream ConvertContentStream(IContentStream contentStream);
// types
IObjectType ConvertTypeDefinition(ITypeDefinition typeDefinition);
IObjectType GetTypeFromObjectData(IObjectData objectData);
// properties
- IProperty CreateProperty(IPropertyDefinition type, IList<object> values);
+ IProperty CreateProperty<T>(IPropertyDefinition type, IList<T> values);
IDictionary<string, IProperty> ConvertProperties(IObjectType objectType, IProperties properties);
IProperties ConvertProperties(IDictionary<string, object> properties, IObjectType type, HashSet<Updatability> updatabilityFilter);
IList<IPropertyData> ConvertQueryProperties(IProperties properties);
@@ -223,12 +222,18 @@
IContentStream GetContentStream();
}
- public interface IProperty : IPropertyData
+ public interface IProperty
{
+ string Id { get; }
+ string LocalName { get; }
+ string DisplayName { get; }
+ string QueryName { get; }
bool IsMultiValued { get; }
- PropertyType PropertyType { get; }
- PropertyDefinition PropertyDefinition { get; }
+ PropertyType? PropertyType { get; }
+ IPropertyDefinition PropertyDefinition { get; }
object Value { get; }
+ IList<object> Values { get; }
+ object FirstValue { get; }
string ValueAsString { get; }
string ValuesAsString { get; }
}
@@ -296,8 +301,8 @@
IFileableCmisObject Move(IObjectId sourceFolderId, IObjectId targetFolderId);
// navigation service
- IList<IFolder> GetParents();
- IList<string> GetPaths();
+ IList<IFolder> Parents { get; }
+ IList<string> Paths { get; }
// multifiling service
void AddToFolder(IObjectId folderId, bool allVersions);
@@ -312,11 +317,11 @@
bool? IsLatestMajorVersion { get; }
string VersionLabel { get; }
string VersionSeriesId { get; }
- bool? VersionSeriesCheckedOut { get; }
+ bool? IsVersionSeriesCheckedOut { get; }
string VersionSeriesCheckedOutBy { get; }
string VersionSeriesCheckedOutId { get; }
string CheckinComment { get; }
- long ContentStreamLength { get; }
+ long? ContentStreamLength { get; }
string ContentStreamMimeType { get; }
string ContentStreamFileName { get; }
string ContentStreamId { get; }
@@ -335,7 +340,7 @@
void CancelCheckOut();
IObjectId CheckIn(bool major, IDictionary<string, object> properties, IContentStream contentStream, string checkinComment,
IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces);
- IObjectId checkIn(bool major, IDictionary<string, object> properties, IContentStream contentStream, string checkinComment);
+ IObjectId CheckIn(bool major, IDictionary<string, object> properties, IContentStream contentStream, string checkinComment);
IDocument GetObjectOfLatestVersion(bool major);
IDocument GetObjectOfLatestVersion(bool major, IOperationContext context);
IList<IDocument> GetAllVersions();
@@ -361,7 +366,7 @@
IFolder CreateFolder(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
IOperationContext context);
IFolder CreateFolder(IDictionary<string, object> properties);
- IPolicy CreatePolicy(IDictionary<string, object> properties, List<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
+ IPolicy CreatePolicy(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces,
IOperationContext context);
IPolicy CreatePolicy(IDictionary<string, object> properties);
IList<string> DeleteTree(bool allversions, UnfileObject? unfile, bool continueOnFailure);
diff --git a/DotCMIS/client/client-objectfactory.cs b/DotCMIS/client/client-objectfactory.cs
index 43d6d63..1de2d67 100644
--- a/DotCMIS/client/client-objectfactory.cs
+++ b/DotCMIS/client/client-objectfactory.cs
@@ -24,6 +24,7 @@
using System.IO;
using DotCMIS.Enums;
using DotCMIS.Exceptions;
+using System.Collections;
namespace DotCMIS.Client
{
@@ -37,55 +38,469 @@
}
// ACL and ACE
- public IAcl ConvertAces(IList<IAce> aces) { return null; }
- public IAcl CreateAcl(IList<IAce> aces) { return null; }
- public IAce CreateAce(string principal, List<string> permissions) { return null; }
+ public IAcl ConvertAces(IList<IAce> aces)
+ {
+ if (aces == null) { return null; }
+
+ Acl result = new Acl();
+ result.Aces = new List<IAce>();
+
+ foreach (IAce ace in aces)
+ {
+ result.Aces.Add(ace);
+ }
+
+ return result;
+ }
+
+ public IAcl CreateAcl(IList<IAce> aces)
+ {
+ Acl acl = new Acl();
+ acl.Aces = aces;
+
+ return acl;
+ }
+
+ public IAce CreateAce(string principal, IList<string> permissions)
+ {
+ Ace ace = new Ace();
+ Principal acePrincipal = new Principal();
+ acePrincipal.Id = principal;
+ ace.Principal = acePrincipal;
+ ace.Permissions = permissions;
+
+ return ace;
+ }
// policies
- public IList<string> ConvertPolicies(IList<IPolicy> policies) { return null; }
+ public IList<string> ConvertPolicies(IList<IPolicy> policies)
+ {
+ if (policies == null) { return null; }
+
+ IList<string> result = new List<string>();
+ foreach (IPolicy policy in policies)
+ {
+ if (policy != null && policy.Id != null)
+ {
+ result.Add(policy.Id);
+ }
+ }
+
+ return result;
+ }
// renditions
- public IRendition ConvertRendition(string objectId, IRenditionData rendition) { return null; }
+ public IRendition ConvertRendition(string objectId, IRenditionData rendition)
+ {
+ if (rendition == null)
+ {
+ throw new ArgumentException("rendition");
+ }
+
+ return new Rendition(this.session, objectId, rendition.StreamId, rendition.MimeType, rendition.Length, rendition.Kind,
+ rendition.Title, rendition.Height, rendition.Height, rendition.RenditionDocumentId);
+ }
// content stream
- public IContentStream CreateContentStream(string filename, long length, string mimetype, Stream stream) { return null; }
- public IContentStream ConvertContentStream(IContentStream contentStream) { return null; }
+ public IContentStream CreateContentStream(string filename, long length, string mimetype, Stream stream)
+ {
+ ContentStream result = new ContentStream();
+ result.FileName = filename;
+ result.Length = length;
+ result.MimeType = mimetype;
+ result.Stream = stream;
+
+ return result;
+ }
// types
public IObjectType ConvertTypeDefinition(ITypeDefinition typeDefinition)
{
- if (typeDefinition is IDocumentTypeDefinition)
+ switch (typeDefinition.BaseTypeId)
{
- return new DocumentType(session, (IDocumentTypeDefinition)typeDefinition);
- }
- else if (typeDefinition is IFolderTypeDefinition)
- {
- return new FolderType(session, (IFolderTypeDefinition)typeDefinition);
- }
- else if (typeDefinition is IRelationshipTypeDefinition)
- {
- return new RelationshipType(session, (IRelationshipTypeDefinition)typeDefinition);
- }
- else if (typeDefinition is IPolicyTypeDefinition)
- {
- return new PolicyType(session, (IPolicyTypeDefinition)typeDefinition);
- }
- else
- {
- throw new CmisRuntimeException("Unknown base type!");
+ case BaseTypeId.CmisDocument:
+ return new DocumentType(session, (IDocumentTypeDefinition)typeDefinition);
+ case BaseTypeId.CmisFolder:
+ return new FolderType(session, (IFolderTypeDefinition)typeDefinition);
+ case BaseTypeId.CmisRelationship:
+ return new RelationshipType(session, (IRelationshipTypeDefinition)typeDefinition);
+ case BaseTypeId.CmisPolicy:
+ return new PolicyType(session, (IPolicyTypeDefinition)typeDefinition);
+ default:
+ throw new CmisRuntimeException("Unknown base type!");
}
}
- public IObjectType GetTypeFromObjectData(IObjectData objectData) { return null; }
+ public IObjectType GetTypeFromObjectData(IObjectData objectData)
+ {
+ if (objectData == null || objectData.Properties == null)
+ {
+ return null;
+ }
+
+ IPropertyId typeProperty = objectData.Properties[PropertyIds.ObjectTypeId] as IPropertyId;
+ if (typeProperty == null)
+ {
+ return null;
+ }
+
+ return session.GetTypeDefinition(typeProperty.FirstValue);
+ }
// properties
- public IProperty CreateProperty(IPropertyDefinition type, IList<object> values) { return null; }
- public IDictionary<string, IProperty> ConvertProperties(IObjectType objectType, IProperties properties) { return null; }
- public IProperties ConvertProperties(IDictionary<string, object> properties, IObjectType type, HashSet<Updatability> updatabilityFilter) { return null; }
- public IList<IPropertyData> ConvertQueryProperties(IProperties properties) { return null; }
+ public IProperty CreateProperty<T>(IPropertyDefinition type, IList<T> values)
+ {
+ return new Property(type, (IList<object>)values);
+ }
+
+ protected IProperty ConvertProperty(IObjectType objectType, IPropertyData pd)
+ {
+ IPropertyDefinition definition = objectType[pd.Id];
+ if (definition == null)
+ {
+ // property without definition
+ throw new CmisRuntimeException("Property '" + pd.Id + "' doesn't exist!");
+ }
+
+ switch (definition.PropertyType)
+ {
+ case PropertyType.String:
+ return CreateProperty(definition, ((IPropertyString)pd).Values);
+ case PropertyType.Id:
+ return CreateProperty(definition, ((IPropertyId)pd).Values);
+ case PropertyType.Integer:
+ return CreateProperty(definition, ((IPropertyInteger)pd).Values);
+ case PropertyType.Boolean:
+ return CreateProperty(definition, ((IPropertyBoolean)pd).Values);
+ case PropertyType.Decimal:
+ return CreateProperty(definition, ((IPropertyDecimal)pd).Values);
+ case PropertyType.Uri:
+ return CreateProperty(definition, ((IPropertyUri)pd).Values);
+ case PropertyType.Html:
+ return CreateProperty(definition, ((IPropertyHtml)pd).Values);
+ default:
+ return null;
+ }
+ }
+
+ public IDictionary<string, IProperty> ConvertProperties(IObjectType objectType, IProperties properties)
+ {
+ if (objectType == null)
+ {
+ throw new ArgumentNullException("objectType");
+ }
+
+ if (objectType.PropertyDefintions == null)
+ {
+ throw new ArgumentException("Object type has no property defintions!");
+ }
+
+ if (properties == null || properties.PropertyList == null)
+ {
+ throw new ArgumentException("Properties must be set!");
+ }
+
+ // iterate through properties and convert them
+ IDictionary<string, IProperty> result = new Dictionary<string, IProperty>();
+ foreach (IPropertyData property in properties.PropertyList)
+ {
+ // find property definition
+ IProperty apiProperty = ConvertProperty(objectType, property);
+ result[property.Id] = apiProperty;
+ }
+
+ return result;
+ }
+
+ public IProperties ConvertProperties(IDictionary<string, object> properties, IObjectType type, HashSet<Updatability> updatabilityFilter)
+ {
+ // check input
+ if (properties == null)
+ {
+ return null;
+ }
+
+ // get the type
+ if (type == null)
+ {
+ string typeId = properties[PropertyIds.ObjectTypeId] as string;
+ if (typeId == null)
+ {
+ throw new ArgumentException("Type or type property must be set!");
+ }
+
+ type = session.GetTypeDefinition(typeId);
+ }
+
+ Properties result = new Properties();
+
+ // the big loop
+ foreach (KeyValuePair<string, object> property in properties)
+ {
+ string id = property.Key;
+ object value = property.Value;
+
+ if (value is IProperty)
+ {
+ IProperty p = (IProperty)value;
+ if (id != p.Id)
+ {
+ throw new ArgumentException("Property id mismatch: '" + id + "' != '" + p.Id + "'!");
+ }
+ value = (p.PropertyDefinition.Cardinality == Cardinality.Single ? p.FirstValue : p.Values);
+ }
+
+ // get the property definition
+ IPropertyDefinition definition = type[id];
+ if (definition == null)
+ {
+ throw new ArgumentException("Property +'" + id + "' is not valid for this type!");
+ }
+
+ // check updatability
+ if (updatabilityFilter != null)
+ {
+ if (!updatabilityFilter.Contains(definition.Updatability))
+ {
+ continue;
+ }
+ }
+
+ // single and multi value check
+ IList<dynamic> values;
+ if (value == null)
+ {
+ values = null;
+ }
+ else if (value is IList<dynamic>)
+ {
+ if (definition.Cardinality != Cardinality.Multi)
+ {
+ throw new ArgumentException("Property '" + id + "' is not a multi value property!");
+ }
+ values = (IList<dynamic>)value;
+
+ // check if the list is homogeneous and does not contain null values
+ Type valueType = null;
+ foreach (object o in values)
+ {
+ if (o == null)
+ {
+ throw new ArgumentException("Property '" + id + "' contains null values!");
+ }
+ if (valueType == null)
+ {
+ valueType = o.GetType();
+ }
+ else
+ {
+ if (!valueType.IsInstanceOfType(o))
+ {
+ throw new ArgumentException("Property '" + id + "' is inhomogeneous!");
+ }
+ }
+ }
+ }
+ else
+ {
+ if (definition.Cardinality != Cardinality.Single)
+ {
+ throw new ArgumentException("Property '" + id + "' is not a single value property!");
+ }
+ values = new List<dynamic>();
+ values.Add(value);
+ }
+
+ // assemble property
+ object firstValue = (values == null || values.Count == 0 ? null : values[0]);
+
+ switch (definition.PropertyType)
+ {
+ case PropertyType.String:
+ PropertyString stringProperty = new PropertyString();
+ stringProperty.Id = id;
+ stringProperty.Values = new List<string>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is string))
+ {
+ throw new ArgumentException("Property '" + id + "' is a String property!");
+ }
+
+ foreach (object o in values)
+ {
+ stringProperty.Values.Add((string)o);
+ }
+ }
+ result.AddProperty(stringProperty);
+ break;
+ case PropertyType.Id:
+ PropertyId idProperty = new PropertyId();
+ idProperty.Id = id;
+ idProperty.Values = new List<string>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is string))
+ {
+ throw new ArgumentException("Property '" + id + "' is a Id property!");
+ }
+
+ foreach (object o in values)
+ {
+ idProperty.Values.Add((string)o);
+ }
+ }
+ result.AddProperty(idProperty);
+ break;
+ case PropertyType.Integer:
+ PropertyInteger intProperty = new PropertyInteger();
+ intProperty.Id = id;
+ intProperty.Values = new List<long>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is sbyte || firstValue is byte || firstValue is short || firstValue is ushort || firstValue is int || firstValue is uint || firstValue is long))
+ {
+ throw new ArgumentException("Property '" + id + "' is an Integer property!");
+ }
+
+ foreach (object o in values)
+ {
+ intProperty.Values.Add((long)o);
+ }
+ }
+ result.AddProperty(intProperty);
+ break;
+ case PropertyType.Boolean:
+ PropertyBoolean booleanProperty = new PropertyBoolean();
+ booleanProperty.Id = id;
+ booleanProperty.Values = new List<bool>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is bool))
+ {
+ throw new ArgumentException("Property '" + id + "' is a boolean property!");
+ }
+
+ foreach (object o in values)
+ {
+ booleanProperty.Values.Add((bool)o);
+ }
+ }
+ result.AddProperty(booleanProperty);
+ break;
+ case PropertyType.DateTime:
+ PropertyDateTime dateTimeProperty = new PropertyDateTime();
+ dateTimeProperty.Id = id;
+ dateTimeProperty.Values = new List<DateTime>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is DateTime))
+ {
+ throw new ArgumentException("Property '" + id + "' is a Boolean property!");
+ }
+
+ foreach (object o in values)
+ {
+ dateTimeProperty.Values.Add((DateTime)o);
+ }
+ }
+ result.AddProperty(dateTimeProperty);
+ break;
+ case PropertyType.Decimal:
+ PropertyDecimal decimalProperty = new PropertyDecimal();
+ decimalProperty.Id = id;
+ decimalProperty.Values = new List<decimal>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is DateTime))
+ {
+ throw new ArgumentException("Property '" + id + "' is a Decimal property!");
+ }
+
+ foreach (object o in values)
+ {
+ decimalProperty.Values.Add((decimal)o);
+ }
+ }
+ result.AddProperty(decimalProperty);
+ break;
+ case PropertyType.Uri:
+ PropertyUri uriProperty = new PropertyUri();
+ uriProperty.Id = id;
+ uriProperty.Values = new List<string>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is string))
+ {
+ throw new ArgumentException("Property '" + id + "' is a URI property!");
+ }
+
+ foreach (object o in values)
+ {
+ uriProperty.Values.Add((string)o);
+ }
+ }
+ result.AddProperty(uriProperty);
+ break;
+ case PropertyType.Html:
+ PropertyHtml htmlProperty = new PropertyHtml();
+ htmlProperty.Id = id;
+ htmlProperty.Values = new List<string>(values.Count);
+ if (values != null)
+ {
+ if (firstValue != null && !(firstValue is string))
+ {
+ throw new ArgumentException("Property '" + id + "' is a HTML property!");
+ }
+
+ foreach (object o in values)
+ {
+ htmlProperty.Values.Add((string)o);
+ }
+ }
+ result.AddProperty(htmlProperty);
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ public IList<IPropertyData> ConvertQueryProperties(IProperties properties)
+ {
+ if ((properties == null) || (properties.PropertyList == null))
+ {
+ throw new ArgumentException("Properties must be set!");
+ }
+
+ return new List<IPropertyData>(properties.PropertyList);
+ }
// objects
- public ICmisObject ConvertObject(IObjectData objectData, IOperationContext context) { return null; }
+ public ICmisObject ConvertObject(IObjectData objectData, IOperationContext context)
+ {
+ if (objectData == null)
+ {
+ throw new ArgumentNullException("objectData");
+ }
+
+ IObjectType type = GetTypeFromObjectData(objectData);
+
+ switch (objectData.BaseTypeId)
+ {
+ case BaseTypeId.CmisDocument:
+ return new Document(session, type, objectData, context);
+ case BaseTypeId.CmisFolder:
+ return new Folder(session, type, objectData, context);
+ case BaseTypeId.CmisPolicy:
+ return new Policy(session, type, objectData, context);
+ case BaseTypeId.CmisRelationship:
+ return new Relationship(session, type, objectData, context);
+ default:
+ throw new CmisRuntimeException("Unsupported type: " + objectData.BaseTypeId);
+ }
+ }
+
public IQueryResult ConvertQueryResult(IObjectData objectData) { return null; }
public IChangeEvent ConvertChangeEvent(IObjectData objectData) { return null; }
public IChangeEvents ConvertChangeEvents(String changeLogToken, IObjectList objectList) { return null; }
diff --git a/DotCMIS/client/client-objects.cs b/DotCMIS/client/client-objects.cs
index c77d8bb..cc75cc9 100644
--- a/DotCMIS/client/client-objects.cs
+++ b/DotCMIS/client/client-objects.cs
@@ -27,10 +27,14 @@
using DotCMIS.Data.Extensions;
using DotCMIS.Enums;
using DotCMIS.Exceptions;
+using DotCMIS.Binding.Services;
namespace DotCMIS.Client
{
- internal abstract class AbstractCmisObject : ICmisObject
+ /// <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; } }
@@ -80,7 +84,7 @@
private object objectLock = new object();
- protected void initialize(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
+ protected void Initialize(ISession session, IObjectType objectType, IObjectData objectData, IOperationContext context)
{
if (session == null)
{
@@ -104,7 +108,6 @@
this.CreationContext = new OperationContext(context);
this.RefreshTimestamp = DateTime.UtcNow;
-
IObjectFactory of = Session.ObjectFactory;
if (objectData != null)
@@ -146,10 +149,10 @@
policies = new List<IPolicy>();
foreach (string pid in objectData.PolicyIds.PolicyIds)
{
- ICmisObject policy = Session.GetObject(Session.CreateObjectId(pid));
- if (policy is IPolicy)
+ IPolicy policy = Session.GetObject(Session.CreateObjectId(pid)) as IPolicy;
+ if (policy != null)
{
- policies.Add((IPolicy)policy);
+ policies.Add(policy);
}
}
extensions[ExtensionLevel.Policies] = objectData.PolicyIds.Extensions;
@@ -161,10 +164,10 @@
relationships = new List<IRelationship>();
foreach (IObjectData rod in objectData.Relationships)
{
- ICmisObject relationship = of.ConvertObject(rod, CreationContext);
- if (relationship is IRelationship)
+ IRelationship relationship = of.ConvertObject(rod, CreationContext) as IRelationship;
+ if (relationship != null)
{
- relationships.Add((IRelationship)relationship);
+ relationships.Add(relationship);
}
}
}
@@ -274,7 +277,7 @@
// --- properties ---
- public IObjectType BaseType { get { return Session.GetTypeDefinition(BaseTypeId.GetCmisValue()); } }
+ public IObjectType BaseType { get { return Session.GetTypeDefinition(GetPropertyValue(PropertyIds.BaseTypeId) as string); } }
public BaseTypeId BaseTypeId
{
@@ -521,7 +524,7 @@
oc.IncludeRelationships, oc.RenditionFilterString, oc.IncludePolicies, oc.IncludeAcls, null);
// reset this object
- initialize(Session, ObjectType, objectData, CreationContext);
+ Initialize(Session, ObjectType, objectData, CreationContext);
}
finally
{
@@ -555,4 +558,1106 @@
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> providerParents = Binding.GetNavigationService().GetObjectParents(
+ RepositoryId, ObjectId, GetPropertyQueryName(PropertyIds.ObjectId), false,
+ IncludeRelationshipsFlag.None, null, false, null);
+
+ IList<IFolder> parents = new List<IFolder>();
+
+ foreach (IObjectParentData p in providerParents)
+ {
+ if (p == null || p.Object == null || p.Object.Properties == null)
+ {
+ // should not happen...
+ throw new CmisRuntimeException("Repository sent invalid data!");
+ }
+
+ // get id property
+ IPropertyId idProperty = p.Object.Properties[PropertyIds.ObjectId] as IPropertyId;
+ if (idProperty == null)
+ {
+ // 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);
+ 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
+ IPropertyString pathProperty = p.Object.Properties[PropertyIds.Path] as IPropertyString;
+ if (pathProperty == null)
+ {
+ // 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;
+ 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
+ {
+ private static HashSet<Updatability> CreateUpdatability = new HashSet<Updatability>();
+ static Folder()
+ {
+ CreateUpdatability.Add(Updatability.OnCreate);
+ CreateUpdatability.Add(Updatability.ReadWrite);
+ }
+
+ 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)
+ {
+ PropertyString pathProperty = objectData.Properties[PropertyIds.Path] as PropertyString;
+ if (pathProperty != null)
+ {
+ path = pathProperty.FirstValue;
+ }
+ }
+ }
+ }
+ 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.Count == 0 ? null : Values[0];
+ }
+ else
+ {
+ return Values;
+ }
+ }
+ }
+
+ public IList<object> Values { get; protected set; }
+
+ public object FirstValue { get { return 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/DotCMIS/client/client-types.cs b/DotCMIS/client/client-types.cs
index 3b4a93a..e6b333f 100644
--- a/DotCMIS/client/client-types.cs
+++ b/DotCMIS/client/client-types.cs
@@ -43,7 +43,7 @@
public ISession Session { get { return session; } }
- public bool IsBaseType { get { return objectType.ParentTypeId == null; } }
+ public bool IsBaseType { get { return objectType.ParentTypeId == null || objectType.ParentTypeId.Length == 0; } }
public IObjectType GetBaseType()
{
diff --git a/DotCMIS/const.cs b/DotCMIS/const.cs
index 4d81286..83424be 100644
--- a/DotCMIS/const.cs
+++ b/DotCMIS/const.cs
@@ -91,7 +91,7 @@
public const string IsImmutable = "cmis:isImmutable";
public const string IsLatestVersion = "cmis:isLatestVersion";
public const string IsMajorVersion = "cmis:isMajorVersion";
- public const string isLatestMajorVersion = "cmis:isLatestMajorVersion";
+ public const string IsLatestMajorVersion = "cmis:isLatestMajorVersion";
public const string VersionLabel = "cmis:versionLabel";
public const string VersionSeriesId = "cmis:versionSeriesId";
public const string IsVersionSeriesCheckedOut = "cmis:isVersionSeriesCheckedOut";
diff --git a/DotCMIS/data/data-impl.cs b/DotCMIS/data/data-impl.cs
index 6aaa1ab..78d09eb 100644
--- a/DotCMIS/data/data-impl.cs
+++ b/DotCMIS/data/data-impl.cs
@@ -225,9 +225,9 @@
public string DisplayName { get; set; }
public string QueryName { get; set; }
public string Description { get; set; }
- public PropertyType? PropertyType { get; set; }
- public Cardinality? Cardinality { get; set; }
- public Updatability? Updatability { get; set; }
+ public PropertyType PropertyType { get; set; }
+ public Cardinality Cardinality { get; set; }
+ public Updatability Updatability { get; set; }
public bool? IsInherited { get; set; }
public bool? IsRequired { get; set; }
public bool? IsQueryable { get; set; }
@@ -427,7 +427,7 @@
}
}
- public abstract class PropertyData : ExtensionsData, IPropertyData
+ public abstract class AbstractPropertyData : ExtensionsData, IPropertyData
{
public string Id { get; set; }
public string LocalName { get; set; }
@@ -438,37 +438,37 @@
{
get
{
- if (this is PropertyBoolean)
+ if (this is IPropertyString)
{
- return ((PropertyBoolean)this).FirstValue;
+ return ((IPropertyString)this).FirstValue;
}
- else if (this is PropertyDateTime)
+ else if (this is IPropertyInteger)
{
- return ((PropertyDateTime)this).FirstValue;
+ return ((IPropertyInteger)this).FirstValue;
}
- else if (this is PropertyDecimal)
+ else if (this is IPropertyId)
{
- return ((PropertyDecimal)this).FirstValue;
+ return ((IPropertyId)this).FirstValue;
}
- else if (this is PropertyHtml)
+ else if (this is IPropertyBoolean)
{
- return ((PropertyHtml)this).FirstValue;
+ return ((IPropertyBoolean)this).FirstValue;
}
- else if (this is PropertyId)
+ else if (this is IPropertyDateTime)
{
- return ((PropertyId)this).FirstValue;
+ return ((IPropertyDateTime)this).FirstValue;
}
- else if (this is PropertyInteger)
+ else if (this is IPropertyDecimal)
{
- return ((PropertyInteger)this).FirstValue;
+ return ((IPropertyDecimal)this).FirstValue;
}
- else if (this is PropertyString)
+ else if (this is IPropertyHtml)
{
- return ((PropertyString)this).FirstValue;
+ return ((IPropertyHtml)this).FirstValue;
}
- else if (this is PropertyUri)
+ else if (this is IPropertyUri)
{
- return ((PropertyUri)this).FirstValue;
+ return ((IPropertyUri)this).FirstValue;
}
return null;
@@ -481,49 +481,49 @@
}
}
- public class PropertyBoolean : PropertyData, IPropertyBoolean
+ public class PropertyBoolean : AbstractPropertyData, IPropertyBoolean
{
public IList<bool> Values { get; set; }
public bool? FirstValue { get { return Values == null || Values.Count < 1 ? null : (bool?)Values[0]; } }
}
- public class PropertyDateTime : PropertyData, IPropertyDateTime
+ public class PropertyDateTime : AbstractPropertyData, IPropertyDateTime
{
public IList<DateTime> Values { get; set; }
public DateTime? FirstValue { get { return Values == null || Values.Count < 1 ? null : (DateTime?)Values[0]; } }
}
- public class PropertyDecimal : PropertyData, IPropertyDecimal
+ public class PropertyDecimal : AbstractPropertyData, IPropertyDecimal
{
public IList<decimal> Values { get; set; }
public decimal? FirstValue { get { return Values == null || Values.Count < 1 ? null : (decimal?)Values[0]; } }
}
- public class PropertyHtml : PropertyData, IPropertyHtml
+ public class PropertyHtml : AbstractPropertyData, IPropertyHtml
{
public IList<string> Values { get; set; }
public string FirstValue { get { return Values == null || Values.Count < 1 ? null : Values[0]; } }
}
- public class PropertyId : PropertyData, IPropertyId
+ public class PropertyId : AbstractPropertyData, IPropertyId
{
public IList<string> Values { get; set; }
public string FirstValue { get { return Values == null || Values.Count < 1 ? null : Values[0]; } }
}
- public class PropertyInteger : PropertyData, IPropertyInteger
+ public class PropertyInteger : AbstractPropertyData, IPropertyInteger
{
public IList<long> Values { get; set; }
public long? FirstValue { get { return Values == null || Values.Count < 1 ? null : (long?)Values[0]; } }
}
- public class PropertyString : PropertyData, IPropertyString
+ public class PropertyString : AbstractPropertyData, IPropertyString
{
public IList<string> Values { get; set; }
public string FirstValue { get { return Values == null || Values.Count < 1 ? null : Values[0]; } }
}
- public class PropertyUri : PropertyData, IPropertyUri
+ public class PropertyUri : AbstractPropertyData, IPropertyUri
{
public IList<string> Values { get; set; }
public string FirstValue { get { return Values == null || Values.Count < 1 ? null : Values[0]; } }
diff --git a/DotCMIS/data/data-intf.cs b/DotCMIS/data/data-intf.cs
index d243b9e..6260b7e 100644
--- a/DotCMIS/data/data-intf.cs
+++ b/DotCMIS/data/data-intf.cs
@@ -145,9 +145,9 @@
string DisplayName { get; }
string QueryName { get; }
string Description { get; }
- PropertyType? PropertyType { get; }
- Cardinality? Cardinality { get; }
- Updatability? Updatability { get; }
+ PropertyType PropertyType { get; }
+ Cardinality Cardinality { get; }
+ Updatability Updatability { get; }
bool? IsInherited { get; }
bool? IsRequired { get; }
bool? IsQueryable { get; }
diff --git a/DotCMISUnitTest/TestFramework.cs b/DotCMISUnitTest/TestFramework.cs
index 9246e9d..57883ee 100644
--- a/DotCMISUnitTest/TestFramework.cs
+++ b/DotCMISUnitTest/TestFramework.cs
@@ -334,6 +334,8 @@
Assert.NotNull(expected);
Assert.NotNull(actual);
+ Assert.NotNull(actual.Id);
+
Assert.AreEqual(expected.Id, actual.Id);
Assert.AreEqual(expected.IsBaseType, actual.IsBaseType);
Assert.AreEqual(expected.BaseTypeId, actual.BaseTypeId);
@@ -343,6 +345,39 @@
Assert.AreEqual(expected.LocalNamespace, actual.LocalNamespace);
Assert.AreEqual(expected.QueryName, actual.QueryName);
Assert.AreEqual(expected.PropertyDefintions.Count, actual.PropertyDefintions.Count);
+
+ foreach (IPropertyDefinition propDef in expected.PropertyDefintions)
+ {
+ Assert.NotNull(propDef);
+ Assert.NotNull(propDef.Id);
+
+ IPropertyDefinition propDef2 = actual[propDef.Id];
+
+ AssertAreEqual(propDef, propDef2);
+ }
+ }
+
+ public void AssertAreEqual(IPropertyDefinition expected, IPropertyDefinition actual)
+ {
+ if (expected == null && actual == null)
+ {
+ return;
+ }
+
+ Assert.NotNull(expected);
+ Assert.NotNull(actual);
+
+ Assert.NotNull(actual.Id);
+
+ Assert.AreEqual(expected.Id, actual.Id);
+ Assert.AreEqual(expected.LocalName, actual.LocalName);
+ Assert.AreEqual(expected.LocalNamespace, actual.LocalNamespace);
+ Assert.AreEqual(expected.DisplayName, actual.DisplayName);
+ Assert.AreEqual(expected.Description, actual.Description);
+ Assert.AreEqual(expected.QueryName, actual.QueryName);
+ Assert.AreEqual(expected.PropertyType, actual.PropertyType);
+ Assert.AreEqual(expected.Cardinality, actual.Cardinality);
+ Assert.AreEqual(expected.Updatability, actual.Updatability);
}
}
}