New test.
[mono.git] / mcs / class / System.Web / System.Web.Compilation / AspComponentFoundry.cs
1 //
2 // System.Web.Compilation.AspComponentFoundry
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.Collections;
32 using System.IO;
33 using System.Reflection;
34
35 namespace System.Web.Compilation
36 {
37         internal class AspComponentFoundry
38         {
39                 private Hashtable foundries;
40
41                 public AspComponentFoundry ()
42                 {
43 #if NET_2_0
44                         foundries = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
45 #else
46                         foundries = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
47                                                    CaseInsensitiveComparer.DefaultInvariant);
48 #endif
49
50                         Assembly sw = typeof (AspComponentFoundry).Assembly;
51                         RegisterFoundry ("asp", sw, "System.Web.UI.WebControls");
52                         RegisterFoundry ("", "object", typeof (System.Web.UI.ObjectTag));
53                 }
54
55                 public Type GetComponentType (string foundryName, string tag)
56                 {
57                         Foundry foundry = foundries [foundryName] as Foundry;
58                         if (foundry == null)
59                                 return null;
60
61                         return foundry.GetType (tag);
62                 }
63
64                 public void RegisterFoundry (string foundryName,
65                                                 Assembly assembly,
66                                                 string nameSpace)
67                 {
68                         AssemblyFoundry foundry = new AssemblyFoundry (assembly, nameSpace);
69                         InternalRegister (foundryName, foundry);
70                 }
71
72                 public void RegisterFoundry (string foundryName,
73                                                 string tagName,
74                                                 Type type)
75                 {
76                         TagNameFoundry foundry = new TagNameFoundry (tagName, type);
77                         InternalRegister (foundryName, foundry);
78                 }
79
80                 void InternalRegister (string foundryName, Foundry foundry)
81                 {
82                         object f = foundries [foundryName];
83                         if (f is CompoundFoundry) {
84                                 ((CompoundFoundry) f).Add (foundry);
85                         } else if (f == null || (f is AssemblyFoundry && foundry is AssemblyFoundry)) {
86                                 // If more than 1 namespace/assembly specified, the last one is used.
87                                 foundries [foundryName] = foundry;
88                         } else if (f != null) {
89                                 CompoundFoundry compound = new CompoundFoundry (foundryName);
90                                 compound.Add ((Foundry) f);
91                                 compound.Add (foundry);
92                                 foundries [foundryName] = compound;
93                         }
94                 }
95
96                 public bool LookupFoundry (string foundryName)
97                 {
98                         return foundries.Contains (foundryName);
99                 }
100
101                 abstract class Foundry
102                 {
103                         public abstract Type GetType (string componentName);
104                 }
105                 
106
107                 class TagNameFoundry : Foundry
108                 {
109                         string tagName;
110                         Type type;
111
112                         public TagNameFoundry (string tagName, Type type)
113                         {
114                                 this.tagName = tagName;
115                                 this.type = type;
116                         }
117
118                         public override Type GetType (string componentName)
119                         {
120                                 if (0 != String.Compare (componentName, tagName, true))
121                                         return null;
122                                 
123                                 return type;
124                         }
125
126                         public string TagName {
127                                 get { return tagName; }
128                         }
129                 }
130
131                 class AssemblyFoundry : Foundry
132                 {
133                         string nameSpace;
134                         Assembly assembly;
135
136                         public AssemblyFoundry (Assembly assembly, string nameSpace)
137                         {
138                                 this.assembly = assembly;
139                                 this.nameSpace = nameSpace;
140                         }
141
142                         public override Type GetType (string componentName)
143                         {
144                                 return assembly.GetType (nameSpace + "." + componentName, true, true);
145                         }
146                 }
147
148                 class CompoundFoundry : Foundry
149                 {
150                         AssemblyFoundry assemblyFoundry;
151                         Hashtable tagnames;
152                         string tagPrefix;
153
154                         public CompoundFoundry (string tagPrefix)
155                         {
156                                 this.tagPrefix = tagPrefix;
157 #if NET_2_0
158                                 tagnames = new Hashtable (StringComparer.InvariantCultureIgnoreCase);
159 #else
160                                 tagnames = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
161                                                           CaseInsensitiveComparer.DefaultInvariant);
162 #endif
163                         }
164
165                         public void Add (Foundry foundry)
166                         {
167                                 if (foundry is AssemblyFoundry) {
168                                         assemblyFoundry = (AssemblyFoundry) foundry;
169                                         return;
170                                 }
171                                 
172                                 TagNameFoundry tn = (TagNameFoundry) foundry;
173                                 string tagName = tn.TagName;
174                                 if (tagnames.Contains (tagName)) {
175                                         string msg = String.Format ("{0}:{1} already registered.", tagPrefix, tagName);
176                                         throw new ApplicationException (msg);
177                                 }
178                                 tagnames.Add (tagName, foundry);
179                         }
180
181                         public override Type GetType (string componentName)
182                         {
183                                 Type type = null;
184                                 Foundry foundry = tagnames [componentName] as Foundry;
185                                 if (foundry != null)
186                                         return foundry.GetType (componentName);
187
188                                 if (assemblyFoundry != null) {
189                                         try {
190                                                 type = assemblyFoundry.GetType (componentName);
191                                                 return type;
192                                         } catch { }
193                                 }
194
195                                 string msg = String.Format ("Type {0} not registered for prefix {1}",
196                                                                      componentName, tagPrefix);
197                                 throw new ApplicationException (msg);
198                         }
199                 }
200         }
201 }
202