/[xmltv_parser]/trunk/libxmltv/Core/XMLTVRuntimeInstance.cs
ViewVC logotype

Contents of /trunk/libxmltv/Core/XMLTVRuntimeInstance.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 72 - (show annotations) (download)
Sat Mar 9 09:29:40 2013 UTC (7 years, 8 months ago) by william
File size: 12340 byte(s)

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using libxmltv.Interfaces;
6 using System.ComponentModel;
7 using System.Windows.Forms;
8 using System.Threading;
9 using System.Reflection;
10 using System.Globalization;
11 using System.Diagnostics;
12
13 namespace libxmltv.Core
14 {
15 [Serializable]
16 internal class XMLTVRuntimeInstance : MarshalByRefObject,
17 IXMLTVRuntimeInstance,
18 ISerializer<XMLTVRuntimeInstance>,
19 IGetCreatedInstanceEvent,
20 ISetCreatedInstanceEvent,
21 IDestroyInstance,
22 IRuntimeInstanceLoader<XMLTVRuntimeInstance>
23 {
24 [NonSerialized]
25 Thread worker;
26 public XMLTVRuntimeInstance() { init(); }
27 public XMLTVRuntimeInstance(string xmlfile) : this(xmlfile, null) { }
28 public XMLTVRuntimeInstance(string xmlfile, EventHandler<EventArgs> handler)
29 : this()
30 {
31 this.OnInstanceCreated += handler;
32 worker = new Thread(new ParameterizedThreadStart(CreateInstance)); worker.Start(xmlfile);
33 }
34 private void CreateInstance(object xmlfile)
35 {
36 using (XMLTVInstance instance = new XMLTVInstance(xmlfile.ToString()))
37 {
38 this.LoadFromInstance(instance.GetInstance());
39 OnCreatedInstance(this, new EventArgs());
40 }
41 }
42
43
44 private void OnCreatedInstance(object sender, EventArgs e)
45 {
46 if (OnInstanceCreated != null) { OnInstanceCreated.Invoke(sender, e); }
47 }
48
49 private void init()
50 {
51 this.Source = new XMLTVSource();
52 this.Channels = new Dictionary<string, IXMLTVChannel>();
53 this.Programs = new Dictionary<int, IXMLTVProgram>();
54 this.XmlFile_Name = string.Empty;
55 this.XmlFile_FullName = string.Empty;
56 this.XmlDoc = string.Empty;
57 this.OnInstanceCreated = null;
58 }
59
60 #region IXMLTVRuntimeInstance members
61 private bool _IsAborting;
62 public bool IsAborting { get { return _IsAborting; } private set { _IsAborting = value; } }
63
64
65 private string _XmlFile_Name;
66 public string XmlFile_Name { get { return _XmlFile_Name; } set { _XmlFile_Name = value; } }
67 private string _XmlFile_FullName;
68 public string XmlFile_FullName { get { return _XmlFile_FullName; } set { _XmlFile_FullName = value; } }
69
70 private string _XmlDoc;
71 public string XmlDoc { get { return _XmlDoc; } set { _XmlDoc = value; } }
72 private IXMLTVSource _Source;
73 public IXMLTVSource Source { get { return _Source; } set { _Source = value; } }
74 private Dictionary<string, IXMLTVChannel> _Channels;
75 public Dictionary<string, IXMLTVChannel> Channels { get { return _Channels; } set { _Channels = value; } }
76 private Dictionary<int, IXMLTVProgram> _Programs;
77 public Dictionary<int, IXMLTVProgram> Programs { get { return _Programs; } set { _Programs = value; } }
78 #endregion
79 #region IOnInstanceCreated members
80 [NonSerialized]
81 private EventHandler<EventArgs> _OnInstanceCreated;
82 public EventHandler<EventArgs> OnInstanceCreated { get { return _OnInstanceCreated; } set { _OnInstanceCreated = value; } }
83 #endregion
84 #region IGetCreatedInstanceEvent members
85 public EventHandler<EventArgs> GetOnInstanceCreated() { return OnInstanceCreated; }
86 #endregion
87 #region ISetCreatedInstanceEvent members
88 public void SetOnInstanceCreated(EventHandler<EventArgs> event_instance) { OnInstanceCreated = event_instance; }
89 #endregion
90 #region ISerializer<XMLTVRuntimeInstance> members
91 public IXMLTVSerializer<XMLTVRuntimeInstance> Serializer { get { return new XMLTVSerializer<XMLTVRuntimeInstance>(this); } }
92 #endregion
93 #region IDestroyInstance member
94 public void DestroyInstance()
95 {
96 xmltv_logger.Debug.WriteLine("Destoying Instance of: '{0}'", this.GetType().Name);
97 this.IsAborting = true;
98 if (worker == null)
99 {
100 xmltv_logger.Debug.WriteLine("Unable to destroy instance of: '{0}' - worker thread is null", this.GetType().Name);
101 return;
102 }
103 else
104 {
105 if (worker.IsAlive)
106 {
107 xmltv_logger.Verbose.Debug.WriteLine("Requesting Instance to Abort...");
108 while (worker.IsAlive) { worker.Abort(); Application.DoEvents(); }
109 }
110 else { xmltv_logger.Debug.WriteLine("Instance of: '{0}'- already destroyed.", this.GetType().Name); }
111 }
112 }
113 #endregion
114 #region IRuntimeInstanceLoader<XMLTVRuntimeInstance> member
115 public XMLTVRuntimeInstance LoadFromInstance(XMLTVRuntimeInstance instance)
116 {
117 if (instance == null)
118 {
119 throw new NullReferenceException("Failed to load from instance because the instance is null.");
120 }
121 CloneFromInstance(ref instance);
122 xmltv_logger.Debug.WriteLine("Loading from instance...");
123 if (this.Source != null)
124 {
125 xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Created by '{1}' - original source file: '{2}'", this.Source.SourceName, this.Source.GeneratorName, this.XmlFile_FullName);
126 }
127 else
128 {
129 xmltv_logger.Error.WriteLine("Source Property is null.");
130 throw new NullReferenceException("Source Property is null.");
131 }
132 if (this.Channels != null)
133 {
134 xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Channels from source '{1}'", this.Channels.Count, this.Source.SourceName);
135 }
136 else
137 {
138 xmltv_logger.Error.WriteLine("Channels Property is null.");
139 throw new NullReferenceException("Channels Property is null.");
140 }
141 if (this.Programs != null)
142 {
143 xmltv_logger.Info.WriteLine("Source Loaded: '{0}' Programs from source '{1}'", this.Programs.Count, this.Source.SourceName);
144 }
145 else
146 {
147 xmltv_logger.Error.WriteLine("Programs Property is null.");
148 throw new NullReferenceException("Programs Property is null.");
149 }
150 xmltv_logger.Debug.WriteLine("Loaded from instance...");
151 return instance;
152 }
153 #endregion
154 #region CloneFromInstance
155 private void CloneFromInstance(ref XMLTVRuntimeInstance instance)
156 {
157 xmltv_logger.Debug.WriteLine("Cloning from instance...");
158 BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
159 CultureInfo culture = CultureInfo.CurrentCulture;
160 Type t = typeof(XMLTVRuntimeInstance);
161 foreach (var field in t.GetFields(flags))
162 {
163 try
164 {
165 if (field.IsNotSerialized) { continue; }
166 var f = instance.GetType().GetField(field.Name, flags);
167 var v = f.GetValue(instance);
168 if (v != null)
169 {
170 field.SetValue(this, v);
171 }
172 else
173 {
174 xmltv_logger.Debug.WriteLine("Attempted to set field: '{0}' with a null value. The operation was aborted.", f.Name);
175 continue;
176 }
177 }
178 catch (Exception ex)
179 {
180 throw new Exception(string.Format("Unable to copy value for field: '{0}' from instance", field.Name), ex);
181 }
182 }
183 foreach (var property in t.GetProperties(flags))
184 {
185 try
186 {
187 var f = instance.GetType().GetProperty(property.Name);
188 object value = null;
189 try
190 {
191 value = f.GetValue(instance, null);
192 }
193 catch (ArgumentException ex) { if (ex.Message == "Property get method not found.") { Debug.WriteLine(ex.ToString()); } else { throw ex; } }
194 try
195 {
196 if (value != null)
197 {
198 property.SetValue(this, value, null);
199 }
200 else
201 {
202 xmltv_logger.Debug.WriteLine("Attempted to set property: '{0}' with a null value. The operation was aborted.", f.Name);
203 continue;
204 }
205 }
206 catch (ArgumentException ex) { if (ex.Message == "Property set method not found.") { Debug.WriteLine(ex.ToString()); } else { throw ex; } }
207
208 }
209 catch (Exception ex)
210 {
211 throw new Exception(string.Format("Unable to copy value for property: '{0}' from instance", property.Name), ex);
212 }
213 }
214 xmltv_logger.Debug.WriteLine("Cloned from instance...");
215 }
216 #endregion
217 }
218
219 internal class XMLTVInstance : IGetInstance<XMLTVRuntimeInstance>, IDisposable
220 {
221 private XMLTVRuntimeInstance gInstance;
222 public XMLTVRuntimeInstance GetInstance() { return gInstance; }
223 public XMLTVInstance(string xmlfile)
224 {
225 try
226 {
227 CreateLoader(xmlfile);
228 }
229 catch (Exception ex)
230 {
231 xmltv_logger.Error.WriteLine(ex.ToString());
232 }
233 }
234
235 private void CreateLoader(string xml_file)
236 {
237 gInstance = new XMLTVRuntimeInstance();
238 bool bound_to_ctor = false;
239 object raw_instance = null;
240 Assembly asm = Assembly.GetExecutingAssembly();
241 var types = asm.GetTypes();
242
243 foreach (var type in types)
244 {
245 if (type.BaseType != null && type.BaseType == typeof(XMLTVBase<XMLTVRuntimeInstance>))
246 {
247 xmltv_logger.Verbose.Debug.WriteLine("Type: '{0}' Base: '{1}'", type.Name, type.BaseType == null ? "none" : type.BaseType.Name);
248
249 BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
250 CultureInfo culture = CultureInfo.CurrentCulture;
251 object[] args = new object[] { xml_file, gInstance };
252 try
253 {
254 raw_instance = Activator.CreateInstance(type, flags, null, args, culture);
255 bound_to_ctor = true;
256 }
257 catch (Exception ex)
258 {
259 Debug.WriteLine(ex.ToString());
260 }
261 }
262 }
263 if (!bound_to_ctor) { throw new Exception("Unable to find a compatible XMLTV Data Loader."); }
264 if (raw_instance == null) { throw new NullReferenceException("Found a compatible XMLTV Data Loader, but it returned invalid data."); }
265 IGetInstance<XMLTVRuntimeInstance> getter_instance = (raw_instance as IGetInstance<XMLTVRuntimeInstance>);
266 if (getter_instance != null) { gInstance = getter_instance.GetInstance(); }
267 else { throw new Exception("Found a compatible XMLTV Data Loader, but was unable to obtain the instance holding the data"); }
268 }
269 private void CreateParser(XMLTVRuntimeInstance instance)
270 {
271
272 }
273
274 public void Dispose()
275 {
276 //throw new NotImplementedException();
277 }
278
279
280 }
281 }

  ViewVC Help
Powered by ViewVC 1.1.22