2 // ThunderbirdIndexableGenerator.cs: A helper class that makes it very easy to add new features to this backend
4 // Copyright (C) 2006 Pierre Östlund
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 using System
.Collections
;
30 using System
.Reflection
;
31 using System
.Text
.RegularExpressions
;
35 using TB
= Beagle
.Util
.Thunderbird
;
39 namespace Beagle
.Daemon
.ThunderbirdQueryable
{
41 // This is a generic IndexableGenerator-class and should be used to index mork files only!
42 public abstract class ThunderbirdIndexableGenerator
: IIndexableGenerator
{
43 protected ThunderbirdIndexer indexer
;
44 protected TB
.Database db
;
45 protected TB
.Account account
;
46 protected IEnumerator db_enumerator
;
48 private bool full_index
;
49 private string db_file
;
51 private string relative_path
;
52 protected Hashtable stored_cache
;
54 public ThunderbirdIndexableGenerator (ThunderbirdIndexer indexer
, TB
.Account account
, string db_file
)
56 this.indexer
= indexer
;
57 this.indexer
.NotificationEvent
+= OnNotification
;
58 this.account
= account
;
59 this.full_index
= true;
60 this.db_file
= db_file
;
62 this.relative_path
= Thunderbird
.GetRelativePath (db_file
);
64 // Load the database and make sure the enumerator is up to date. Otherwise we will
65 // get lots of null exceptions when enumerating the database.
69 // Fetch all already stored uris in the index. This way we can remove one uri at the time
70 // while we are indexing and thus in the end now which mails that doesn't exist anymore.
71 if (relative_path
!= null)
72 stored_cache
= indexer
.Lucene
.GetStoredUriStrings (account
.Server
, relative_path
);
74 Logger
.Log
.Debug ("Relative path could not be determined for: {0}. Indexing speed will suffer.",
78 public abstract bool HasNextIndexable ();
79 public abstract Indexable
GetNextIndexable ();
80 public abstract void LoadDatabase ();
82 public virtual bool IsUpToDate (Uri uri
)
87 LuceneAccess
.StoredInfo info
= indexer
.Lucene
.GetStoredInfo (uri
);
89 // Remove this uri from the cache
90 if (stored_cache
!= null)
91 stored_cache
.Remove (uri
.ToString ());
93 // Check if this time is "older" than the time we began to index and if the index
94 // status has changed (partial vs. full indexing)
95 if (info
!= null && ThunderbirdQueryable
.IndexingStart
.CompareTo (info
.LastIndex
) < 0 &&
96 FullIndex
== info
.FullyIndexed
) {
103 public virtual void PostFlushHook ()
105 if (!Done
|| (stored_cache
== null) || (Done
&& stored_cache
.Count
== 0))
108 if (Thunderbird
.Debug
)
109 Logger
.Log
.Debug ("Cleaning out old objects in {0} ({1})", RelativePath
, stored_cache
.Count
);
111 ArrayList uris
= new ArrayList ();
112 foreach (string uri_str
in stored_cache
.Keys
)
113 uris
.Add (new Uri (uri_str
));
115 indexer
.ScheduleRemoval ((Uri
[]) uris
.ToArray (typeof (Uri
)),
116 String
.Format ("PostFlushHook-{0}", RelativePath
), Scheduler
.Priority
.Delayed
);
119 protected virtual Indexable
NewIndexable (Uri uri
, DateTime timestamp
, string hit_type
)
123 indexable
= new Indexable (uri
);
124 indexable
.HitType
= hit_type
;
125 indexable
.Timestamp
= timestamp
;
127 indexable
.AddProperty (Property
.NewKeyword ("fixme:account", account
.Server
));
128 indexable
.AddProperty (Property
.NewKeyword ("fixme:client", "thunderbird"));
129 indexable
.AddProperty (Property
.NewUnsearched ("fixme:fullyIndexed", full_index
));
130 indexable
.AddProperty (Property
.NewUnsearched ("fixme:file", RelativePath
));
131 indexable
.AddProperty (Property
.NewDate ("fixme:indexDateTime", DateTime
.UtcNow
));
136 protected virtual void ResetEnumerator ()
138 if (db
!= null && db
.Count
> 0)
139 db_enumerator
= db
.GetEnumerator ();
141 db_enumerator
= null;
144 protected virtual void OnNotification (object o
, NotificationEventArgs args
)
146 if (args
.Account
!= account
)
150 case NotificationType
.StopIndexing
:
151 indexer
.NotificationEvent
-= OnNotification
;
152 Logger
.Log
.Debug ("Stopping running task {0}", account
.Server
);
155 case NotificationType
.RestartIndexing
:
159 case NotificationType
.UpdateAccountInformation
:
160 account
= (TB
.Account
) args
.Data
;
167 // Done should be set to true when there's no more objects to index. This will allow
168 // PostFlushHook to remove old objects from the index.
171 set { done = value; }
174 public string DbFile
{
175 get { return db_file; }
176 set { db_file = value; }
179 public bool FullIndex
{
180 get { return full_index; }
181 set { full_index = value; }
184 // Realtive path to current mork_file
185 public string RelativePath
{
186 get { return relative_path; }
189 protected IEnumerator DbEnumerator
{
190 get { return db_enumerator; }
193 public string StatusName
{
194 get { return account.Server; }
198 /////////////////////////////////////////////////////////////////////////////////////
200 [AttributeUsage (AttributeTargets
.Class
, AllowMultiple
= true)]
201 public class ThunderbirdIndexableGeneratorAttribute
: System
.Attribute
{
202 private TB
.AccountType type
;
203 private string description
;
204 private bool enabled
;
206 public ThunderbirdIndexableGeneratorAttribute (TB
.AccountType type
, string description
, bool enabled
)
209 this.description
= description
;
210 this.enabled
= enabled
;
213 public TB
.AccountType Type
{
215 set { type = value; }
218 public string Description
{
219 get { return description; }
220 set { description = value; }
223 public bool Enabled
{
224 get { return enabled; }
225 set { enabled = value; }
229 /////////////////////////////////////////////////////////////////////////////////////
232 public class UriRemovalIndexableGenerator
: IIndexableGenerator
{
235 private IEnumerator enumerator
;
237 public UriRemovalIndexableGenerator (Uri
[] uris
)
240 this.enumerator
= this.uris
.GetEnumerator ();
243 public Indexable
GetNextIndexable ()
245 return new Indexable (IndexableType
.Remove
, (Uri
) enumerator
.Current
);
248 public bool HasNextIndexable ()
250 while (enumerator
== null || !enumerator
.MoveNext ())
256 public string StatusName
{
257 get { return String.Format ("Removing {0} uris
", uris.Length); }
260 public void PostFlushHook () { }