TemplateFactory.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //
  2. // System.Web.Compilation.TemplateFactory
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. //
  7. // (C) 2002 Ximian, Inc (http://www.ximian.com)
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Diagnostics;
  12. using System.IO;
  13. using System.Reflection;
  14. using System.Text;
  15. using System.Web.UI;
  16. namespace System.Web.Compilation
  17. {
  18. class TemplateFactory
  19. {
  20. internal class PageBuilder
  21. {
  22. private StringBuilder cscOptions;
  23. private string csFileName;
  24. private string className;
  25. public static char dirSeparator = Path.DirectorySeparatorChar;
  26. private static Hashtable cachedData = new Hashtable ();
  27. private static Random rnd_file = new Random ();
  28. private PageBuilder ()
  29. {
  30. }
  31. internal PageBuilder (string fileName)
  32. {
  33. csFileName = fileName;
  34. cscOptions = new StringBuilder ();
  35. cscOptions.Append ("--target library ");
  36. cscOptions.Append ("-L . ");
  37. AddReference ("corlib");
  38. AddReference ("System");
  39. AddReference ("System.Data");
  40. AddReference ("System.Web");
  41. AddReference ("System.Drawing");
  42. }
  43. internal Type Build ()
  44. {
  45. string dll;
  46. StreamReader st_file = new StreamReader (File.OpenRead (csFileName));
  47. StringReader file_content = new StringReader (st_file.ReadToEnd ());
  48. st_file.Close ();
  49. if (GetBuildOptions (file_content) == false)
  50. return null;
  51. dll = rnd_file.Next () + Path.GetFileName (csFileName).Replace (".cs", ".dll");
  52. if (Compile (csFileName, dll) == true){
  53. Assembly assembly = Assembly.LoadFrom (dll);
  54. Type type = assembly.GetType ("ASP." + className);
  55. return type;
  56. }
  57. return null;
  58. }
  59. private static bool RunProcess (string exe, string arguments, string output_file, string script_file)
  60. {
  61. Console.WriteLine ("{0} {1}", exe, arguments);
  62. Console.WriteLine ("Output goes to {0}", output_file);
  63. Console.WriteLine ("Script file is {0}", script_file);
  64. Process proc = new Process ();
  65. proc.StartInfo.FileName = exe;
  66. proc.StartInfo.Arguments = arguments;
  67. proc.StartInfo.UseShellExecute = false;
  68. proc.StartInfo.RedirectStandardOutput = true;
  69. proc.Start ();
  70. string poutput = proc.StandardOutput.ReadToEnd();
  71. proc.WaitForExit ();
  72. int result = proc.ExitCode;
  73. proc.Close ();
  74. StreamWriter cmd_output = new StreamWriter (File.Create (output_file));
  75. cmd_output.Write (poutput);
  76. cmd_output.Close ();
  77. StreamWriter bat_output = new StreamWriter (File.Create (script_file));
  78. bat_output.Write (exe + " " + arguments);
  79. bat_output.Close ();
  80. return (result == 0);
  81. }
  82. private bool GetBuildOptions (StringReader genCode)
  83. {
  84. string line;
  85. string dll;
  86. while ((line = genCode.ReadLine ()) != String.Empty) {
  87. if (line.StartsWith ("//<class ")){
  88. className = GetAttributeValue (line, "name");
  89. } else if (line.StartsWith ("//<compileandreference ")) {
  90. string src = GetAttributeValue (line, "src");
  91. dll = src.Replace (".cs", ".dll"); //FIXME
  92. //File.Delete (dll);
  93. if (Compile (src, dll) == false){
  94. Console.WriteLine ("Error compiling {0}. See the output file.", src);
  95. return false;
  96. }
  97. AddReference (dll.Replace (".dll", ""));
  98. } else if (line.StartsWith ("//<reference ")) {
  99. dll = GetAttributeValue (line, "dll");
  100. AddReference (dll);
  101. } else if (line.StartsWith ("//<compileroptions ")) {
  102. string options = GetAttributeValue (line, "options");
  103. cscOptions.Append (" " + options + " ");
  104. } else {
  105. Console.WriteLine ("This is the build option line i get:\n" + line);
  106. return false;
  107. }
  108. }
  109. return true;
  110. }
  111. private void AddReference (string reference)
  112. {
  113. string arg = String.Format ("/r:{0} ", reference);
  114. cscOptions.Append (arg);
  115. }
  116. private string GetAttributeValue (string line, string att)
  117. {
  118. string att_start = att + "=\"";
  119. int begin = line.IndexOf (att_start);
  120. int end = line.Substring (begin + att_start.Length).IndexOf ('"');
  121. if (begin == -1 || end == -1)
  122. throw new ApplicationException ("Error in reference option:\n" + line);
  123. return line.Substring (begin + att_start.Length, end);
  124. }
  125. private bool Compile (string csName, string dllName)
  126. {
  127. cscOptions.AppendFormat ("/out:{0} ", dllName);
  128. cscOptions.Append (csName);
  129. string cmdline = cscOptions.ToString ();
  130. string noext = csName.Replace (".cs", "");
  131. string output_file = noext + "_compilation_output.txt";
  132. string bat_file = noext + "_compile_command.bat";
  133. return RunProcess ("mcs", cmdline, output_file, bat_file);
  134. }
  135. }
  136. internal static string CompilationOutputFileName (string fileName)
  137. {
  138. string name = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".txt");
  139. return "output" + PageBuilder.dirSeparator + "output_from_compilation_" + name;
  140. }
  141. internal static string GeneratedXspFileName (string fileName)
  142. {
  143. string name = Path.GetFileName (fileName).Replace (".aspx", ".cs");
  144. return "output" + PageBuilder.dirSeparator + "xsp_" + name;
  145. }
  146. private TemplateFactory ()
  147. {
  148. }
  149. internal static Type GetTypeFromSource (string fileName)
  150. {
  151. PageBuilder builder = new PageBuilder (fileName);
  152. return builder.Build ();
  153. }
  154. }
  155. }