PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System.Design/System.ComponentModel.Design.Serialization/DesignerSerializationManager.cs

https://bitbucket.org/danipen/mono
C# | 510 lines | 379 code | 87 blank | 44 comment | 117 complexity | 4452c9f63d475423153ee0b93176f2c3 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //
  2. // System.ComponentModel.Design.Serialization.DesignerSerializationManager
  3. //
  4. // Authors:
  5. // Ivan N. Zlatev (contact i-nZ.net)
  6. //
  7. // (C) 2007 Ivan N. Zlatev
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. #if NET_2_0
  29. using System;
  30. using System.Collections;
  31. using System.Collections.Generic;
  32. using System.Reflection;
  33. using System.ComponentModel;
  34. using System.ComponentModel.Design;
  35. namespace System.ComponentModel.Design.Serialization
  36. {
  37. public class DesignerSerializationManager : IDesignerSerializationManager, IServiceProvider
  38. {
  39. private class Session : IDisposable
  40. {
  41. private DesignerSerializationManager _manager;
  42. public Session (DesignerSerializationManager manager)
  43. {
  44. _manager = manager;
  45. }
  46. public void Dispose ()
  47. {
  48. _manager.OnSessionDisposed (EventArgs.Empty);
  49. }
  50. }
  51. public DesignerSerializationManager () : this (null)
  52. {
  53. }
  54. // This constructor sets the PreserveNames and ValidateRecycledTypes properties to true.
  55. //
  56. public DesignerSerializationManager (IServiceProvider provider)
  57. {
  58. _serviceProvider = provider;
  59. _preserveNames = true;
  60. _validateRecycledTypes = true;
  61. }
  62. private IServiceProvider _serviceProvider;
  63. private bool _preserveNames = false;
  64. private bool _validateRecycledTypes = false;
  65. private bool _recycleInstances = false;
  66. private IContainer _designerContainer = null;
  67. private object _propertyProvider = null;
  68. private Session _session = null;
  69. private ArrayList _errors = null;
  70. private List <IDesignerSerializationProvider> _serializationProviders;
  71. private Dictionary <Type, object> _serializersCache = null; // componentType - serializer instance
  72. private Dictionary <string, object> _instancesByNameCache = null; // name - instance
  73. private Dictionary <object, string> _instancesByValueCache = null; // instance - name
  74. private ContextStack _contextStack = null;
  75. public bool RecycleInstances {
  76. get { return _recycleInstances; }
  77. set {
  78. VerifyNotInSession ();
  79. _recycleInstances = value;
  80. }
  81. }
  82. public bool PreserveNames {
  83. get { return _preserveNames; }
  84. set {
  85. VerifyNotInSession ();
  86. _preserveNames = value;
  87. }
  88. }
  89. public bool ValidateRecycledTypes {
  90. get { return _validateRecycledTypes; }
  91. set {
  92. VerifyNotInSession ();
  93. _validateRecycledTypes = value;
  94. }
  95. }
  96. public IContainer Container {
  97. get {
  98. if (_designerContainer == null) {
  99. _designerContainer = (this.GetService (typeof (IDesignerHost)) as IDesignerHost).Container;
  100. }
  101. return _designerContainer;
  102. }
  103. set{
  104. VerifyNotInSession ();
  105. _designerContainer = value;
  106. }
  107. }
  108. public object PropertyProvider {
  109. get { return _propertyProvider; }
  110. set { _propertyProvider = value; }
  111. }
  112. public IList Errors {
  113. get { return _errors; }
  114. }
  115. public event EventHandler SessionDisposed;
  116. public event EventHandler SessionCreated;
  117. protected virtual void OnSessionCreated (EventArgs e)
  118. {
  119. if (SessionCreated != null) {
  120. SessionCreated (this, e);
  121. }
  122. }
  123. // For behaviour description:
  124. //
  125. // http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.designerserializationmanager.validaterecycledtypes.aspx
  126. // http://msdn2.microsoft.com/en-us/library/system.componentmodel.design.serialization.designerserializationmanager.preservenames.aspx
  127. //
  128. protected virtual object CreateInstance (Type type, ICollection arguments, string name, bool addToContainer)
  129. {
  130. VerifyInSession ();
  131. object instance = null;
  132. if (name != null && _recycleInstances) {
  133. _instancesByNameCache.TryGetValue (name, out instance);
  134. if (instance != null && _validateRecycledTypes) {
  135. if (instance.GetType () != type)
  136. instance = null;
  137. }
  138. }
  139. if (instance == null || !_recycleInstances)
  140. instance = this.CreateInstance (type, arguments);
  141. if (addToContainer && instance != null && this.Container != null && typeof (IComponent).IsAssignableFrom (type)) {
  142. if (_preserveNames) {
  143. this.Container.Add ((IComponent) instance, name);
  144. }
  145. else {
  146. if (name != null && this.Container.Components[name] != null) {
  147. this.Container.Add ((IComponent) instance);
  148. }
  149. else {
  150. this.Container.Add ((IComponent) instance, name);
  151. }
  152. }
  153. ISite site = ((IComponent)instance).Site; // get the name from the site in case a name has been generated.
  154. if (site != null)
  155. name = site.Name;
  156. }
  157. if (instance != null && name != null) {
  158. _instancesByNameCache[name] = instance;
  159. _instancesByValueCache[instance] = name;
  160. }
  161. return instance;
  162. }
  163. // Invokes the constructor that matches the arguments
  164. //
  165. private object CreateInstance (Type type, ICollection argsCollection)
  166. {
  167. object instance = null;
  168. object[] arguments = null;
  169. Type[] types = new Type[0];
  170. if (argsCollection != null) {
  171. arguments = new object[argsCollection.Count];
  172. types = new Type[argsCollection.Count];
  173. argsCollection.CopyTo (arguments, 0);
  174. for (int i=0; i < arguments.Length; i++) {
  175. if (arguments[i] == null)
  176. types[i] = null;
  177. else
  178. types[i] = arguments[i].GetType ();
  179. }
  180. }
  181. ConstructorInfo ctor = type.GetConstructor (types);
  182. if (ctor != null) {
  183. instance = ctor.Invoke (arguments);
  184. }
  185. return instance;
  186. }
  187. public object GetSerializer (Type componentType, Type serializerType)
  188. {
  189. VerifyInSession ();
  190. if (serializerType == null)
  191. throw new ArgumentNullException ("serializerType");
  192. object serializer = null;
  193. if (componentType != null) {
  194. // try 1: from cache
  195. //
  196. _serializersCache.TryGetValue (componentType, out serializer);
  197. // check for provider attribute and add it to the list of providers
  198. //
  199. if (serializer != null && !serializerType.IsAssignableFrom (serializer.GetType ()))
  200. serializer = null;
  201. AttributeCollection attributes = TypeDescriptor.GetAttributes (componentType);
  202. DefaultSerializationProviderAttribute providerAttribute = attributes[typeof (DefaultSerializationProviderAttribute)]
  203. as DefaultSerializationProviderAttribute;
  204. if (providerAttribute != null && this.GetType (providerAttribute.ProviderTypeName) == serializerType) {
  205. object provider = Activator.CreateInstance (this.GetType (providerAttribute.ProviderTypeName),
  206. BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic,
  207. null, null, null);
  208. ((IDesignerSerializationManager)this).AddSerializationProvider ((IDesignerSerializationProvider) provider);
  209. }
  210. }
  211. // try 2: DesignerSerializerAttribute
  212. //
  213. if (serializer == null && componentType != null) {
  214. AttributeCollection attributes = TypeDescriptor.GetAttributes (componentType);
  215. DesignerSerializerAttribute serializerAttribute = attributes[typeof (DesignerSerializerAttribute)] as DesignerSerializerAttribute;
  216. if (serializerAttribute != null &&
  217. this.GetType (serializerAttribute.SerializerBaseTypeName) == serializerType) {
  218. try {
  219. serializer = Activator.CreateInstance (this.GetType (serializerAttribute.SerializerTypeName),
  220. BindingFlags.CreateInstance | BindingFlags.Instance |
  221. BindingFlags.Public | BindingFlags.NonPublic,
  222. null, null, null);
  223. } catch {}
  224. }
  225. if (serializer != null)
  226. _serializersCache[componentType] = serializer;
  227. }
  228. // try 3: from provider
  229. //
  230. if (serializer == null && _serializationProviders != null) {
  231. foreach (IDesignerSerializationProvider provider in _serializationProviders) {
  232. serializer = provider.GetSerializer (this, null, componentType, serializerType);
  233. if (serializer != null)
  234. break;
  235. }
  236. }
  237. return serializer;
  238. }
  239. private void VerifyInSession ()
  240. {
  241. if (_session == null)
  242. throw new InvalidOperationException ("Not in session.");
  243. }
  244. private void VerifyNotInSession ()
  245. {
  246. if (_session != null)
  247. throw new InvalidOperationException ("In session.");
  248. }
  249. public IDisposable CreateSession ()
  250. {
  251. VerifyNotInSession ();
  252. _errors = new ArrayList ();
  253. _session = new Session (this);
  254. _serializersCache = new Dictionary<System.Type,object> ();
  255. _instancesByNameCache = new Dictionary<string,object> ();
  256. _instancesByValueCache = new Dictionary<object, string> ();
  257. _contextStack = new ContextStack ();
  258. this.OnSessionCreated (EventArgs.Empty);
  259. return _session;
  260. }
  261. protected virtual void OnSessionDisposed (EventArgs e)
  262. {
  263. _errors.Clear ();
  264. _errors = null;
  265. _serializersCache.Clear ();
  266. _serializersCache = null;
  267. _instancesByNameCache.Clear ();
  268. _instancesByNameCache = null;
  269. _instancesByValueCache.Clear ();
  270. _instancesByValueCache = null;
  271. _session = null;
  272. _contextStack = null;
  273. _resolveNameHandler = null;
  274. _serializationCompleteHandler = null;
  275. if (SessionDisposed != null) {
  276. SessionDisposed (this, e);
  277. }
  278. if (_serializationCompleteHandler != null)
  279. _serializationCompleteHandler (this, EventArgs.Empty);
  280. }
  281. protected virtual Type GetType (string name)
  282. {
  283. if (name == null)
  284. throw new ArgumentNullException ("name");
  285. this.VerifyInSession ();
  286. Type result = null;
  287. ITypeResolutionService typeResSvc = this.GetService (typeof (ITypeResolutionService)) as ITypeResolutionService;
  288. if (typeResSvc != null)
  289. result = typeResSvc.GetType (name);
  290. if (result == null)
  291. result = Type.GetType (name);
  292. return result;
  293. }
  294. #region IDesignerSerializationManager implementation
  295. protected virtual void OnResolveName (ResolveNameEventArgs e)
  296. {
  297. if (_resolveNameHandler != null) {
  298. _resolveNameHandler (this, e);
  299. }
  300. }
  301. void IDesignerSerializationManager.AddSerializationProvider (IDesignerSerializationProvider provider)
  302. {
  303. if (_serializationProviders == null)
  304. _serializationProviders = new List <IDesignerSerializationProvider> ();
  305. if (!_serializationProviders.Contains (provider))
  306. _serializationProviders.Add (provider);
  307. }
  308. void IDesignerSerializationManager.RemoveSerializationProvider (IDesignerSerializationProvider provider)
  309. {
  310. if (_serializationProviders != null)
  311. _serializationProviders.Remove (provider);
  312. }
  313. object IDesignerSerializationManager.CreateInstance (Type type, ICollection arguments, string name, bool addToContainer)
  314. {
  315. return this.CreateInstance (type, arguments, name, addToContainer);
  316. }
  317. object IDesignerSerializationManager.GetInstance (string name)
  318. {
  319. if (name == null)
  320. throw new ArgumentNullException ("name");
  321. this.VerifyInSession ();
  322. object instance = null;
  323. _instancesByNameCache.TryGetValue (name, out instance);
  324. if (instance == null && this.Container != null)
  325. instance = this.Container.Components[name];
  326. if (instance == null)
  327. instance = this.RequestInstance (name);
  328. return instance;
  329. }
  330. private object RequestInstance (string name)
  331. {
  332. ResolveNameEventArgs args = new ResolveNameEventArgs (name);
  333. this.OnResolveName (args);
  334. return args.Value;
  335. }
  336. Type IDesignerSerializationManager.GetType (string name)
  337. {
  338. return this.GetType (name);
  339. }
  340. object IDesignerSerializationManager.GetSerializer (Type type, Type serializerType)
  341. {
  342. return this.GetSerializer (type, serializerType);
  343. }
  344. string IDesignerSerializationManager.GetName (object instance)
  345. {
  346. if (instance == null)
  347. throw new ArgumentNullException ("instance");
  348. this.VerifyInSession ();
  349. string name = null;
  350. if (instance is IComponent) {
  351. ISite site = ((IComponent)instance).Site;
  352. if (site != null && site is INestedSite)
  353. name = ((INestedSite)site).FullName;
  354. else if (site != null)
  355. name = site.Name;
  356. }
  357. if (name == null)
  358. _instancesByValueCache.TryGetValue (instance, out name);
  359. return name;
  360. }
  361. void IDesignerSerializationManager.SetName (object instance, string name)
  362. {
  363. if (instance == null)
  364. throw new ArgumentNullException ("instance");
  365. if (name == null)
  366. throw new ArgumentNullException ("name");
  367. if (_instancesByNameCache.ContainsKey (name))
  368. throw new ArgumentException ("The object specified by instance already has a name, or name is already used by another named object.");
  369. _instancesByNameCache.Add (name, instance);
  370. _instancesByValueCache.Add (instance, name);
  371. }
  372. void IDesignerSerializationManager.ReportError (object error)
  373. {
  374. this.VerifyInSession ();
  375. _errors.Add (error);
  376. }
  377. ContextStack IDesignerSerializationManager.Context {
  378. get { return _contextStack; }
  379. }
  380. PropertyDescriptorCollection IDesignerSerializationManager.Properties {
  381. get {
  382. PropertyDescriptorCollection properties = new PropertyDescriptorCollection (new PropertyDescriptor[0]);
  383. object component = this.PropertyProvider;
  384. if (component != null)
  385. properties = TypeDescriptor.GetProperties (component);
  386. return properties;
  387. }
  388. }
  389. private EventHandler _serializationCompleteHandler;
  390. private ResolveNameEventHandler _resolveNameHandler;
  391. event EventHandler IDesignerSerializationManager.SerializationComplete {
  392. add {
  393. this.VerifyInSession ();
  394. _serializationCompleteHandler = (EventHandler) Delegate.Combine (_serializationCompleteHandler, value);
  395. }
  396. remove {
  397. _serializationCompleteHandler = (EventHandler) Delegate.Remove (_serializationCompleteHandler, value);
  398. }
  399. }
  400. event ResolveNameEventHandler IDesignerSerializationManager.ResolveName {
  401. add {
  402. this.VerifyInSession ();
  403. _resolveNameHandler = (ResolveNameEventHandler) Delegate.Combine (_resolveNameHandler, value);
  404. }
  405. remove {
  406. _resolveNameHandler = (ResolveNameEventHandler) Delegate.Remove (_resolveNameHandler, value);
  407. }
  408. }
  409. #endregion
  410. object IServiceProvider.GetService (Type service)
  411. {
  412. return this.GetService (service);
  413. }
  414. protected virtual object GetService (Type service)
  415. {
  416. object result = null;
  417. if (_serviceProvider != null)
  418. result = _serviceProvider.GetService (service);
  419. return result;
  420. }
  421. }
  422. }
  423. #endif