/* * 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; using System.Collections.Generic; using System.Text; using DotCMIS.Enums; namespace DotCMIS.Client.Impl { /// /// Operation context implementation. /// public class OperationContext : IOperationContext { public const string PropertiesStar = "*"; public const string RenditionNone = "cmis:none"; private HashSet filter; private bool includeAllowableActions; private bool includeAcls; private IncludeRelationshipsFlag? includeRelationships; private bool includePolicies; private HashSet renditionFilter; private bool includePathSegments; private string orderBy; private bool cacheEnabled; private string cacheKey; private int maxItemsPerPage; public OperationContext() { filter = null; includeAcls = false; includeAllowableActions = true; includePolicies = false; includeRelationships = IncludeRelationshipsFlag.None; renditionFilter = null; includePathSegments = true; orderBy = null; cacheEnabled = false; maxItemsPerPage = 100; GenerateCacheKey(); } public OperationContext(IOperationContext source) { filter = (source.Filter == null ? null : new HashSet(source.Filter)); includeAcls = source.IncludeAcls; includeAllowableActions = source.IncludeAllowableActions; includePolicies = source.IncludePolicies; includeRelationships = source.IncludeRelationships; renditionFilter = (source.RenditionFilter == null ? null : new HashSet(source.RenditionFilter)); includePathSegments = source.IncludePathSegments; orderBy = source.OrderBy; cacheEnabled = source.CacheEnabled; maxItemsPerPage = source.MaxItemsPerPage; GenerateCacheKey(); } public OperationContext(HashSet filter, bool includeAcls, bool includeAllowableActions, bool includePolicies, IncludeRelationshipsFlag includeRelationships, HashSet renditionFilter, bool includePathSegments, String orderBy, bool cacheEnabled, int maxItemsPerPage) { this.filter = filter; this.includeAcls = includeAcls; this.includeAllowableActions = includeAllowableActions; this.includePolicies = includePolicies; this.includeRelationships = includeRelationships; this.renditionFilter = renditionFilter; this.includePathSegments = includePathSegments; this.orderBy = orderBy; this.cacheEnabled = cacheEnabled; this.maxItemsPerPage = maxItemsPerPage; GenerateCacheKey(); } public HashSet Filter { get { return filter == null ? null : new HashSet(filter); } set { if (value != null) { HashSet tempSet = new HashSet(); foreach (string oid in value) { if (oid == null) { continue; } string toid = oid.Trim(); if (toid.Length == 0) { continue; } if (toid == PropertiesStar) { tempSet = new HashSet(); tempSet.Add(PropertiesStar); break; } if (toid.IndexOf(',') > -1) { throw new ArgumentException("Query id must not contain a comma!"); } tempSet.Add(toid); } if (tempSet.Count == 0) { filter = null; } else { filter = tempSet; } } else { filter = null; } GenerateCacheKey(); } } public string FilterString { get { if (filter == null) { return null; } if (filter.Contains(PropertiesStar)) { return PropertiesStar; } this.filter.Add(PropertyIds.ObjectId); this.filter.Add(PropertyIds.BaseTypeId); this.filter.Add(PropertyIds.ObjectTypeId); StringBuilder sb = new StringBuilder(); foreach (String oid in filter) { if (sb.Length > 0) { sb.Append(','); } sb.Append(oid); } return sb.ToString(); } set { if (value == null || value.Trim().Length == 0) { Filter = null; return; } string[] ids = value.Split(','); HashSet tempSet = new HashSet(); foreach (string qid in ids) { tempSet.Add(qid); } Filter = tempSet; } } public bool IncludeAllowableActions { get { return includeAllowableActions; } set { includeAllowableActions = value; GenerateCacheKey(); } } public bool IncludeAcls { get { return includeAcls; } set { includeAcls = value; GenerateCacheKey(); } } public IncludeRelationshipsFlag? IncludeRelationships { get { return includeRelationships; } set { includeRelationships = value; GenerateCacheKey(); } } public bool IncludePolicies { get { return includePolicies; } set { includePolicies = value; GenerateCacheKey(); } } public HashSet RenditionFilter { get { return renditionFilter == null ? null : new HashSet(renditionFilter); } set { HashSet tempSet = new HashSet(); if (value != null) { foreach (String rf in value) { if (rf == null) { continue; } String trf = rf.Trim(); if (trf.Length == 0) { continue; } if (trf.IndexOf(',') > -1) { throw new ArgumentException("Rendition must not contain a comma!"); } tempSet.Add(trf); } if (tempSet.Count == 0) { tempSet.Add(RenditionNone); } } else { tempSet.Add(RenditionNone); } renditionFilter = tempSet; GenerateCacheKey(); } } public string RenditionFilterString { get { if (renditionFilter == null) { return null; } StringBuilder sb = new StringBuilder(); foreach (string rf in renditionFilter) { if (sb.Length > 0) { sb.Append(','); } sb.Append(rf); } return sb.ToString(); } set { if (value == null || value.Trim().Length == 0) { RenditionFilter = null; return; } string[] renditions = value.Split(','); HashSet tempSet = new HashSet(); foreach (string rend in renditions) { tempSet.Add(rend); } RenditionFilter = tempSet; } } public bool IncludePathSegments { get { return includePathSegments; } set { includePathSegments = value; GenerateCacheKey(); } } public string OrderBy { get { return orderBy; } set { orderBy = value; GenerateCacheKey(); } } public bool CacheEnabled { get { return cacheEnabled; } set { cacheEnabled = value; GenerateCacheKey(); } } public string CacheKey { get { return cacheKey; } } public int MaxItemsPerPage { get { return maxItemsPerPage; } set { maxItemsPerPage = value; } } protected void GenerateCacheKey() { if (!cacheEnabled) { cacheKey = null; } StringBuilder sb = new StringBuilder(); sb.Append(includeAcls ? "1" : "0"); sb.Append(includeAllowableActions ? "1" : "0"); sb.Append(includePolicies ? "1" : "0"); sb.Append("|"); sb.Append(filter == null ? "" : FilterString); sb.Append("|"); sb.Append(includeRelationships == null ? "" : includeRelationships.GetCmisValue()); sb.Append("|"); sb.Append(renditionFilter == null ? "" : RenditionFilterString); cacheKey = sb.ToString(); } } /// /// Object id implementation. /// public class ObjectId : IObjectId { private string id; public string Id { get { return id; } set { if (value == null || value.Length == 0) { throw new ArgumentException("Id must be set!"); } id = value; } } public ObjectId(string id) { Id = id; } } /// /// Tree implementation. /// public class Tree : ITree { public T Item { get; set; } public IList> Children { get; set; } } /// /// Base class for IItemEnumerable's. /// public abstract class AbstractEnumerable : IItemEnumerable { private AbstractEnumerator enumerator; protected AbstractEnumerator Enumerator { get { if (enumerator == null) { enumerator = CreateEnumerator(); } return enumerator; } } protected PageFetcher PageFetcher { get; set; } protected long SkipCount { get; private set; } public AbstractEnumerable(PageFetcher pageFetcher) : this(0, pageFetcher) { } protected AbstractEnumerable(long position, PageFetcher pageFetcher) { this.PageFetcher = pageFetcher; this.SkipCount = position; } protected abstract AbstractEnumerator CreateEnumerator(); IEnumerator IEnumerable.GetEnumerator() { return Enumerator; } IEnumerator IEnumerable.GetEnumerator() { return Enumerator; } public IItemEnumerable SkipTo(long position) { return new CollectionEnumerable(position, PageFetcher); } public IItemEnumerable GetPage() { return new CollectionPageEnumerable(SkipCount, PageFetcher); } public IItemEnumerable GetPage(int maxNumItems) { PageFetcher.MaxNumItems = maxNumItems; return new CollectionPageEnumerable(SkipCount, PageFetcher); } public long PageNumItems { get { return Enumerator.PageNumItems; } } public bool HasMoreItems { get { return Enumerator.HasMoreItems; } } public long TotalNumItems { get { return Enumerator.TotalNumItems; } } } /// /// Abstract Enumerator implementation. /// public abstract class AbstractEnumerator : IEnumerator { private PageFetcher pageFetcher; private PageFetcher.Page page = null; private long? totalNumItems = null; private bool? hasMoreItems = null; protected T Current; public AbstractEnumerator(long skipCount, PageFetcher pageFetcher) { this.SkipCount = skipCount; this.pageFetcher = pageFetcher; } T IEnumerator.Current { get { return Current; } } object IEnumerator.Current { get { return Current; } } public void Reset() { throw new NotSupportedException(); } public abstract bool MoveNext(); public void Dispose() { } public long SkipCount { get; protected set; } public int SkipOffset { get; protected set; } public long Position { get { return SkipCount + SkipOffset; } } public long PageNumItems { get { PageFetcher.Page page = GetCurrentPage(); if (page != null) { IList items = page.Items; if (items != null) { return items.Count; } } return 0; } } public long TotalNumItems { get { if (totalNumItems == null) { totalNumItems = -1; PageFetcher.Page page = GetCurrentPage(); if (page != null) { totalNumItems = page.TotalNumItems; } } return (long)totalNumItems; } } public bool HasMoreItems { get { if (hasMoreItems == null) { hasMoreItems = false; PageFetcher.Page page = GetCurrentPage(); if (page != null) { if (page.HasMoreItems.HasValue) { hasMoreItems = page.HasMoreItems; } } } return (bool)hasMoreItems; } } protected int IncrementSkipOffset() { return SkipOffset++; } protected PageFetcher.Page GetCurrentPage() { if (page == null) { page = pageFetcher.FetchNextPage(SkipCount); } return page; } protected PageFetcher.Page IncrementPage() { SkipCount += SkipOffset; SkipOffset = 0; totalNumItems = null; hasMoreItems = null; page = pageFetcher.FetchNextPage(SkipCount); return page; } } /// /// Page fetcher. /// public class PageFetcher { public delegate Page FetchPage(long maxNumItems, long skipCount); private FetchPage fetchPageDelegate; public PageFetcher(long maxNumItems, FetchPage fetchPageDelegate) { MaxNumItems = maxNumItems; this.fetchPageDelegate = fetchPageDelegate; } public long MaxNumItems { get; set; } public Page FetchNextPage(long skipCount) { return fetchPageDelegate(MaxNumItems, skipCount); } public class Page

{ public Page(IList

items, long? totalNumItems, bool? hasMoreItems) { Items = items; TotalNumItems = totalNumItems; HasMoreItems = hasMoreItems; } public IList

Items { get; private set; } public long? TotalNumItems { get; private set; } public bool? HasMoreItems { get; private set; } } } ///

/// CMIS Collection Enumerable. /// public class CollectionEnumerable : AbstractEnumerable { public CollectionEnumerable(PageFetcher pageFetcher) : this(0, pageFetcher) { } public CollectionEnumerable(long position, PageFetcher pageFetcher) : base(position, pageFetcher) { } protected override AbstractEnumerator CreateEnumerator() { return new CollectionEnumerator(SkipCount, PageFetcher); } } /// /// Enumerator for iterating over all items in a CMIS Collection. /// public class CollectionEnumerator : AbstractEnumerator { public CollectionEnumerator(long skipCount, PageFetcher pageFetcher) : base(skipCount, pageFetcher) { } public override bool MoveNext() { PageFetcher.Page page = GetCurrentPage(); if (page == null) { return false; } IList items = page.Items; if (items == null || items.Count == 0) { return false; } if (SkipOffset == items.Count) { if (!HasMoreItems) { return false; } page = IncrementPage(); items = page == null ? null : page.Items; } if (items == null || items.Count == 0 || SkipOffset == items.Count) { return false; } Current = items[IncrementSkipOffset()]; return true; } } /// /// Enumerable for a CMIS Collection Page. /// public class CollectionPageEnumerable : AbstractEnumerable { public CollectionPageEnumerable(PageFetcher pageFetcher) : this(0, pageFetcher) { } public CollectionPageEnumerable(long position, PageFetcher pageFetcher) : base(position, pageFetcher) { } protected override AbstractEnumerator CreateEnumerator() { return new CollectionPageEnumerator(SkipCount, PageFetcher); } } /// /// Enumerator for iterating over a page of items in a CMIS Collection. /// public class CollectionPageEnumerator : AbstractEnumerator { public CollectionPageEnumerator(long skipCount, PageFetcher pageFetcher) : base(skipCount, pageFetcher) { } public override bool MoveNext() { PageFetcher.Page page = GetCurrentPage(); if (page == null) { return false; } IList items = page.Items; if (items == null || items.Count == 0 || SkipOffset == items.Count) { return false; } Current = items[IncrementSkipOffset()]; return true; } } }