Parcourir la source

2003-01-07 Gonzalo Paniagua Javier <[email protected]>

	* AspComponentFoundry.cs: reworked to allow same prefix for multiple
	controls. You can register 1 assembly plus any number of user controls
	under the same prefix.

	* AspGenerator.cs: don't add duplicate 'using' for the same namespace.
	Hack to allow @Register access to assemblies in other places than bin
	directory.

svn path=/trunk/mcs/; revision=10225
Gonzalo Paniagua Javier il y a 23 ans
Parent
commit
1ccb7b53e5

+ 137 - 27
mcs/class/System.Web/System.Web.Compilation/AspComponentFoundry.cs

@@ -27,7 +27,7 @@ namespace System.Web.Compilation
 
 		public AspComponent MakeAspComponent (string foundryName, string componentName, Tag tag)
 		{
-			InternalFoundry foundry = foundries [foundryName] as InternalFoundry;
+			Foundry foundry = foundries [foundryName] as Foundry;
 			if (foundry == null)
 				throw new ApplicationException ("Foundry not found: " + foundryName);
 
@@ -38,17 +38,34 @@ namespace System.Web.Compilation
 						string assemblyName,
 						string nameSpace)
 		{
-			InternalFoundry foundry = new InternalFoundry (assemblyName, nameSpace, null);
-			foundries.Add (foundryName, foundry);
+			AssemblyFoundry foundry = new AssemblyFoundry (assemblyName, nameSpace);
+			InternalRegister (foundryName, foundry);
 		}
 
 		public void RegisterFoundry (string foundryName,
+						string tagName,
 						string assemblyName,
 						string nameSpace,
 						string typeName)
 		{
-			InternalFoundry foundry = new InternalFoundry (assemblyName, nameSpace, typeName);
-			foundries.Add (foundryName, foundry);
+			TagNameFoundry foundry = new TagNameFoundry (assemblyName, tagName, nameSpace, typeName);
+			InternalRegister (foundryName, foundry);
+		}
+
+		void InternalRegister (string foundryName, Foundry foundry)
+		{
+			object f = foundries [foundryName];
+			if (f is CompoundFoundry) {
+				((CompoundFoundry) f).Add (foundry);
+			} else if (f == null || (f is AssemblyFoundry && foundry is AssemblyFoundry)) {
+				// If more than 1 namespace/assembly specified, the last one is used.
+				foundries [foundryName] = foundry;
+			} else if (f != null) {
+				CompoundFoundry compound = new CompoundFoundry (foundryName);
+				compound.Add ((Foundry) f);
+				compound.Add (foundry);
+				foundries [foundryName] = compound;
+			}
 		}
 
 		public bool LookupFoundry (string foundryName)
@@ -56,51 +73,144 @@ namespace System.Web.Compilation
 			return foundries.Contains (foundryName);
 		}
 
-		class InternalFoundry
+		abstract class Foundry
+		{
+			public abstract Type GetType (string componentName);
+
+			public Assembly LoadAssembly (string assemblyName)
+			{
+				Assembly assembly = null;
+				try {
+					assembly = Assembly.LoadFrom (Path.GetFullPath (assemblyName));
+				} catch {
+					string partialName = assemblyName;
+					if (String.Compare (Path.GetExtension (partialName), ".dll", true) == 0)
+						partialName = Path.GetFileNameWithoutExtension (assemblyName);
+
+					assembly = Assembly.LoadWithPartialName (partialName);
+				}
+
+				if (assembly == null)
+					throw new ApplicationException ("Assembly not found:" + assemblyName);
+
+				return assembly;
+			}
+		}
+		
+
+		class TagNameFoundry : Foundry
 		{
-			string nameSpace;
 			string assemblyName;
+			string tagName;
+			string nameSpace;
 			string typeName;
-			Assembly assembly;
+			Type type;
 
-			public InternalFoundry (string assemblyName, string nameSpace, string typeName)
+			public TagNameFoundry (string assemblyName, string tagName, string nameSpace, string typeName)
 			{
 				this.assemblyName = assemblyName;
+				this.tagName = tagName;
 				this.nameSpace = nameSpace;
 				this.typeName = typeName;
-				assembly = null;
 			}
 
-			public Type GetType (string componentName)
+			public override Type GetType (string componentName)
 			{
-				EnsureAssembly ();
+				if (0 != String.Compare (componentName, tagName, true))
+					throw new ArgumentException (componentName + " != " + tagName);
+				
+				if (type != null)
+					return type;
+					
+				Assembly assembly = LoadAssembly (assemblyName);
+				type =  assembly.GetType (nameSpace + "." + typeName, true, true);
+				return type;
+			}
 
-				// For ascx files
-				if (typeName != null && 0 == String.Compare (componentName, typeName, true)) {
-					throw new ApplicationException ("Only type '" + typeName + "' allowed.");
-				} else if (typeName != null) {
-					componentName = typeName;
-				}
+			public string TagName {
+				get { return tagName; }
+			}
+		}
+
+		class AssemblyFoundry : Foundry
+		{
+			string nameSpace;
+			string assemblyName;
+			Assembly assembly;
+
+			public AssemblyFoundry (string assemblyName, string nameSpace)
+			{
+				this.assemblyName = assemblyName;
+				this.nameSpace = nameSpace;
+				assembly = null;
+			}
+
+			public override Type GetType (string componentName)
+			{
+				Assembly ass = EnsureAssembly (componentName);
 
-				return assembly.GetType (nameSpace + "." + componentName, true, true);
+				return ass.GetType (nameSpace + "." + componentName, true, true);
 			}
 			
-			private void EnsureAssembly ()
+			Assembly EnsureAssembly (string componentName)
 			{
 				if (assembly != null)
+					return assembly;
+
+				assembly = LoadAssembly (assemblyName);
+				return assembly;
+			}
+		}
+
+		class CompoundFoundry : Foundry
+		{
+			AssemblyFoundry assemblyFoundry;
+			Hashtable tagnames;
+			string tagPrefix;
+
+			public CompoundFoundry (string tagPrefix)
+			{
+				this.tagPrefix = tagPrefix;
+				tagnames = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
+							   CaseInsensitiveComparer.Default);
+			}
+
+			public void Add (Foundry foundry)
+			{
+				if (foundry is AssemblyFoundry) {
+					assemblyFoundry = (AssemblyFoundry) foundry;
 					return;
+				}
+				
+				TagNameFoundry tn = (TagNameFoundry) foundry;
+				string tagName = tn.TagName;
+				if (tagnames.Contains (tagName)) {
+					string msg = String.Format ("{0}:{1} already registered.", tagPrefix, tagName);
+					throw new ApplicationException (msg);
+				}
+				tagnames.Add (tagName, foundry);
+			}
 
