merge from trunk revisions 58933, 58935, 58936
[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                         foundries = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
44                                                    CaseInsensitiveComparer.DefaultInvariant);
45
46                         Assembly sw = typeof (AspComponentFoundry).Assembly;
47                         RegisterFoundry ("asp", sw, "System.Web.UI.WebControls");
48                         RegisterFoundry ("", "object", typeof (System.Web.UI.ObjectTag));
49                 }
50
51                 public Type GetComponentType (string foundryName, string tag)
52                 {
53                         Foundry foundry = foundries [foundryName] as Foundry;
54                         if (foundry == null)
55                                 return null;
56
57                         return foundry.GetType (tag);
58                 }
59
60                 public void RegisterFoundry (string foundryName,
61                                                 Assembly assembly,
62                                                 string nameSpace)
63                 {
64                         AssemblyFoundry foundry = new AssemblyFoundry (assembly, nameSpace);
65                         InternalRegister (foundryName, foundry);
66                 }
67
68                 public void RegisterFoundry (string foundryName,
69                                                 string tagName,
70                                                 Type type)
71                 {
72                         TagNameFoundry foundry = new TagNameFoundry (tagName, type);
73                         InternalRegister (foundryName, foundry);
74                 }
75
76                 void InternalRegister (string foundryName, Foundry foundry)
77                 {
78                         object f = foundries [foundryName];
79                         if (f is CompoundFoundry) {
80                                 ((CompoundFoundry) f).Add (foundry);
81                         } else if (f == null || (f is AssemblyFoundry && foundry is AssemblyFoundry)) {
82                                 // If more than 1 namespace/assembly specified, the last one is used.
83                                 foundries [foundryName] = foundry;
84                         } else if (f != null) {
85                                 CompoundFoundry compound = new CompoundFoundry (foundryName);
86                                 compound.Add ((Foundry) f);
87                                 compound.Add (foundry);
88                                 foundries [foundryName] = compound;
89                         }
90                 }
91
92                 public bool LookupFoundry (string foundryName)
93                 {
94                         return foundries.Contains (foundryName);
95                 }
96
97                 abstract class Foundry
98                 {
99                         public abstract Type GetType (string componentName);
100                 }
101                 
102
103                 class TagNameFoundry : Foundry
104                 {
105                         string tagName;
106                         Type type;
107
108                         public TagNameFoundry (string tagName, Type type)
109                         {
110                                 this.tagName = tagName;
111                                 this.type = type;
112                         }
113
114                         public override Type GetType (string componentName)
115                         {
116                                 if (0 != String.Compare (componentName, tagName, true))
117                                         return null;
118                                 
119                                 return type;
120                         }
121
122                         public string TagName {
123                                 get { return tagName; }
124                         }
125                 }
126
127                 class AssemblyFoundry : Foundry
128                 {
129                         string nameSpace;
130                         Assembly assembly;
131
132                         public AssemblyFoundry (Assembly assembly, string nameSpace)
133                         {
134                                 this.assembly = assembly;
135                                 this.nameSpace = nameSpace;
136                         }
137
138                         public override Type GetType (string componentName)
139                         {
140                                 return assembly.GetType (nameSpace + "." + componentName, true, true);
141                         }
142                 }
143
144                 class CompoundFoundry : Foundry
145                 {
146                         AssemblyFoundry assemblyFoundry;
147                         Hashtable tagnames;
148                         string tagPrefix;
149
150                         public CompoundFoundry (string tagPrefix)
151                         {
152                                 this.tagPrefix = tagPrefix;
153                                 tagnames = new Hashtable (CaseInsensitiveHashCodeProvider.DefaultInvariant,
154                                                            CaseInsensitiveComparer.DefaultInvariant);
155                         }
156
157                         public void Add (Foundry foundry)
158                         {
159                                 if (foundry is AssemblyFoundry) {
160                                         assemblyFoundry = (AssemblyFoundry) foundry;
161                                         return;
162                                 }
163                                 
164                                 TagNameFoundry tn = (TagNameFoundry) foundry;
165                                 string tagName = tn.TagName;
166                                 if (tagnames.Contains (tagName)) {
167                                         string msg = String.Format ("{0}:{1} already registered.", tagPrefix, tagName);
168                                         throw new ApplicationException (msg);
169                                 }
170                                 tagnames.Add (tagName, foundry);
171                         }
172
173                         public override Type GetType (string componentName)
174                         {
175                                 Type type = null;
176                                 Foundry foundry = tagnames [componentName] as Foundry;
177                                 if (foundry != null)
178                                         return foundry.GetType (componentName);
179
180                                 if (assemblyFoundry != null) {
181                                         try {
182                                                 type = assemblyFoundry.GetType (componentName);
183                                                 return type;
184                                         } catch { }
185                                 }
186
187                                 string msg = String.Format ("Type {0} not registered for prefix {1}",
188                                                                      componentName, tagPrefix);
189                                 throw new ApplicationException (msg);
190                         }
191                 }
192         }
193 }
194