PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Microsoft.AspNet.SignalR.Utils/Commands/GenerateHubProxyCommand.cs

https://github.com/mip1983/SignalR
C# | 232 lines | 188 code | 42 blank | 2 comment | 17 complexity | 156c80de19bc7344833c488a9e091a6a MD5 | raw file
Possible License(s): Apache-2.0, CC-BY-SA-3.0
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information.
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Reflection;
  8. using System.Text.RegularExpressions;
  9. namespace Microsoft.AspNet.SignalR.Utils
  10. {
  11. internal class GenerateHubProxyCommand : Command
  12. {
  13. public GenerateHubProxyCommand(Action<string> info, Action<string> success, Action<string> warning, Action<string> error)
  14. : base(info, success, warning, error)
  15. {
  16. }
  17. public override string DisplayName
  18. {
  19. get { return "Generate Hub Proxy"; }
  20. }
  21. public override string Help
  22. {
  23. get { return "Generates Hub proxy JavaScript files for server Hub classes."; }
  24. }
  25. public override string[] Names
  26. {
  27. get { return new[] { "ghp" }; }
  28. }
  29. public override void Execute(string[] args)
  30. {
  31. bool absolute = false;
  32. string path = null;
  33. string outputPath = null;
  34. string url = null;
  35. ParseArguments(args, out url, out absolute, out path, out outputPath);
  36. if (String.IsNullOrEmpty(outputPath))
  37. {
  38. outputPath = ".";
  39. }
  40. outputPath = Path.GetFullPath(outputPath);
  41. if (String.IsNullOrWhiteSpace(Path.GetExtension(outputPath)))
  42. {
  43. outputPath = Path.Combine(outputPath, "server.js");
  44. }
  45. if (!String.IsNullOrEmpty(url) && String.IsNullOrEmpty(path))
  46. {
  47. OutputHubsFromUrl(url, outputPath, absolute);
  48. }
  49. else
  50. {
  51. OutputHubs(path, url, outputPath);
  52. }
  53. }
  54. private void OutputHubs(string path, string url, string outputPath)
  55. {
  56. path = path ?? Directory.GetCurrentDirectory();
  57. url = url ?? "/signalr";
  58. var assemblies = Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories);
  59. var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
  60. Info(String.Format("Creating temp directory {0}", tempPath));
  61. Directory.CreateDirectory(tempPath);
  62. // Copy all assemblies to temp
  63. foreach (var assemblyPath in assemblies)
  64. {
  65. Copy(assemblyPath, tempPath);
  66. }
  67. Copy(typeof(Program).Assembly.Location, tempPath);
  68. var setup = new AppDomainSetup
  69. {
  70. ApplicationBase = tempPath
  71. };
  72. var domain = AppDomain.CreateDomain("hubs", AppDomain.CurrentDomain.Evidence, setup);
  73. var generator = (JavaScriptGenerator)domain.CreateInstanceAndUnwrap(typeof(Program).Assembly.FullName,
  74. typeof(JavaScriptGenerator).FullName);
  75. var js = generator.GenerateProxy(path, url);
  76. Generate(outputPath, js);
  77. }
  78. private static void Copy(string sourcePath, string destinationPath)
  79. {
  80. string target = Path.Combine(destinationPath, Path.GetFileName(sourcePath));
  81. File.Copy(sourcePath, target, overwrite: true);
  82. }
  83. private static void OutputHubsFromUrl(string url, string outputPath, bool absolute)
  84. {
  85. string baseUrl = null;
  86. if (!url.EndsWith("/"))
  87. {
  88. url += "/";
  89. }
  90. if (!url.EndsWith("signalr"))
  91. {
  92. url += "signalr/";
  93. }
  94. baseUrl = url;
  95. if (!url.EndsWith("hubs", StringComparison.OrdinalIgnoreCase))
  96. {
  97. url += "hubs";
  98. }
  99. var uri = new Uri(url);
  100. var wc = new WebClient();
  101. string js = wc.DownloadString(uri);
  102. if (absolute)
  103. {
  104. js = Regex.Replace(js, @"=(\w+)\(""(.*?/signalr)""\)", m =>
  105. {
  106. return "=" + m.Groups[1].Value + "(\"" + baseUrl + "\")";
  107. });
  108. }
  109. Generate(outputPath, js);
  110. }
  111. private static void Generate(string outputPath, string js)
  112. {
  113. File.WriteAllText(outputPath, js);
  114. }
  115. private static void ParseArguments(string[] args, out string url, out bool absolute, out string path, out string outputPath)
  116. {
  117. absolute = false;
  118. path = null;
  119. url = null;
  120. outputPath = null;
  121. foreach (var a in args)
  122. {
  123. if (!a.StartsWith("/"))
  124. {
  125. continue;
  126. }
  127. KeyValuePair<string, string> arg = ParseArg(a);
  128. switch (arg.Key)
  129. {
  130. case "absolute":
  131. absolute = true;
  132. break;
  133. case "path":
  134. path = arg.Value;
  135. break;
  136. case "url":
  137. url = arg.Value;
  138. break;
  139. case "o":
  140. outputPath = arg.Value;
  141. break;
  142. default:
  143. break;
  144. }
  145. }
  146. }
  147. private static KeyValuePair<string, string> ParseArg(string arg)
  148. {
  149. arg = arg.Substring(1);
  150. if (arg.Contains(":"))
  151. {
  152. var splitIndex = arg.IndexOf(':');
  153. var key = arg.Substring(0, splitIndex).Trim();
  154. var value = arg.Substring(splitIndex + 1).Trim();
  155. return new KeyValuePair<string, string>(key, value);
  156. }
  157. return new KeyValuePair<string, string>(arg.Trim(), null);
  158. }
  159. public class JavaScriptGenerator : MarshalByRefObject
  160. {
  161. public string GenerateProxy(string path, string url)
  162. {
  163. foreach (var assemblyPath in Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories))
  164. {
  165. Assembly.Load(AssemblyName.GetAssemblyName(assemblyPath));
  166. }
  167. var signalrAssembly = (from a in AppDomain.CurrentDomain.GetAssemblies()
  168. where a.GetName().Name.Equals("Microsoft.AspNet.SignalR.Core", StringComparison.OrdinalIgnoreCase)
  169. select a).FirstOrDefault();
  170. if (signalrAssembly == null)
  171. {
  172. return null;
  173. }
  174. Type resolverType = signalrAssembly.GetType("Microsoft.AspNet.SignalR.DefaultDependencyResolver");
  175. if (resolverType == null)
  176. {
  177. return null;
  178. }
  179. Type proxyGeneratorType = signalrAssembly.GetType("Microsoft.AspNet.SignalR.Hubs.DefaultJavaScriptProxyGenerator");
  180. if (proxyGeneratorType == null)
  181. {
  182. return null;
  183. }
  184. object resolver = Activator.CreateInstance(resolverType);
  185. dynamic proxyGenerator = Activator.CreateInstance(proxyGeneratorType, resolver);
  186. return proxyGenerator.GenerateProxy(url, true);
  187. }
  188. }
  189. }
  190. }