-				try {
-					assembly = Assembly.LoadFrom (Path.GetFullPath (assemblyName));
-				} catch {
-					assembly = Assembly.LoadWithPartialName (assemblyName);
+			public override Type GetType (string componentName)
+			{
+				Type type = null;
+				if (assemblyFoundry != null) {
+					try {
+						type = assemblyFoundry.GetType (componentName);
+						return type;
+					} catch { }
 				}
 
-				if (assembly == null)
-					throw new ApplicationException ("Assembly not found:" + assemblyName);
+				Foundry foundry = tagnames [componentName] as Foundry;
+				if (foundry == null) {
+					string msg = String.Format ("Type {0} not registered for prefix {1}",
+								     componentName, tagPrefix);
+					throw new ApplicationException (msg);
+				}
+
+				return foundry.GetType (componentName);
 			}
 		}
-
 	}
 }
 

+ 21 - 5
mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs

@@ -416,6 +416,17 @@ class AspGenerator
 		set { context = value; }
 	}
 	
+	bool AddUsing (string nspace)
+	{
+		string _using = "using " + nspace + ";";
+		if (prolog.ToString ().IndexOf (_using) == -1) {
+			prolog.AppendFormat ("\t{0}\n", _using);
+			return true;
+		}
+
+		return false;
+	}
+
 	void AddInterface (Type type)
 	{
 		AddInterface (type.ToString ());
@@ -662,8 +673,14 @@ class AspGenerator
 			if (tag_name != "" || src != "")
 				throw new ApplicationException ("Invalid attributes for @ Register: " +
 								att.ToString ());
-			prolog.AppendFormat ("\tusing {0};\n", name_space);
+
+			AddUsing (name_space);
 			string dll = privateBinPath + Path.DirectorySeparatorChar + assembly_name + ".dll";
+			// Hack: it should use assembly.load semantics...
+			// may be when we don't run mcs as a external program...
+			if (!File.Exists (dll))
+				dll = assembly_name;
+
 			Foundry.RegisterFoundry (tag_prefix, dll, name_space);
 			AddReference (dll);
 			return;
@@ -681,9 +698,9 @@ class AspGenerator
 			UserControlData data = GenerateUserControl (src, Context);
 			switch (data.result) {
 			case UserControlResult.OK:
-				prolog.AppendFormat ("\tusing {0};\n", "ASP");
+				AddUsing ("ASP");
 				string dll = "output" + Path.DirectorySeparatorChar + data.assemblyName + ".dll";
-				Foundry.RegisterFoundry (tag_prefix, data.assemblyName, "ASP", data.className);
+				Foundry.RegisterFoundry (tag_prefix, tag_name, data.assemblyName, "ASP", data.className);
 				AddReference (data.assemblyName);
 				break;
 			case UserControlResult.FileNotFound:
@@ -742,8 +759,7 @@ class AspGenerator
 				throw new ApplicationException ("Wrong syntax in Import directive.");
 
 			string _using = "using " + value + ";";
-			if (prolog.ToString ().IndexOf (_using) == -1) {
-				prolog.AppendFormat ("\t{0}\n", _using);
+			if (AddUsing (value) == true) {
 				string imports = Options ["Import"] as string;
 				if (imports == null) {
 					imports = value;

+ 10 - 0
mcs/class/System.Web/System.Web.Compilation/ChangeLog

@@ -1,3 +1,13 @@
+2003-01-07  Gonzalo Paniagua Javier <[email protected]>
+
+	* AspComponentFoundry.cs: reworked to allow same prefix for multiple
+	controls. You can register 1 assembly plus any number of user controls
+	under the same prefix.
+
+	* AspGenerator.cs: don't add duplicate 'using' for the same namespace.
+	Hack to allow @Register access to assemblies in other places than bin
+	directory.
+
 2003-01-06  Gonzalo Paniagua Javier <[email protected]>
 
 	* AspElements.cs: added 'codebehind' attribute for page, control and