3 using System
.Collections
;
11 public class FileModel
{
13 // Properties of the root directory:
14 // name contains full path of BEAGLE_HOME
17 // children is non-null
19 // Properties of a non-root directory:
23 // children is non-null
25 // Properties of a file:
27 // parent is non-null, and is a directory
31 private string name
= null;
32 private FileModel parent
= null;
33 private string [] body
= null;
34 private Hashtable children
= null;
36 //////////////////////////////////////////////////////////////
39 get { return parent == null; }
42 public bool IsDirectory
{
43 get { return body == null; }
47 get { return body != null; }
54 public string FullName
{
55 get { return IsRoot ? Name : Path.Combine (parent.FullName, name); }
59 get { return UriFu.PathToFileUri (FullName); }
62 public string [] Body
{
66 public ICollection Children
{
67 get { return children.Values; }
76 sum
= 1; // count ourselves
77 foreach (FileModel child
in children
.Values
)
83 //////////////////////////////////////////////////////////////
85 private void RecursiveListAdd (ArrayList list
, bool add_dirs
, bool add_files
)
87 if ((add_dirs
&& IsDirectory
) || (add_files
&& IsFile
))
90 foreach (FileModel file
in children
.Values
)
91 file
.RecursiveListAdd (list
, add_files
, add_files
);
94 public ArrayList
GetDescendants ()
96 ArrayList list
= new ArrayList ();
97 RecursiveListAdd (list
, true, true);
98 list
.RemoveAt (0); // remove ourselves
102 public ArrayList
GetFileDescendants ()
104 ArrayList list
= new ArrayList ();
105 RecursiveListAdd (list
, false, true);
106 list
.RemoveAt (0); // remove ourselves
110 public ArrayList
GetDirectoryDescendants ()
112 ArrayList list
= new ArrayList ();
113 RecursiveListAdd (list
, true, false);
114 list
.RemoveAt (0); // remove ourselves
118 //////////////////////////////////////////////////////////////
120 static Random random
= new Random ();
122 public FileModel
PickDescendant ()
125 all
= GetDescendants ();
128 return all
[random
.Next (all
.Count
)] as FileModel
;
131 public FileModel
PickFileDescendant ()
134 all
= GetFileDescendants ();
137 return all
[random
.Next (all
.Count
)] as FileModel
;
140 public FileModel
PickDirectoryDescendant ()
143 all
= GetDirectoryDescendants ();
146 return all
[random
.Next (all
.Count
)] as FileModel
;
149 //////////////////////////////////////////////////////////////
151 public bool BodyContains (string token
)
156 // FIXME: Do a binary search (or something smarter)
158 for (int i
= 0; i
< body
.Length
; ++i
)
159 if (body
[i
] == token
)
164 public bool Contains (string token
)
166 return name
== token
|| BodyContains (token
);
169 //////////////////////////////////////////////////////////////
171 private FileModel () { }
173 public static FileModel
NewRoot ()
175 FileModel root
= new FileModel ();
176 root
.name
= PathFinder
.HomeDir
;
177 root
.children
= new Hashtable ();
181 // Creates a randomly-named new directory.
182 // Avoid name collisions with existing files.
183 public FileModel
NewDirectory ()
186 throw new ArgumentException ("parent must be a directory");
188 // no more names left
189 if (children
.Count
== Token
.Count
)
193 child
= new FileModel ();
194 child
.name
= PickName (this);
195 child
.children
= new Hashtable ();
198 children
[child
.name
] = child
;
200 // Actually create the directory
201 Directory
.CreateDirectory (child
.FullName
);
206 public FileModel
NewFile ()
209 throw new ArgumentException ("parent must be a directory");
211 // no more names left
212 if (children
.Count
== Token
.Count
)
216 child
= new FileModel ();
217 child
.name
= PickName (this);
218 child
.body
= NewBody (10);
221 children
[child
.name
] = child
;
229 //////////////////////////////////////////////////////////////
231 public void Grow (int depth
)
233 const int num_dirs
= 2;
234 const int num_files
= 5;
237 for (int i
= 0; i
< num_dirs
; ++i
) {
239 file
= NewDirectory ();
241 file
.Grow (depth
- 1);
245 for (int i
= 0; i
< num_files
; ++i
)
249 //////////////////////////////////////////////////////////////
251 public void Delete ()
254 throw new Exception ("Can't delete the root!");
257 Directory
.Delete (FullName
, true); // recursive
259 File
.Delete (FullName
);
261 parent
.children
.Remove (name
);
266 //////////////////////////////////////////////////////////////
268 static private string PickName (FileModel p
)
272 pick
= Token
.GetRandom ();
273 } while (p
.children
.Contains (pick
));
277 static private string [] NewBody (int size
)
280 body
= new string [size
];
281 for (int i
= 0; i
< size
; ++i
)
282 body
[i
] = Token
.GetRandom ();
287 private void Write ()
290 writer
= new StreamWriter (FullName
);
291 for (int i
= 0; i
< body
.Length
; ++i
)
292 writer
.WriteLine (body
[i
]);
296 //////////////////////////////////////////////////////////////
299 // Code to determine a a file will match a particular query
302 private bool MatchesQueryPart (QueryPart abstract_part
)
307 if (abstract_part
is QueryPart_Text
) {
309 part
= abstract_part
as QueryPart_Text
;
311 if ((part
.SearchTextProperties
&& Name
== part
.Text
)
312 || (part
.SearchFullText
&& BodyContains (part
.Text
)))
315 } else if (abstract_part
is QueryPart_Or
) {
317 part
= abstract_part
as QueryPart_Or
;
319 foreach (QueryPart sub_part
in part
.SubParts
) {
320 if (MatchesQueryPart (sub_part
)) {
325 } else if (abstract_part
is QueryPart_Property
) {
326 QueryPart_Property part
;
327 part
= abstract_part
as QueryPart_Property
;
329 if (part
.Key
== "beagle:MimeType") {
330 if (part
.Value
== "inode/directory")
331 is_match
= IsDirectory
;
332 else if (part
.Value
== "text/plain")
336 } else if (part
.Key
== "beagle:ExactFilename") {
337 is_match
= (Name
== part
.Value
);
339 throw new Exception ("Unsupported property " + part
.Key
);
342 throw new Exception ("Unsupported part");
345 if (abstract_part
.Logic
== QueryPartLogic
.Prohibited
)
346 is_match
= ! is_match
;
351 public bool MatchesQuery (Query query
)
353 // We assume the root node never matches any query.
357 foreach (QueryPart part
in query
.Parts
) {
358 if (! MatchesQueryPart (part
))
365 private void RecursiveQueryCheck (ArrayList match_list
, Query query
)
367 if (MatchesQuery (query
))
368 match_list
.Add (this);
370 if (children
!= null)
371 foreach (FileModel file
in children
.Values
)
372 file
.RecursiveQueryCheck (match_list
, query
);
375 public ArrayList
GetMatchingDescendants (Query query
)
377 ArrayList match_list
;
378 match_list
= new ArrayList ();
379 RecursiveQueryCheck (match_list
, query
);