You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2011/01/26 18:19:25 UTC

svn commit: r1063802 - in /incubator/chemistry/dotcmis/trunk/DotCMIS: DotCMIS.csproj binding/binding-intf.cs client/client-impl.cs client/client-intf.cs client/client-objects.cs

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);
+        }
+    }
+}