4 // Copyright (C) 2004-2005 Novell, Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all 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
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
32 using System
.Xml
.Serialization
;
38 public enum QueryDomain
{
45 public class Query
: RequestMessage
{
47 // FIXME: This is a good default when on an airplane.
48 private Beagle
.QueryDomain domainFlags
= QueryDomain
.Local
| QueryDomain
.System
;
50 private ArrayList parts
= new ArrayList ();
51 private ArrayList mimeTypes
= new ArrayList ();
52 private ArrayList hitTypes
= new ArrayList ();
53 private ArrayList searchSources
= new ArrayList ();
55 private ArrayList exact_text
= null;
56 private ArrayList stemmed_text
= null;
58 private QueryPart_Or mime_type_part
= null;
59 private QueryPart_Or hit_type_part
= null;
61 // Events to make things nicer to clients
62 public delegate void HitsAdded (HitsAddedResponse response
);
63 public event HitsAdded HitsAddedEvent
;
65 public delegate void HitsSubtracted (HitsSubtractedResponse response
);
66 public event HitsSubtracted HitsSubtractedEvent
;
68 public delegate void Finished (FinishedResponse response
);
69 public event Finished FinishedEvent
;
71 public delegate void Cancelled (CancelledResponse response
);
72 public event Cancelled CancelledEvent
;
75 public Query () : base (true)
77 this.RegisterAsyncResponseHandler (typeof (HitsAddedResponse
), OnHitsAdded
);
78 this.RegisterAsyncResponseHandler (typeof (HitsSubtractedResponse
), OnHitsSubtracted
);
79 this.RegisterAsyncResponseHandler (typeof (FinishedResponse
), OnFinished
);
80 this.RegisterAsyncResponseHandler (typeof (CancelledResponse
), OnCancelled
);
81 this.RegisterAsyncResponseHandler (typeof (ErrorResponse
), OnError
);
82 this.RegisterAsyncResponseHandler (typeof (SearchTermResponse
), OnSearchTerms
);
85 public Query (string str
) : this ()
90 ///////////////////////////////////////////////////////////////
92 private void OnHitsAdded (ResponseMessage r
)
94 HitsAddedResponse response
= (HitsAddedResponse
) r
;
96 if (this.HitsAddedEvent
!= null)
97 this.HitsAddedEvent (response
);
100 private void OnHitsSubtracted (ResponseMessage r
)
102 HitsSubtractedResponse response
= (HitsSubtractedResponse
) r
;
104 if (this.HitsSubtractedEvent
!= null)
105 this.HitsSubtractedEvent (response
);
108 private void OnFinished (ResponseMessage r
)
110 FinishedResponse response
= (FinishedResponse
) r
;
112 if (this.FinishedEvent
!= null)
113 this.FinishedEvent (response
);
116 private void OnCancelled (ResponseMessage r
)
118 CancelledResponse response
= (CancelledResponse
) r
;
120 if (this.CancelledEvent
!= null)
121 this.CancelledEvent (response
);
124 private void OnError (ResponseMessage r
)
126 ErrorResponse response
= (ErrorResponse
) r
;
128 throw new ResponseMessageException (response
);
131 private void OnSearchTerms (ResponseMessage r
)
133 SearchTermResponse response
= (SearchTermResponse
) r
;
134 ProcessSearchTermResponse (response
);
137 ///////////////////////////////////////////////////////////////
139 // This is exposed for the benefit of QueryDriver.DoQueryLocal
140 public void ProcessSearchTermResponse (SearchTermResponse response
)
142 exact_text
= response
.ExactText
;
143 stemmed_text
= response
.StemmedText
;
146 ///////////////////////////////////////////////////////////////
148 public void ClearParts ()
154 public void AddPart (QueryPart part
)
160 // This is a human-entered query string that will be parsed in
162 public void AddText (string str
)
164 QueryPart_Human part
;
165 part
= new QueryPart_Human ();
166 part
.QueryString
= str
;
170 [XmlArrayItem (ElementName
="Part", Type
=typeof (QueryPart
))]
171 [XmlArray (ElementName
="Parts")]
172 public ArrayList Parts
{
173 get { return parts; }
177 public ICollection Text
{
178 get { return exact_text; }
182 public string QuotedText
{
184 StringBuilder builder
= new StringBuilder ();
185 foreach (string text
in Text
) {
186 string text_cooked
= text
;
187 if (builder
.Length
> 0)
188 builder
.Append (' ');
189 bool contains_space
= (text
.IndexOf (' ') != -1);
190 if (contains_space
) {
191 text_cooked
= text
.Replace ("\"", "\\\"");
192 builder
.Append ('"');
194 builder
.Append (text_cooked
);
196 builder
.Append ('"');
198 return builder
.ToString ();
203 public ICollection StemmedText
{
204 get { return stemmed_text; }
207 ///////////////////////////////////////////////////////////////
209 // This API is DEPRECATED.
210 // The mime type is now stored in the beagle:MimeType property.
211 // To restrict on mime type, just do a normal property query.
213 public void AddMimeType (string str
)
217 if (mime_type_part
== null) {
218 mime_type_part
= new QueryPart_Or ();
219 AddPart (mime_type_part
);
222 // Create a part for this mime type.
223 QueryPart_Property part
;
224 part
= new QueryPart_Property ();
225 part
.Type
= PropertyType
.Keyword
;
226 part
.Key
= "beagle:MimeType";
228 mime_type_part
.Add (part
);
231 public bool AllowsMimeType (string str
)
233 if (mimeTypes
.Count
== 0)
235 foreach (string mt
in mimeTypes
)
241 [XmlArrayItem (ElementName
="MimeType",
242 Type
=typeof (string))]
243 [XmlArray (ElementName
="MimeTypes")]
244 public ArrayList MimeTypes
{
245 get { return mimeTypes; }
248 public bool HasMimeTypes
{
249 get { return mimeTypes.Count > 0; }
252 ///////////////////////////////////////////////////////////////
254 // This API is DEPRECATED.
255 // The mime type is now stored in the beagle:Type property.
256 // To restrict on type, just do a normal property query.
258 public void AddHitType (string str
)
262 if (hit_type_part
== null) {
263 hit_type_part
= new QueryPart_Or ();
264 AddPart (hit_type_part
);
267 // Add a part for this hit type.
268 QueryPart_Property part
;
269 part
= new QueryPart_Property ();
270 part
.Type
= PropertyType
.Keyword
;
271 part
.Key
= "beagle:Type";
273 hit_type_part
.Add (part
);
276 public bool AllowsHitType (string str
)
278 if (hitTypes
.Count
== 0)
280 foreach (string ht
in hitTypes
)
286 [XmlArrayItem (ElementName
="HitType",
287 Type
=typeof(string))]
288 [XmlArray (ElementName
="HitTypes")]
289 public ArrayList HitTypes
{
290 get { return hitTypes; }
294 public bool HasHitTypes
{
295 get { return hitTypes.Count > 0; }
298 ///////////////////////////////////////////////////////////////
300 public void AddSource (string str
)
302 searchSources
.Add (str
);
306 public bool AllowsSource (string str
)
308 if (searchSources
.Count
== 0)
310 foreach (string ss
in searchSources
)
311 if (str
.ToUpper () == ss
.ToUpper ())
316 [XmlArrayItem (ElementName
="Source",
317 Type
=typeof (string))]
318 [XmlArray (ElementName
="Sources")]
319 public ArrayList Sources
{
320 get { return searchSources; }
324 public bool HasSources
{
325 get { return searchSources.Count > 0; }
328 ///////////////////////////////////////////////////////////////
330 public void AddDomain (Beagle
.QueryDomain d
)
335 public void RemoveDomain (Beagle
.QueryDomain d
)
340 public bool AllowsDomain (Beagle
.QueryDomain d
)
342 return (domainFlags
& d
) != 0;
345 ///////////////////////////////////////////////////////////////
347 private int max_hits
= 100;
349 get { return max_hits; }
350 set { max_hits = value; }
353 ///////////////////////////////////////////////////////////////
356 public bool IsEmpty
{
357 get { return parts
.Count
== 0
358 && mimeTypes
.Count
== 0
359 && searchSources
.Count
== 0; }