TemplateFactory.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. AddReference ("System.Data");
  37. AddReference ("System.Web");
  38. AddReference ("System.Drawing");
  39. }
  40. internal Type Build ()
  41. {
  42. string dll;
  43. StreamReader st_file = new StreamReader (File.OpenRead (csFileName));
  44. StringReader file_content = new StringReader (st_file.ReadToEnd ());
  45. st_file.Close ();
  46. if (GetBuildOptions (file_content) == false)
  47. return null;
  48. dll = rnd_file.Next () + Path.GetFileName (csFileName).Replace (".cs", ".dll");
  49. if (Compile (csFileName, dll) == true){
  50. Assembly assembly = Assembly.LoadFrom (dll);
  51. Type type = assembly.GetType ("ASP." + className);
  52. return type;
  53. }
  54. return null;
  55. }
  56. private static bool RunProcess (string exe, string arguments, string output_file, string script_file)
  57. {
  58. Console.WriteLine ("{0} {1}", exe, arguments);
  59. Console.WriteLine ("Output goes to {0}", output_file);
  60. Console.WriteLine ("Script file is {0}", script_file);
  61. Process proc = new Process ();
  62. proc.StartInfo.FileName = exe;
  63. proc.StartInfo.Arguments = arguments;
  64. proc.StartInfo.UseShellExecute = false;
  65. proc.StartInfo.RedirectStandardOutput = true;
  66. proc.Start ();
  67. string poutput = proc.StandardOutput.ReadToEnd();
  68. proc.WaitForExit ();
  69. int result = proc.ExitCode;
  70. proc.Close ();
  71. StreamWriter cmd_output = new StreamWriter (File.Create (output_file));
  72. cmd_output.Write (poutput);
  73. cmd_output.Close ();
  74. StreamWriter bat_output = new StreamWriter (File.Create (script_file));
  75. bat_output.Write (exe + " " + arguments);
  76. bat_output.Close ();
  77. return (result == 0);
  78. }
  79. private bool GetBuildOptions (StringReader genCode)
  80. {
  81. string line;
  82. string dll;
  83. while ((line = genCode.ReadLine ()) != String.Empty) {
  84. if (line.StartsWith ("//<class ")){
  85. className = GetAttributeValue (line, "name");
  86. } else if (line.StartsWith ("//<compileandreference ")) {
  87. string src = GetAttributeValue (line, "src");
  88. dll = src.Replace (".cs", ".dll"); //FIXME
  89. //File.Delete (dll);
  90. if (Compile (src, dll) == false){
  91. Console.WriteLine ("Error compiling {0}. See the output file.", src);
  92. return false;
  93. }
  94. AddReference (dll.Replace (".dll", ""));
  95. } else if (line.StartsWith ("//<reference ")) {
  96. dll = GetAttributeValue (line, "dll");
  97. AddReference (dll);
  98. } else if (line.StartsWith ("//<compileroptions ")) {
  99. string options = GetAttributeValue (line, "options");
  100. cscOptions.Append (" " + options + " ");
  101. } else {
  102. Console.WriteLine ("This is the build option line i get:\n" + line);
  103. return false;
  104. }
  105. }
  106. return true;
  107. }
  108. private void AddReference (string reference)
  109. {
  110. string arg = String.Format ("/r:{0}.dll ", reference);
  111. cscOptions.Append (arg);
  112. }
  113. private string GetAttributeValue (string line, string att)
  114. {
  115. string att_start = att + "=\"";
  116. int begin = line.IndexOf (att_start);
  117. int end = line.Substring (begin + att_start.Length).IndexOf ('"');
  118. if (begin == -1 || end == -1)
  119. throw new ApplicationException ("Error in reference option:\n" + line);
  120. return line.Substring (begin + att_start.Length, end);
  121. }
  122. private bool Compile (string csName, string dllName)
  123. {
  124. cscOptions.AppendFormat ("/out:{0} ", dllName);
  125. cscOptions.Append (csName);
  126. string cmdline = cscOptions.ToString ();
  127. string noext = csName.Replace (".cs", "");
  128. string output_file = noext + "_compilation_output.txt";
  129. string bat_file = noext + "_compile_command.bat";
  130. return RunProcess ("mcs", cmdline, output_file, bat_file);
  131. }
  132. }
  133. internal static string CompilationOutputFileName (string fileName)
  134. {
  135. string name = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".txt");
  136. return "output" + PageBuilder.dirSeparator + "output_from_compilation_" + name;
  137. }
  138. internal static string GeneratedXspFileName (string fileName)
  139. {
  140. string name = Path.GetFileName (fileName).Replace (".aspx", ".cs");
  141. return "output" + PageBuilder.dirSeparator + "xsp_" + name;
  142. }
  143. private TemplateFactory ()
  144. {
  145. }
  146. internal static Type GetTypeFromSource (string fileName)
  147. {
  148. PageBuilder builder = new PageBuilder (fileName);
  149. return builder.Build ();
  150. }
  151. }
  152. }