Merge the recent changes from HEAD onto the branch
[beagle.git] / bludgeon / Toolbox.cs
blob1f85d01eb3f23a9706e6b12e6e25b06294800ed1
1 using System;
2 using System.Collections;
3 using System.Reflection;
5 using Beagle.Util;
7 namespace Bludgeon {
9 public class Toolbox {
11 private class Pair {
12 public HammerAttribute Attribute;
13 public Type Type;
15 public IHammer CreateInstance () {
16 return Activator.CreateInstance (Type) as IHammer;
20 static ArrayList all_pairs = new ArrayList ();
21 static Hashtable pairs_by_name = new Hashtable ();
23 /////////////////////////////////////////////////////
25 private Toolbox () { } // This is a static class
27 static Toolbox ()
29 LoadAllPairs (Assembly.GetExecutingAssembly ());
32 // These are strings
33 static public ICollection HammerNames {
34 get { return pairs_by_name.Keys; }
37 /////////////////////////////////////////////////////
39 private class MixedHammer : IHammer {
40 Random random = new Random ();
41 ArrayList hammers = new ArrayList ();
43 public void Add (IHammer hammer)
45 hammers.Add (hammer);
48 public int Count {
49 get { return hammers.Count; }
52 public bool HammerOnce (DirectoryObject dir, EventTracker tracker)
54 // We randomly pick an IHammer, and call HammerOnce on it.
55 // If it returns false, we try the next IHammer until we
56 // find one that returns true or until we've exhausted
57 // all possibilities.
58 int i;
59 i = random.Next (hammers.Count);
61 for (int j = 0; j < hammers.Count; ++j) {
62 int k = (i + j) % hammers.Count;
63 IHammer hammer;
64 hammer = hammers [k] as IHammer;
65 if (hammer.HammerOnce (dir, tracker))
66 return true;
69 return false;
73 static private IHammer GetMixedHammer (string name)
75 string [] parts;
76 parts = name.Split (',');
78 MixedHammer mixed;
79 mixed = new MixedHammer ();
80 foreach (string part in parts) {
81 IHammer hammer;
83 if (part.IndexOf ('*') != -1) {
84 foreach (IHammer match in GetMatchingHammers (part))
85 mixed.Add (match);
86 continue;
89 hammer = GetHammer (part);
90 if (hammer != null)
91 mixed.Add (hammer);
94 return mixed.Count > 0 ? mixed : null;
97 static public IHammer GetHammer (string name)
99 if (name.IndexOf (',') != -1 || name.IndexOf ('*') != -1)
100 return GetMixedHammer (name);
102 Pair pair;
103 pair = pairs_by_name [name] as Pair;
104 if (pair == null)
105 return null; // should probably throw exception
107 return pair.CreateInstance ();
110 static public ICollection GetMatchingHammers (string pattern)
112 ArrayList matches;
113 matches = new ArrayList ();
115 foreach (Pair pair in all_pairs)
116 if (StringFu.GlobMatch (pattern, pair.Attribute.Name))
117 matches.Add (pair.CreateInstance ());
119 return matches;
122 /////////////////////////////////////////////////////
124 static private void LoadAllPairs (Assembly assembly)
126 foreach (Type type in assembly.GetTypes ()) { // assembly.GetTypes() is very bad.
127 if (type.GetInterface (typeof (IHammer).ToString ()) == null)
128 continue;
130 foreach (HammerAttribute attr in ReflectionFu.ScanTypeForAttribute (type, typeof (HammerAttribute))) {
131 Pair pair;
132 pair = new Pair ();
133 pair.Attribute = attr;
134 pair.Type = type;
136 all_pairs.Add (pair);
137 pairs_by_name [pair.Attribute.Name] = pair;
139 break;