blob: 603b9128d85af3b856d4d5d6b53f04dff0e7a901 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotCMIS.Binding;
using DotCMIS.Data;
using DotCMIS.Exceptions;
using System.Threading;
using DotCMIS.Enums;
using DotCMIS.Data.Extensions;
using DotCMIS.Binding.Services;
namespace DotCMIS.Client
{
/// <summary>
/// Session factory implementation.
/// </summary>
public class SessionFactory : ISessionFactory
{
private SessionFactory()
{
}
public static SessionFactory NewInstance()
{
return new SessionFactory();
}
public ISession CreateSession(IDictionary<string, string> parameters)
{
Session session = new Session(parameters);
session.Connect();
return session;
}
public IList<IRepository> GetRepositories(IDictionary<string, string> parameters)
{
ICmisBinding binding = CmisBindingHelper.CreateProvider(parameters);
IList<IRepositoryInfo> repositoryInfos = binding.GetRepositoryService().GetRepositoryInfos(null);
IList<IRepository> result = new List<IRepository>();
foreach (IRepositoryInfo data in repositoryInfos)
{
result.Add(new Repository(data, parameters, this));
}
return result;
}
}
/// <summary>
/// Binding helper class.
/// </summary>
internal class CmisBindingHelper
{
public static ICmisBinding CreateProvider(IDictionary<string, string> parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
if (!parameters.ContainsKey(SessionParameter.BindingType))
{
parameters[SessionParameter.BindingType] = BindingType.Custom;
}
string bt = parameters[SessionParameter.BindingType];
switch (bt)
{
case BindingType.AtomPub:
return CreateAtomPubBinding(parameters);
case BindingType.WebServices:
return CreateWebServiceBinding(parameters);
case BindingType.Custom:
return CreateCustomBinding(parameters);
default:
throw new CmisRuntimeException("Ambiguous session parameter: " + parameters);
}
}
private static ICmisBinding CreateCustomBinding(IDictionary<string, string> parameters)
{
CmisBindingFactory factory = CmisBindingFactory.NewInstance();
ICmisBinding binding = factory.CreateCmisBinding(parameters);
return binding;
}
private static ICmisBinding CreateWebServiceBinding(IDictionary<string, string> parameters)
{
CmisBindingFactory factory = CmisBindingFactory.NewInstance();
ICmisBinding binding = factory.CreateCmisWebServicesBinding(parameters);
return binding;
}
private static ICmisBinding CreateAtomPubBinding(IDictionary<string, string> parameters)
{
CmisBindingFactory factory = CmisBindingFactory.NewInstance();
ICmisBinding binding = factory.CreateCmisAtomPubBinding(parameters);
return binding;
}
}
/// <summary>
/// Repository implementation.
/// </summary>
public class Repository : RepositoryInfo, IRepository
{
private IDictionary<string, string> parameters;
private ISessionFactory sessionFactory;
public Repository(IRepositoryInfo info, IDictionary<string, string> parameters, ISessionFactory sessionFactory)
: base(info)
{
this.parameters = new Dictionary<string, string>(parameters);
this.parameters[SessionParameter.RepositoryId] = Id;
this.sessionFactory = sessionFactory;
}
public ISession CreateSession()
{
return sessionFactory.CreateSession(parameters);
}
}
/// <summary>
/// Session implementation.
/// </summary>
public class Session : ISession
{
protected static IOperationContext FallbackContext = new OperationContext(null, false, true, false, IncludeRelationshipsFlag.None, null, true, null, true, 100);
protected IDictionary<string, string> parameters;
private object sessionLock = new object();
public ICmisBinding Binding { get; protected set; }
public IRepositoryInfo RepositoryInfo { get; protected set; }
public string RepositoryId { get { return RepositoryInfo.Id; } }
public IObjectFactory ObjectFactory { get; protected set; }
protected ICache Cache { get; set; }
private IOperationContext context = FallbackContext;
public IOperationContext DefaultContext
{
get
{
Lock();
try
{
return context;
}
finally
{
Unlock();
}
}
set
{
Lock();
try
{
context = (value == null ? FallbackContext : value);
}
finally
{
Unlock();
}
}
}
public Session(IDictionary<string, string> parameters)
{
if (parameters == null)
{
throw new ArgumentNullException("parameters");
}
this.parameters = parameters;
ObjectFactory = CreateObjectFactory();
Cache = CreateCache();
}
public void Connect()
{
Lock();
try
{
Binding = CmisBindingHelper.CreateProvider(parameters);
string repositoryId;
if (!parameters.TryGetValue(SessionParameter.RepositoryId, out repositoryId))
{
throw new ArgumentException("Repository Id is not set!");
}
RepositoryInfo = Binding.GetRepositoryService().GetRepositoryInfo(repositoryId, null);
}
finally
{
Unlock();
}
}
protected ICache CreateCache()
{
try
{
string typeName;
Type cacheType;
if (parameters.TryGetValue(SessionParameter.CacheClass, out typeName))
{
cacheType = Type.GetType(typeName);
}
else
{
cacheType = typeof(NoCache);
}
object cacheObject = Activator.CreateInstance(cacheType);
if (!(cacheObject is ICache))
{
throw new Exception("Class does not implement ICache!");
}
((ICache)cacheObject).Initialize(this, parameters);
return (ICache)cacheObject;
}
catch (Exception e)
{
throw new ArgumentException("Unable to create cache: " + e, e);
}
}
protected IObjectFactory CreateObjectFactory()
{
try
{
string ofName;
Type ofType;
if (parameters.TryGetValue(SessionParameter.ObjectFactoryClass, out ofName))
{
ofType = Type.GetType(ofName);
}
else
{
ofType = typeof(ObjectFactory);
}
object ofObject = Activator.CreateInstance(ofType);
if (!(ofObject is IObjectFactory))
{
throw new Exception("Class does not implement IObjectFactory!");
}
((IObjectFactory)ofObject).Initialize(this, parameters);
return (IObjectFactory)ofObject;
}
catch (Exception e)
{
throw new ArgumentException("Unable to create object factory: " + e, e);
}
}
public void Clear()
{
Lock();
try
{
Cache = CreateCache();
Binding.ClearAllCaches();
}
finally
{
Unlock();
}
}
// session context
public IOperationContext CreateOperationContext()
{
return new OperationContext();
}
public IOperationContext CreateOperationContext(HashSet<string> filter, bool includeAcls, bool includeAllowableActions, bool includePolicies,
IncludeRelationshipsFlag includeRelationships, HashSet<string> renditionFilter, bool includePathSegments, string orderBy,
bool cacheEnabled, int maxItemsPerPage)
{
return new OperationContext(filter, includeAcls, includeAllowableActions, includePolicies, includeRelationships, renditionFilter,
includePathSegments, orderBy, cacheEnabled, maxItemsPerPage);
}
public IObjectId CreateObjectId(string id)
{
return new ObjectId(id);
}
// types
public IObjectType GetTypeDefinition(string typeId)
{
ITypeDefinition typeDefinition = Binding.GetRepositoryService().GetTypeDefinition(RepositoryId, typeId, null);
return ObjectFactory.ConvertTypeDefinition(typeDefinition);
}
public IItemEnumerable<IObjectType> GetTypeChildren(string typeId, bool includePropertyDefinitions)
{
IRepositoryService repositoryService = Binding.GetRepositoryService();
PageFetcher<IObjectType>.FetchPage fetchPageDelegate = delegate(long maxNumItems, long skipCount)
{
// fetch the data
ITypeDefinitionList tdl = repositoryService.GetTypeChildren(RepositoryId, typeId, includePropertyDefinitions, maxNumItems, skipCount, null);
// convert type definitions
IList<IObjectType> page = new List<IObjectType>(tdl.List.Count);
foreach (ITypeDefinition typeDefinition in tdl.List)
{
page.Add(ObjectFactory.ConvertTypeDefinition(typeDefinition));
}
return new PageFetcher<IObjectType>.Page<IObjectType>(page, tdl.NumItems, tdl.HasMoreItems);
};
return new CollectionEnumerable<IObjectType>(new PageFetcher<IObjectType>(DefaultContext.MaxItemsPerPage, fetchPageDelegate));
}
public IList<ITree<IObjectType>> GetTypeDescendants(string typeId, int depth, bool includePropertyDefinitions)
{
IList<ITypeDefinitionContainer> descendants = Binding.GetRepositoryService().GetTypeDescendants(
RepositoryId, typeId, depth, includePropertyDefinitions, null);
return ConvertTypeDescendants(descendants);
}
private IList<ITree<IObjectType>> ConvertTypeDescendants(IList<ITypeDefinitionContainer> descendantsList)
{
IList<ITree<IObjectType>> result = new List<ITree<IObjectType>>();
foreach (ITypeDefinitionContainer container in descendantsList)
{
Tree<IObjectType> tree = new Tree<IObjectType>();
tree.Item = ObjectFactory.ConvertTypeDefinition(container.TypeDefinition);
tree.Children = ConvertTypeDescendants(container.Children);
result.Add(tree);
}
return result;
}
// navigation
public IFolder GetRootFolder()
{
return GetRootFolder(DefaultContext);
}
public IFolder GetRootFolder(IOperationContext context)
{
ICmisObject rootFolder = GetObject(CreateObjectId(RepositoryInfo.RootFolderId), context);
if (!(rootFolder is IFolder))
{
throw new CmisRuntimeException("Root folder object is not a folder!");
}
return (IFolder)rootFolder;
}
public IItemEnumerable<IDocument> GetCheckedOutDocs()
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IItemEnumerable<IDocument> GetCheckedOutDocs(IOperationContext context)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public ICmisObject GetObject(IObjectId objectId)
{
return GetObject(objectId, DefaultContext);
}
public ICmisObject GetObject(IObjectId objectId, IOperationContext context)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public ICmisObject GetObjectByPath(string path)
{
return GetObjectByPath(path, DefaultContext);
}
public ICmisObject GetObjectByPath(string path, IOperationContext context)
{ throw new CmisNotSupportedException("Client not implemented!"); }
// discovery
public IItemEnumerable<IQueryResult> Query(string statement, bool searchAllVersions)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IItemEnumerable<IQueryResult> Query(string statement, bool searchAllVersions, IOperationContext context)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IChangeEvents GetContentChanges(string changeLogToken, bool includeProperties, long maxNumItems)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IChangeEvents GetContentChanges(string changeLogToken, bool includeProperties, long maxNumItems,
IOperationContext context)
{ throw new CmisNotSupportedException("Client not implemented!"); }
// create
public IObjectId CreateDocument(IDictionary<string, object> properties, IObjectId folderId, IContentStream contentStream,
VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateDocument(IDictionary<string, object> properties, IObjectId folderId, IContentStream contentStream,
VersioningState? versioningState)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, IObjectId folderId,
VersioningState? versioningState, IList<IPolicy> policies, IList<IAce> addAces, IList<IAce> removeAces)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateDocumentFromSource(IObjectId source, IDictionary<string, object> properties, IObjectId folderId,
VersioningState? versioningState)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateFolder(IDictionary<string, object> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateFolder(IDictionary<string, object> properties, IObjectId folderId)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreatePolicy(IDictionary<string, object> properties, IObjectId folderId, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreatePolicy(IDictionary<string, object> properties, IObjectId folderId)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateRelationship(IDictionary<string, object> properties, IList<IPolicy> policies, IList<IAce> addAces,
IList<IAce> removeAces)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IObjectId CreateRelationship(IDictionary<string, object> properties)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IItemEnumerable<IRelationship> GetRelationships(IObjectId objectId, bool includeSubRelationshipTypes,
RelationshipDirection? relationshipDirection, IObjectType type, IOperationContext context)
{ throw new CmisNotSupportedException("Client not implemented!"); }
// permissions
public IAcl GetAcl(IObjectId objectId, bool onlyBasicPermissions)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public IAcl ApplyAcl(IObjectId objectId, IList<IAce> addAces, IList<IAce> removeAces, AclPropagation? aclPropagation)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public void ApplyPolicy(IObjectId objectId, IObjectId policyIds)
{ throw new CmisNotSupportedException("Client not implemented!"); }
public void RemovePolicy(IObjectId objectId, IObjectId policyIds)
{ throw new CmisNotSupportedException("Client not implemented!"); }
protected void Lock()
{
Monitor.Enter(sessionLock);
}
protected void Unlock()
{
Monitor.Exit(sessionLock);
}
}
}