Cleaned up ZPushLocalStore, merged into IStore.

This commit is contained in:
Patrick Simpson 2017-02-10 10:34:36 +01:00
parent 65a46510c1
commit d1bbb221b4
8 changed files with 133 additions and 78 deletions

View File

@ -39,7 +39,7 @@ namespace Acacia.Features.GAB
private readonly Dictionary<string, GABHandler> _gabsByDomainName = new Dictionary<string, GABHandler>();
private readonly HashSet<string> _gabFolders = new HashSet<string>();
private readonly HashSet<string> _domains = new HashSet<string>();
private ZPushLocalStore _store;
private IStore _store;
private int _processing;
public FeatureGAB()
@ -316,11 +316,11 @@ namespace Acacia.Features.GAB
// Delete any contacts folders in the local store
if (DeleteExistingFolder)
{
using (ZPushLocalStore store = ZPushLocalStore.GetInstance(ThisAddIn.Instance))
using (IStore store = ZPushLocalStore.GetInstance(ThisAddIn.Instance))
{
if (store != null)
{
using (IFolder root = store.RootFolder)
using (IFolder root = store.GetRootFolder())
{
foreach (IFolder folder in root.GetSubFolders<IFolder>())
{
@ -416,7 +416,7 @@ namespace Acacia.Features.GAB
return null;
// Try to find the existing GAB
using (IFolder root = _store.RootFolder)
using (IFolder root = _store.GetRootFolder())
{
IAddressBook gab = FindGABForDomain(root, domainName);
if (gab == null)
@ -538,7 +538,7 @@ namespace Acacia.Features.GAB
return;
bool deletedSomething = false;
using (IFolder root = _store.RootFolder)
using (IFolder root = _store.GetRootFolder())
{
foreach (IFolder subfolder in root.GetSubFolders<IFolder>())
{

View File

@ -57,6 +57,13 @@ namespace Acacia.Stubs
IRecipient ResolveRecipient(string name);
IStore AddFileStore(string path);
/// <summary>
/// Returns the stores. The caller is responsible for disposing.
/// </summary>
IEnumerable<IStore> Stores { get; }
#endregion
}
}

View File

@ -54,6 +54,7 @@ namespace Acacia.Stubs
IEnumerable<FolderType> GetSubFolders<FolderType>()
where FolderType : IFolder;
IEnumerable<IFolder> GetSubFolders();
FolderType GetSubFolder<FolderType>(string name)
where FolderType : IFolder;

View File

@ -24,9 +24,18 @@ namespace Acacia.Stubs
{
public interface IStore : IDisposable
{
/// <summary>
/// Returns the root folder.
/// </summary>
/// <returns>The root folder. The caller is responsible for disposing.</returns>
IFolder GetRootFolder();
IItem GetItemFromID(string id);
string DisplayName { get; }
string StoreID { get; }
bool IsFileStore { get; }
string FilePath { get; }
void EmptyDeletedItems();
}
}

View File

@ -94,7 +94,7 @@ namespace Acacia.Stubs.OutlookWrappers
Microsoft.Office.Core.COMAddIns addIns = _app.COMAddIns;
try
{
foreach(Microsoft.Office.Core.COMAddIn comAddin in addIns)
foreach (Microsoft.Office.Core.COMAddIn comAddin in addIns)
{
try
{
@ -196,13 +196,44 @@ namespace Acacia.Stubs.OutlookWrappers
using (ComRelease com = new ComRelease())
{
NSOutlook.NameSpace session = com.Add(_app.Session);
NSOutlook.Recipient recipient = session.CreateRecipient(name);
// Add recipient, unlock after Resolve (which might throw) to wrap
NSOutlook.Recipient recipient = com.Add(session.CreateRecipient(name));
if (recipient == null)
return null;
com.Add(recipient);
recipient.Resolve();
return Mapping.Wrap(com.Remove(recipient));
}
}
public IStore AddFileStore(string path)
{
using (ComRelease com = new ComRelease())
{
NSOutlook.NameSpace session = com.Add(_app.Session);
// Add the store
session.AddStore(path);
// And fetch it and wrap
NSOutlook.Stores stores = com.Add(session.Stores);
return StoreWrapper.Wrap(stores[stores.Count]);
}
}
public IEnumerable<IStore> Stores
{
get
{
using (ComRelease com = new ComRelease())
{
NSOutlook.NameSpace session = com.Add(_app.Session);
NSOutlook.Stores stores = com.Add(session.Stores);
foreach (NSOutlook.Store store in stores)
{
yield return StoreWrapper.Wrap(store);
}
}
}
}
}
}

View File

@ -296,6 +296,11 @@ namespace Acacia.Stubs.OutlookWrappers
};
}
public IEnumerable<IFolder> GetSubFolders()
{
return GetSubFolders<IFolder>();
}
public FolderType GetSubFolder<FolderType>(string name)
where FolderType : IFolder
{

View File

@ -24,9 +24,9 @@ using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Stubs.OutlookWrappers
{
public class StoreWrapper : ComWrapper, IStore
class StoreWrapper : ComWrapper, IStore
{
public static IStore Wrap(NSOutlook.Store store)
internal static IStore Wrap(NSOutlook.Store store)
{
return store == null ? null : new StoreWrapper(store);
}
@ -64,5 +64,30 @@ namespace Acacia.Stubs.OutlookWrappers
public string DisplayName { get { return _store.DisplayName; } }
public string StoreID { get { return _store.StoreID; } }
public bool IsFileStore { get { return _store.IsDataFileStore; } }
public string FilePath { get { return _store.FilePath; } }
public void EmptyDeletedItems()
{
using (ComRelease com = new ComRelease())
{
NSOutlook.MAPIFolder f = _store.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems);
if (f != null)
{
com.Add(f);
// Normal enumeration fails when deleting. Do it like this.
NSOutlook.Folders folders = com.Add(f.Folders);
for (int i = folders.Count; i > 0; --i)
com.Add(folders[i]).Delete();
NSOutlook.Items items = com.Add(f.Items);
for (int i = items.Count; i > 0; --i)
com.Add(items[i]).Delete();
}
}
}
}
}

View File

@ -30,58 +30,32 @@ namespace Acacia.ZPush
/// <summary>
/// Manages a local store in which Z-Push data is stored.
/// </summary>
/// TODO: merge with Store where possible
public class ZPushLocalStore : ComWrapper
public static class ZPushLocalStore
{
private NSOutlook.Store _store;
public IFolder RootFolder
/// <summary>
/// Returns or creates the local store.
/// </summary>
/// <returns>The store, or null on error. If a store is returned, the caller is responsible for disposing.</returns>
public static IStore GetInstance(IAddIn addIn)
{
get
IStore store = OpenOrCreateInstance(addIn);
if (store == null)
return null;
try
{
return Mapping.Wrap<IFolder>(_store.GetRootFolder());
HideAllFolders(store);
return store;
}
catch(Exception e)
{
store.Dispose();
throw e;
}
}
public string StoreId { get { return _store.StoreID; } }
private ZPushLocalStore(NSOutlook.Store store)
{
this._store = store;
HideAllFolders();
}
protected override void DoRelease()
{
ComRelease.Release(_store);
_store = null;
}
private bool IsCustomFolder(IFolder folder)
{
return Features.GAB.FeatureGAB.IsGABContactsFolder(folder);
}
private void HideAllFolders()
{
if (GlobalOptions.INSTANCE.LocalFolders_Hide)
{
// Hide the folders that are not custom folders
using (ComRelease com = new ComRelease())
{
foreach (NSOutlook.Folder sub in com.Add(com.Add(_store.GetRootFolder()).Folders))
{
using (IFolder wrapped = Mapping.Wrap<IFolder>(sub))
{
wrapped.AttrHidden = !IsCustomFolder(wrapped);
}
}
}
}
}
public static ZPushLocalStore GetInstance(IAddIn addIn)
{
private static IStore OpenOrCreateInstance(IAddIn addIn)
{
try
{
// Try to find the existing store
@ -94,9 +68,9 @@ namespace Acacia.ZPush
Logger.Instance.Debug(typeof(ZPushLocalStore), "Opening store with prefix {0}", prefix);
// See if a store with this prefix exists
NSOutlook.Store store = FindInstance(addIn, prefix);
IStore store = FindInstance(addIn, prefix);
if (store != null)
return new ZPushLocalStore(store);
return store;
// Doesn't exist, create it
Logger.Instance.Debug(typeof(ZPushLocalStore), "No existing store found");
@ -114,8 +88,7 @@ namespace Acacia.ZPush
// Path found, create the store
Logger.Instance.Info(typeof(ZPushLocalStore), "Creating new store: {0}", path);
addIn.RawApp.Session.AddStore(path);
store = addIn.RawApp.Session.Stores[addIn.RawApp.Session.Stores.Count];
store = addIn.AddFileStore(path);
Logger.Instance.Debug(typeof(ZPushLocalStore), "Created new store: {0}", store.FilePath);
// Set the display name
@ -125,7 +98,7 @@ namespace Acacia.ZPush
}
// Done
return new ZPushLocalStore(store);
return store;
}
catch(System.Exception e)
{
@ -134,38 +107,42 @@ namespace Acacia.ZPush
}
}
private static NSOutlook.Store FindInstance(IAddIn addIn, string prefix)
private static IStore FindInstance(IAddIn addIn, string prefix)
{
foreach (NSOutlook.Store store in addIn.RawApp.Session.Stores)
foreach (IStore store in addIn.Stores)
{
if (store.IsDataFileStore && store.FilePath.StartsWith(prefix))
if (store.IsFileStore && store.FilePath.StartsWith(prefix))
{
Logger.Instance.Info(typeof(ZPushLocalStore), "Opening existing store: {0}", store.FilePath);
return store;
}
else
{
store.Dispose();
}
}
return null;
}
internal void EmptyDeletedItems()
private static bool IsCustomFolder(IFolder folder)
{
using (ComRelease com = new ComRelease())
return Features.GAB.FeatureGAB.IsGABContactsFolder(folder);
}
private static void HideAllFolders(IStore store)
{
if (GlobalOptions.INSTANCE.LocalFolders_Hide)
{
NSOutlook.MAPIFolder f = _store.GetDefaultFolder(NSOutlook.OlDefaultFolders.olFolderDeletedItems);
if (f != null)
// Hide the folders that are not custom folders
using (ComRelease com = new ComRelease())
{
com.Add(f);
// Normal enumeration fails when deleting. Do it like this.
NSOutlook.Folders folders = com.Add(f.Folders);
for (int i = folders.Count; i > 0; --i)
com.Add(folders[i]).Delete();
NSOutlook.Items items = com.Add(f.Items);
for (int i = items.Count; i > 0; --i)
com.Add(items[i]).Delete();
foreach(IFolder sub in store.GetRootFolder().GetSubFolders())
{
sub.AttrHidden = !IsCustomFolder(sub);
}
}
}
}
}
}