From 46c3caf9605b6c6402717f66caf4c2539e7fa9ea Mon Sep 17 00:00:00 2001
From: Patrick Simpson
Date: Fri, 10 Feb 2017 10:34:36 +0100
Subject: [PATCH] Cleaned up ZPushLocalStore, merged into IStore.
---
.../Features/GAB/FeatureGAB.cs | 10 +-
.../AcaciaZPushPlugin/Stubs/IAddIn.cs | 7 ++
.../AcaciaZPushPlugin/Stubs/IFolder.cs | 1 +
.../AcaciaZPushPlugin/Stubs/IStore.cs | 9 ++
.../Stubs/OutlookWrappers/AddInWrapper.cs | 37 +++++-
.../Stubs/OutlookWrappers/FolderWrapper.cs | 5 +
.../Stubs/OutlookWrappers/StoreWrapper.cs | 29 ++++-
.../ZPush/ZPushLocalStore.cs | 113 +++++++-----------
8 files changed, 133 insertions(+), 78 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
index aadb251..475187f 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/GAB/FeatureGAB.cs
@@ -39,7 +39,7 @@ namespace Acacia.Features.GAB
private readonly Dictionary _gabsByDomainName = new Dictionary();
private readonly HashSet _gabFolders = new HashSet();
private readonly HashSet _domains = new HashSet();
- 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())
{
@@ -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())
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs
index ed384be..4a07b11 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddIn.cs
@@ -57,6 +57,13 @@ namespace Acacia.Stubs
IRecipient ResolveRecipient(string name);
+ IStore AddFileStore(string path);
+
+ ///
+ /// Returns the stores. The caller is responsible for disposing.
+ ///
+ IEnumerable Stores { get; }
+
#endregion
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs
index 9130f06..13aca83 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs
@@ -54,6 +54,7 @@ namespace Acacia.Stubs
IEnumerable GetSubFolders()
where FolderType : IFolder;
+ IEnumerable GetSubFolders();
FolderType GetSubFolder(string name)
where FolderType : IFolder;
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IStore.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IStore.cs
index 51c0523..f14e12d 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IStore.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IStore.cs
@@ -24,9 +24,18 @@ namespace Acacia.Stubs
{
public interface IStore : IDisposable
{
+ ///
+ /// Returns the root folder.
+ ///
+ /// The root folder. The caller is responsible for disposing.
IFolder GetRootFolder();
IItem GetItemFromID(string id);
string DisplayName { get; }
string StoreID { get; }
+
+ bool IsFileStore { get; }
+ string FilePath { get; }
+
+ void EmptyDeletedItems();
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs
index b2cbe70..ebad830 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddInWrapper.cs
@@ -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 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);
+ }
+ }
+ }
+ }
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs
index 2361b09..d19678b 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs
@@ -296,6 +296,11 @@ namespace Acacia.Stubs.OutlookWrappers
};
}
+ public IEnumerable GetSubFolders()
+ {
+ return GetSubFolders();
+ }
+
public FolderType GetSubFolder(string name)
where FolderType : IFolder
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs
index 30f1241..675c292 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StoreWrapper.cs
@@ -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();
+ }
+ }
+ }
+
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs
index faa31f2..643b266 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushLocalStore.cs
@@ -30,58 +30,32 @@ namespace Acacia.ZPush
///
/// Manages a local store in which Z-Push data is stored.
///
- /// TODO: merge with Store where possible
- public class ZPushLocalStore : ComWrapper
+ public static class ZPushLocalStore
{
- private NSOutlook.Store _store;
-
- public IFolder RootFolder
+ ///
+ /// Returns or creates the local store.
+ ///
+ /// The store, or null on error. If a store is returned, the caller is responsible for disposing.
+ public static IStore GetInstance(IAddIn addIn)
{
- get
+ IStore store = OpenOrCreateInstance(addIn);
+ if (store == null)
+ return null;
+
+ try
{
- return Mapping.Wrap(_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(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);
+ }
}
}
}
+
}
}