Author: fmui Date: Wed Jan 26 17:19:24 2011 New Revision: 1063802 URL: http://svn.apache.org/viewvc?rev=1063802&view=rev Log: - more client layer code
Added: incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-objects.cs Modified: incubator/chemistry/dotcmis/trunk/DotCMIS/DotCMIS.csproj incubator/chemistry/dotcmis/trunk/DotCMIS/binding/binding-intf.cs incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-impl.cs incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-intf.cs Modified: incubator/chemistry/dotcmis/trunk/DotCMIS/DotCMIS.csproj URL: http://svn.apache.org/viewvc/incubator/chemistry/dotcmis/trunk/DotCMIS/DotCMIS.csproj?rev=1063802&r1=1063801&r2=1063802&view=diff ============================================================================== --- incubator/chemistry/dotcmis/trunk/DotCMIS/DotCMIS.csproj (original) +++ incubator/chemistry/dotcmis/trunk/DotCMIS/DotCMIS.csproj Wed Jan 26 17:19:24 2011 @@ -56,6 +56,7 @@ <Compile Include="client\client-caches.cs" /> <Compile Include="client\client-intf.cs" /> <Compile Include="client\client-impl.cs" /> + <Compile Include="client\client-objects.cs" /> <Compile Include="const.cs" /> <Compile Include="data\data-impl.cs" /> <Compile Include="data\data-intf.cs" /> Modified: incubator/chemistry/dotcmis/trunk/DotCMIS/binding/binding-intf.cs URL: http://svn.apache.org/viewvc/incubator/chemistry/dotcmis/trunk/DotCMIS/binding/binding-intf.cs?rev=1063802&r1=1063801&r2=1063802&view=diff ============================================================================== --- incubator/chemistry/dotcmis/trunk/DotCMIS/binding/binding-intf.cs (original) +++ incubator/chemistry/dotcmis/trunk/DotCMIS/binding/binding-intf.cs Wed Jan 26 17:19:24 2011 @@ -30,38 +30,24 @@ namespace DotCMIS.Binding public interface ICmisBinding { IRepositoryService GetRepositoryService(); - INavigationService GetNavigationService(); - IObjectService GetObjectService(); - IVersioningService GetVersioningService(); - IRelationshipService GetRelationshipService(); - IDiscoveryService GetDiscoveryService(); - IMultiFilingService GetMultiFilingService(); - IAclService GetAclService(); - IPolicyService GetPolicyService(); - IBindingsObjectFactory GetObjectFactory(); - void ClearAllCaches(); - void ClearRepositoryCache(string repositoryId); - void Close(); } public interface IBindingSession { object GetValue(string key); - object GetValue(string key, object defValue); - int GetValue(string key, int defValue); } Modified: incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-impl.cs URL: http://svn.apache.org/viewvc/incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-impl.cs?rev=1063802&r1=1063801&r2=1063802&view=diff ============================================================================== --- incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-impl.cs (original) +++ incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-impl.cs Wed Jan 26 17:19:24 2011 @@ -25,6 +25,7 @@ using DotCMIS.Data; using DotCMIS.Exceptions; using System.Threading; using DotCMIS.Enums; +using DotCMIS.Data.Extensions; namespace DotCMIS.Client { @@ -463,6 +464,22 @@ namespace DotCMIS.Client GenerateCacheKey(); } + public OperationContext(IOperationContext source) + { + filter = new HashSet<string>(source.Filter); + includeAcls = source.IncludeAcls; + includeAllowableActions = source.IncludeAllowableActions; + includePolicies = source.IncludePolicies; + includeRelationships = source.IncludeRelationships; + renditionFilter = new HashSet<string>(source.RenditionFilter); + includePathSegments = source.IncludePathSegments; + orderBy = source.OrderBy; + cacheEnabled = source.CacheEnabled; + maxItemsPerPage = source.MaxItemsPerPage; + + GenerateCacheKey(); + } + public OperationContext(HashSet<string> filter, bool includeAcls, bool includeAllowableActions, bool includePolicies, IncludeRelationshipsFlag includeRelationships, HashSet<string> renditionFilter, bool includePathSegments, String orderBy, bool cacheEnabled, int maxItemsPerPage) Modified: incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-intf.cs URL: http://svn.apache.org/viewvc/incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-intf.cs?rev=1063802&r1=1063801&r2=1063802&view=diff ============================================================================== --- incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-intf.cs (original) +++ incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-intf.cs Wed Jan 26 17:19:24 2011 @@ -18,12 +18,11 @@ */ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; +using DotCMIS.Binding; using DotCMIS.Data; -using DotCMIS.Enums; using DotCMIS.Data.Extensions; -using DotCMIS.Binding; +using DotCMIS.Enums; +using System.IO; namespace DotCMIS.Client { @@ -49,7 +48,7 @@ namespace DotCMIS.Client IOperationContext DefaultContext { get; set; } IOperationContext CreateOperationContext(); IOperationContext CreateOperationContext(HashSet<string> filter, bool includeAcls, bool includeAllowableActions, bool includePolicies, - IncludeRelationshipsFlag includeRelationships, HashSet<string> renditionFilter, bool includePathSegments, string orderBy, + IncludeRelationshipsFlag includeRelationships, HashSet<string> renditionFilter, bool includePathSegments, string orderBy, bool cacheEnabled, int maxItemsPerPage); IObjectId CreateObjectId(string id); @@ -114,7 +113,41 @@ namespace DotCMIS.Client void RemovePolicy(IObjectId objectId, IObjectId policyIds); } - public interface IObjectFactory { } + public interface IObjectFactory + { + void Initialize(ISession session, IDictionary<string, string> parameters); + + // ACL and ACE + IAcl ConvertAces(IList<IAce> aces); + IAcl CreateAcl(IList<IAce> aces); + IAce CreateAce(string principal, List<string> permissions); + + // policies + IList<string> ConvertPolicies(IList<IPolicy> policies); + + // renditions + IRendition ConvertRendition(string objectId, IRenditionData rendition); + + // 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); + IDictionary<string, IProperty> ConvertProperties(IObjectType objectType, IProperties properties); + IProperties ConvertProperties(IDictionary<string, object> properties, IObjectType type, HashSet<Updatability> updatabilityFilter); + IList<IPropertyData> ConvertQueryProperties(IProperties properties); + + // objects + ICmisObject ConvertObject(IObjectData objectData, IOperationContext context); + IQueryResult ConvertQueryResult(IObjectData objectData); + IChangeEvent ConvertChangeEvent(IObjectData objectData); + IChangeEvents ConvertChangeEvents(String changeLogToken, IObjectList objectList); + } public interface IOperationContext { @@ -175,23 +208,23 @@ namespace DotCMIS.Client bool IsMultiValued { get; } PropertyType PropertyType { get; } PropertyDefinition PropertyDefinition { get; } - V GetValue<V>(); - string GetValueAsString(); - string GetValuesAsString(); + object Value { get; } + string ValueAsString { get; } + string ValuesAsString { get; } } public interface ICmisObjectProperties { IList<IProperty> Properties { get; } - IProperty GetProperty(string id); - T GetPropertyValue<T>(string id); + IProperty this[string propertyId] { get; } + object GetPropertyValue(string propertyId); // convenience accessors string Name { get; } string CreatedBy { get; } - DateTime CreationDate { get; } + DateTime? CreationDate { get; } string LastModifiedBy { get; } - DateTime LastModificationDate { get; } + DateTime? LastModificationDate { get; } BaseTypeId BaseTypeId { get; } IObjectType BaseType { get; } IObjectType Type { get; } @@ -207,9 +240,9 @@ namespace DotCMIS.Client public interface ICmisObject : IObjectId, ICmisObjectProperties { // object - IAllowableActions GetAllowableActions(); - IList<IRelationship> GetRelationships(); - IAcl GetAcl(); + IAllowableActions AllowableActions { get; } + IList<IRelationship> Relationships { get; } + IAcl Acl { get; } // object service void Delete(bool allVersions); @@ -217,22 +250,22 @@ namespace DotCMIS.Client IObjectId UpdateProperties(IDictionary<string, object> properties, bool refresh); // renditions - IList<IRendition> GetRenditions(); + IList<IRendition> Renditions { get; } // policy service void ApplyPolicy(IObjectId policyId); - void RemovePolicy(IObjectId policyIds); - IList<IPolicy> GetPolicies(); + void RemovePolicy(IObjectId policyId); + IList<IPolicy> Policies { get; } // ACL service - IAcl applyAcl(IList<IAce> AddAces, IList<IAce> removeAces, AclPropagation? aclPropagation); - IAcl addAcl(IList<IAce> AddAces, AclPropagation? aclPropagation); - IAcl removeAcl(IList<IAce> RemoveAces, AclPropagation? aclPropagation); + IAcl ApplyAcl(IList<IAce> AddAces, IList<IAce> removeAces, AclPropagation? aclPropagation); + IAcl AddAcl(IList<IAce> AddAces, AclPropagation? aclPropagation); + IAcl RemoveAcl(IList<IAce> RemoveAces, AclPropagation? aclPropagation); // extensions IList<ICmisExtensionElement> GetExtensions(ExtensionLevel level); - long GetRefreshTimestamp(); + DateTime RefreshTimestamp { get; } void Refresh(); void RefreshIfOld(long durationInMillis); } @@ -352,6 +385,10 @@ namespace DotCMIS.Client { } + public interface IChangeEvent + { + } + public interface IChangeEvents { } Added: incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-objects.cs URL: http://svn.apache.org/viewvc/incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-objects.cs?rev=1063802&view=auto ============================================================================== --- incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-objects.cs (added) +++ incubator/chemistry/dotcmis/trunk/DotCMIS/client/client-objects.cs Wed Jan 26 17:19:24 2011 @@ -0,0 +1,558 @@ +/* + * 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.Linq; +using System.Text; +using System.Threading; +using DotCMIS.Binding; +using DotCMIS.Client; +using DotCMIS.Data; +using DotCMIS.Data.Extensions; +using DotCMIS.Enums; +using DotCMIS.Exceptions; + +namespace DotCMIS.Client +{ + internal 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; + protected 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) + { + ICmisObject policy = Session.GetObject(Session.CreateObjectId(pid)); + if (policy is IPolicy) + { + policies.Add((IPolicy)policy); + } + } + extensions[ExtensionLevel.Policies] = objectData.PolicyIds.Extensions; + } + + // handle relationships + if (objectData.Relationships != null) + { + relationships = new List<IRelationship>(); + foreach (IObjectData rod in objectData.Relationships) + { + ICmisObject relationship = of.ConvertObject(rod, CreationContext); + if (relationship is IRelationship) + { + relationships.Add((IRelationship)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(BaseTypeId.GetCmisValue()); } } + + 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 IObjectType Type { get { return ObjectType; } } + + public IList<IProperty> Properties + { + get + { + Lock(); + try + { + return new List<IProperty>(properties.Values); + } + finally + { + Unlock(); + } + } + } + + public IProperty this[string propertyId] + { + get + { + 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(IObjectId policyId) + { + Lock(); + try + { + Session.ApplyPolicy(this, policyId); + } + finally + { + Unlock(); + } + + Refresh(); + } + + public void RemovePolicy(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); + } + } +}