Fix #362058. Check for illegal length in PPT filter.
[beagle.git] / BeagleClient / Query.cs
blob0b7c5e2095488ba51f7a51a5c19835a28c0c37f8
1 //
2 // Query.cs
3 //
4 // Copyright (C) 2004-2005 Novell, Inc.
5 //
7 //
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.
28 using System;
29 using System.IO;
30 using System.Collections;
31 using System.Text;
32 using System.Xml.Serialization;
34 using Beagle.Util;
36 namespace Beagle {
38 [Flags]
39 public enum QueryDomain {
40 Local = 1,
41 System = 2,
42 Neighborhood = 4,
43 Global = 8
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 ()
86 AddText (str);
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 ()
153 if (parts != null)
154 parts.Clear ();
157 public void AddPart (QueryPart part)
159 if (part != null)
160 parts.Add (part);
163 // This is a human-entered query string that will be parsed in
164 // the daemon.
165 public void AddText (string str)
167 QueryPart_Human part;
168 part = new QueryPart_Human ();
169 part.QueryString = str;
170 AddPart (part);
173 [XmlArrayItem (ElementName="Part", Type=typeof (QueryPart))]
174 [XmlArray (ElementName="Parts")]
175 public ArrayList Parts {
176 get { return parts; }
179 [XmlIgnore]
180 public ICollection Text {
181 get { return exact_text; }
184 [XmlIgnore]
185 public string QuotedText {
186 get {
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);
198 if (contains_space)
199 builder.Append ('"');
201 return builder.ToString ();
205 [XmlIgnore]
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)
218 mimeTypes.Add (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";
230 part.Value = str;
231 mime_type_part.Add (part);
234 public bool AllowsMimeType (string str)
236 if (mimeTypes.Count == 0)
237 return true;
238 foreach (string mt in mimeTypes)
239 if (str == mt)
240 return true;
241 return false;
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)
263 hitTypes.Add (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";
275 part.Value = str;
276 hit_type_part.Add (part);
279 public bool AllowsHitType (string str)
281 if (hitTypes.Count == 0)
282 return true;
283 foreach (string ht in hitTypes)
284 if (str == ht)
285 return true;
286 return false;
289 [XmlArrayItem (ElementName="HitType",
290 Type=typeof(string))]
291 [XmlArray (ElementName="HitTypes")]
292 public ArrayList HitTypes {
293 get { return hitTypes; }
296 [XmlIgnore]
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";
321 part.Value = str;
322 source_part.Add (part);
326 public bool AllowsSource (string str)
328 if (searchSources.Count == 0)
329 return true;
330 foreach (string ss in searchSources)
331 if (str == ss)
332 return true;
333 return false;
336 [XmlArrayItem (ElementName="Source",
337 Type=typeof (string))]
338 [XmlArray (ElementName="Sources")]
339 public ArrayList Sources {
340 get { return searchSources; }
343 [XmlIgnore]
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)
357 domainFlags |= d;
360 public void RemoveDomain (Beagle.QueryDomain d)
362 domainFlags &= ~d;
365 public bool AllowsDomain (Beagle.QueryDomain d)
367 return (domainFlags & d) != 0;
370 ///////////////////////////////////////////////////////////////
372 private int max_hits = 100;
373 public int MaxHits {
374 get { return max_hits; }
375 set { max_hits = value; }
378 ///////////////////////////////////////////////////////////////
380 [XmlIgnore]
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 ();