TemplateFactory.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 fileName;
  24. private string csFileName;
  25. private string className;
  26. public static char dirSeparator = Path.DirectorySeparatorChar;
  27. private static Hashtable cachedData = new Hashtable ();
  28. private static Random rnd_file = new Random ();
  29. private PageBuilder ()
  30. {
  31. }
  32. internal PageBuilder (string fileName)
  33. {
  34. this.fileName = fileName;
  35. csFileName = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".cs");
  36. cscOptions = new StringBuilder ();
  37. cscOptions.Append ("--target library ");
  38. cscOptions.Append ("-L . ");
  39. AddReference ("corlib");
  40. AddReference ("System");
  41. AddReference ("System.Data");
  42. AddReference ("System.Web");
  43. AddReference ("System.Drawing");
  44. }
  45. internal Type Build ()
  46. {
  47. string dll;
  48. if (Xsp (fileName, csFileName) == false){
  49. Console.WriteLine ("Error running xsp. " +
  50. "Take a look at the output file.");
  51. return null;
  52. }
  53. StreamReader st_file = new StreamReader (File.OpenRead ("output" +
  54. dirSeparator +
  55. csFileName));
  56. StringReader file_content = new StringReader (st_file.ReadToEnd ());
  57. st_file.Close ();
  58. if (GetBuildOptions (file_content) == false)
  59. return null;
  60. dll = "output" + dirSeparator;
  61. dll += rnd_file.Next () + Path.GetFileName (fileName).Replace (".aspx", ".dll");
  62. if (Compile (csFileName, dll) == true){
  63. Assembly assembly = Assembly.LoadFrom (dll);
  64. Type type = assembly.GetType ("ASP." + className);
  65. return type;
  66. }
  67. return null;
  68. }
  69. private static bool Xsp (string fileName, string csFileName)
  70. {
  71. return RunProcess ("mono",
  72. "xsp.exe " + fileName,
  73. GeneratedXspFileName (fileName),
  74. "output" + dirSeparator + "xsp_" + Path.GetFileName (fileName) +
  75. ".sh");
  76. }
  77. private static bool RunProcess (string exe, string arguments, string output_file, string script_file)
  78. {
  79. Console.WriteLine ("{0} {1}", exe, arguments);
  80. Console.WriteLine ("Output goes to {0}", output_file);
  81. Console.WriteLine ("Script file is {0}", script_file);
  82. Process proc = new Process ();
  83. proc.StartInfo.FileName = "redirector.sh";
  84. proc.StartInfo.Arguments = exe + " " + output_file + " " + arguments;
  85. proc.Start ();
  86. proc.WaitForExit ();
  87. int result = proc.ExitCode;
  88. proc.Close ();
  89. StreamWriter bat_output = new StreamWriter (File.Create (script_file));
  90. bat_output.Write ("redirector.sh" + " " + exe + " " + output_file + " " + arguments);
  91. bat_output.Close ();
  92. /*
  93. * Use this code when redirection works properly
  94. *
  95. proc.StartInfo.FileName = exe;
  96. proc.StartInfo.Arguments = arguments;
  97. proc.StartInfo.UseShellExecute = false;
  98. proc.StartInfo.RedirectStandardOutput = true;
  99. proc.Start ();
  100. string poutput = proc.StandardOutput.ReadToEnd();
  101. proc.WaitForExit ();
  102. int result = proc.ExitCode;
  103. proc.Close ();
  104. StreamWriter cmd_output = new StreamWriter (File.Create (output_file));
  105. cmd_output.Write (poutput);
  106. cmd_output.Close ();
  107. StreamWriter bat_output = new StreamWriter (File.Create (script_file));
  108. bat_output.Write (exe + " " + arguments);
  109. bat_output.Close ();
  110. */
  111. return (result == 0);
  112. }
  113. private bool GetBuildOptions (StringReader genCode)
  114. {
  115. string line;
  116. string dll;
  117. while ((line = genCode.ReadLine ()) != String.Empty) {
  118. if (line.StartsWith ("//<class ")){
  119. className = GetAttributeValue (line, "name");
  120. } else if (line.StartsWith ("//<compileandreference ")) {
  121. string src = GetAttributeValue (line, "src");
  122. dll = src.Replace (".cs", ".dll"); //FIXME
  123. //File.Delete (dll);
  124. if (Compile (src, dll) == false){
  125. Console.WriteLine ("Error compiling {0}. See the output file.", src);
  126. return false;
  127. }
  128. AddReference (dll.Replace (".dll", ""));
  129. } else if (line.StartsWith ("//<reference ")) {
  130. dll = GetAttributeValue (line, "dll");
  131. AddReference (dll);
  132. } else if (line.StartsWith ("//<compileroptions ")) {
  133. string options = GetAttributeValue (line, "options");
  134. cscOptions.Append (" " + options + " ");
  135. } else {
  136. Console.WriteLine ("This is the build option line i get:\n" + line);
  137. return false;
  138. }
  139. }
  140. return true;
  141. }
  142. private void AddReference (string reference)
  143. {
  144. string arg = String.Format ("/r:{0} ", reference);
  145. cscOptions.Append (arg);
  146. }
  147. private string GetAttributeValue (string line, string att)
  148. {
  149. string att_start = att + "=\"";
  150. int begin = line.IndexOf (att_start);
  151. int end = line.Substring (begin + att_start.Length).IndexOf ('"');
  152. if (begin == -1 || end == -1)
  153. throw new ApplicationException ("Error in reference option:\n" + line);
  154. return line.Substring (begin + att_start.Length, end);
  155. }
  156. private bool Compile (string csName, string dllName)
  157. {
  158. cscOptions.AppendFormat ("/out:{0} ", dllName);
  159. cscOptions.Append ("output" + dirSeparator + csName);
  160. string cmdline = cscOptions.ToString ();
  161. string noext = csName.Replace (".cs", "");
  162. string output_file = "output" + dirSeparator + "output_from_compilation_" + noext + ".txt";
  163. string bat_file = "output" + dirSeparator + "last_compilation_" + noext + ".bat";
  164. return RunProcess ("mcs", cmdline, output_file, bat_file);
  165. }
  166. }
  167. internal static string CompilationOutputFileName (string fileName)
  168. {
  169. string name = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".txt");
  170. return "output" + PageBuilder.dirSeparator + "output_from_compilation_" + name;
  171. }
  172. internal static string GeneratedXspFileName (string fileName)
  173. {
  174. string name = Path.GetFileName (fileName).Replace (".aspx", ".cs");
  175. return "output" + PageBuilder.dirSeparator + "xsp_" + name;
  176. }
  177. private TemplateFactory ()
  178. {
  179. }
  180. internal static Type GetTypeFromSource (string fileName)
  181. {
  182. PageBuilder builder = new PageBuilder (fileName);
  183. return builder.Build ();
  184. }
  185. }
  186. }