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
;
39 public enum QueryDomain
{
46 public class Query
: RequestMessage
{
48 // FIXME: This is a good default when on an airplane.
49 private Beagle
.QueryDomain domainFlags
= QueryDomain
.Local
| QueryDomain
.System
;
51 private ArrayList parts
= new ArrayList ();
52 private ArrayList mimeTypes
= new ArrayList ();
53 private ArrayList hitTypes
= new ArrayList ();
54 private ArrayList searchSources
= new ArrayList ();
56 private ArrayList exact_text
= null;
57 private ArrayList stemmed_text
= null;
59 private QueryPart_Or mime_type_part
= null;
60 private QueryPart_Or hit_type_part
= null;
61 private QueryPart_Or source_part
= null;
63 private bool is_index_listener
= false;
65 // Events to make things nicer to clients
66 public delegate void HitsAdded (HitsAddedResponse response
);
67 public event HitsAdded HitsAddedEvent
;
69 public delegate void HitsSubtracted (HitsSubtractedResponse response
);
70 public event HitsSubtracted HitsSubtractedEvent
;
72 public delegate void Finished (FinishedResponse response
);
73 public event Finished FinishedEvent
;
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 (ErrorResponse
), OnError
);
81 this.RegisterAsyncResponseHandler (typeof (SearchTermResponse
), OnSearchTerms
);
84 public Query (string str
) : this ()
89 ///////////////////////////////////////////////////////////////
91 private void OnHitsAdded (ResponseMessage r
)
93 HitsAddedResponse response
= (HitsAddedResponse
) r
;
95 if (this.HitsAddedEvent
!= null)
96 this.HitsAddedEvent (response
);
99 private void OnHitsSubtracted (ResponseMessage r
)
101 HitsSubtractedResponse response
= (HitsSubtractedResponse
) r
;
103 if (this.HitsSubtractedEvent
!= null)
104 this.HitsSubtractedEvent (response
);
107 private void OnFinished (ResponseMessage r
)
109 FinishedResponse response
= (FinishedResponse
) r
;
111 if (this.FinishedEvent
!= null)
112 this.FinishedEvent (response
);
115 private void OnError (ResponseMessage r
)
117 ErrorResponse response
= (ErrorResponse
) r
;
119 throw new ResponseMessageException (response
);
122 private void OnSearchTerms (ResponseMessage r
)
124 SearchTermResponse response
= (SearchTermResponse
) r
;
125 ProcessSearchTermResponse (response
);
128 ///////////////////////////////////////////////////////////////
130 // This is exposed for the benefit of QueryDriver.DoQueryLocal
131 public void ProcessSearchTermResponse (SearchTermResponse response
)
133 exact_text
= response
.ExactText
;
134 stemmed_text
= response
.StemmedText
;
137 ///////////////////////////////////////////////////////////////
139 // Warning: For the moment, the daemon is allowed to IGNORE
140 // index listener queries at its discretion... so don't assume
141 // that they will work for you! Listener queries should only be
142 // used for debugging and testing.
144 public bool IsIndexListener
{
145 set { is_index_listener = value; }
146 get { return is_index_listener; }
149 ///////////////////////////////////////////////////////////////
151 public void ClearParts ()
157 public void AddPart (QueryPart part
)
163 // This is a human-entered query string that will be parsed in
165 public void AddText (string str
)
167 QueryPart_Human part
;
168 part
= new QueryPart_Human ();
169 part
.QueryString
= str
;
173 [XmlArrayItem (ElementName
="Part", Type
=typeof (QueryPart
))]
174 [XmlArray (ElementName
="Parts")]
175 public ArrayList Parts
{
176 get { return parts; }
180 public ICollection Text
{
181 get { return exact_text; }
185 public string QuotedText
{
187 StringBuilder builder
= new StringBuilder ();
188 foreach (string text
in Text
) {
189 string text_cooked
= text
;
190 if (builder
.Length
> 0)
191 builder
.Append (' ');
192 bool contains_space
= (text
.IndexOf (' ') != -1);
193 if (contains_space
) {
194 text_cooked
= text
.Replace ("\"", "\\\"");
195 builder
.Append ('"');
197 builder
.Append (text_cooked
);
199 builder
.Append ('"');
201 return builder
.ToString ();
206 public ICollection StemmedText
{
207 get { return stemmed_text; }
210 ///////////////////////////////////////////////////////////////
212 // This API is DEPRECATED.
213 // The mime type is now stored in the beagle:MimeType property.
214 // To restrict on mime type, just do a normal property query.
216 public void AddMimeType (string str
)
220 if (mime_type_part
== null) {
221 mime_type_part
= new QueryPart_Or ();
222 AddPart (mime_type_part
);
225 // Create a part for this mime type.
226 QueryPart_Property part
;
227 part
= new QueryPart_Property ();
228 part
.Type
= PropertyType
.Keyword
;
229 part
.Key
= "beagle:MimeType";
231 mime_type_part
.Add (part
);
234 public bool AllowsMimeType (string str
)
236 if (mimeTypes
.Count
== 0)
238 foreach (string mt
in mimeTypes
)
244 [XmlArrayItem (ElementName
="MimeType",
245 Type
=typeof (string))]
246 [XmlArray (ElementName
="MimeTypes")]
247 public ArrayList MimeTypes
{
248 get { return mimeTypes; }
251 public bool HasMimeTypes
{
252 get { return mimeTypes.Count > 0; }
255 ///////////////////////////////////////////////////////////////
257 // This API is DEPRECATED.
258 // The mime type is now stored in the beagle:HitType property.
259 // To restrict on type, just do a normal property query.
261 public void AddHitType (string str
)
265 if (hit_type_part
== null) {
266 hit_type_part
= new QueryPart_Or ();
267 AddPart (hit_type_part
);
270 // Add a part for this hit type.
271 QueryPart_Property part
;
272 part
= new QueryPart_Property ();
273 part
.Type
= PropertyType
.Keyword
;
274 part
.Key
= "beagle:HitType";
276 hit_type_part
.Add (part
);
279 public bool AllowsHitType (string str
)
281 if (hitTypes
.Count
== 0)
283 foreach (string ht
in hitTypes
)
289 [XmlArrayItem (ElementName
="HitType",
290 Type
=typeof(string))]
291 [XmlArray (ElementName
="HitTypes")]
292 public ArrayList HitTypes
{
293 get { return hitTypes; }
297 public bool HasHitTypes
{
298 get { return hitTypes.Count > 0; }
301 ///////////////////////////////////////////////////////////////
303 // This API is DEPRECATED.
304 // The source is now stored in the beagle:Source property.
305 // To restrict on source, just do a normal property query.
307 public void AddSource (string str
)
309 searchSources
.Add (str
);
311 if (source_part
== null) {
312 source_part
= new QueryPart_Or ();
313 AddPart (source_part
);
316 // Add a part for this source type.
317 QueryPart_Property part
;
318 part
= new QueryPart_Property ();
319 part
.Type
= PropertyType
.Keyword
;
320 part
.Key
= "beagle:Source";
322 source_part
.Add (part
);
326 public bool AllowsSource (string str
)
328 if (searchSources
.Count
== 0)
330 foreach (string ss
in searchSources
)
336 [XmlArrayItem (ElementName
="Source",
337 Type
=typeof (string))]
338 [XmlArray (ElementName
="Sources")]
339 public ArrayList Sources
{
340 get { return searchSources; }
344 public bool HasSources
{
345 get { return searchSources.Count > 0; }
348 ///////////////////////////////////////////////////////////////
350 public QueryDomain QueryDomain
{
351 get { return domainFlags; }
352 set { domainFlags = value; }
355 public void AddDomain (Beagle
.QueryDomain d
)
360 public void RemoveDomain (Beagle
.QueryDomain d
)
365 public bool AllowsDomain (Beagle
.QueryDomain d
)
367 return (domainFlags
& d
) != 0;
370 ///////////////////////////////////////////////////////////////
372 private int max_hits
= 100;
374 get { return max_hits; }
375 set { max_hits = value; }
378 ///////////////////////////////////////////////////////////////
381 public bool IsEmpty
{
382 get { return parts
.Count
== 0
383 && mimeTypes
.Count
== 0
384 && searchSources
.Count
== 0; }
387 public override string ToString ()
389 StringBuilder sb
= new StringBuilder ();
391 foreach (QueryPart p
in parts
)
392 sb
.Append (p
.ToString () + "\n");
394 return sb
.ToString ();