/[xmltv_parser]/branches/linux/xmltv_parser/libxmltv/Core/XMLTVProgram.cs
ViewVC logotype

Contents of /branches/linux/xmltv_parser/libxmltv/Core/XMLTVProgram.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 111 - (show annotations) (download)
Sun Mar 10 15:37:16 2013 UTC (6 years, 5 months ago) by william
Original Path: trunk/libxmltv/Core/XMLTVProgram.cs
File size: 15306 byte(s)
+ release memory held by reflection calls

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using libxmltv.Interfaces;
6 using System.Xml.Linq;
7 using System.Reflection;
8 using System.IO;
9 using System.Diagnostics;
10 using System.Globalization;
11
12 namespace libxmltv.Core
13 {
14 [Serializable]
15 internal class XMLTVProgram : XMLTVBase<XMLTVRuntimeInstance>, IXMLTVProgram
16 {
17 public XMLTVProgram()
18 : base(null, XMLTVConstants.Programs.RootElement)
19 {
20 InternalDictionaryAddKnownProperties();
21
22 }
23 public XMLTVProgram(XMLTVRuntimeInstance instance, XElement node)
24 : base(instance, XMLTVConstants.Programs.RootElement)
25 {
26 InternalDictionaryAddKnownProperties();
27 try {
28 xmltv_logger.Verbose.Debug.WriteLine("Creating Instance of XMLTVProgram");
29 Create(node);
30 xmltv_logger.Verbose.Debug.WriteLine("Created Instance of XMLTVProgram");
31 UpdateInstance();
32 }
33 catch (IOException ex) { Debug.WriteLine(ex.ToString()); }
34 }
35 #region IXMLTVProgram members
36 //public int Id { get; set; }
37 //public DateTime Start { get; set; }
38 //public DateTime Stop { get; set; }
39 //public IXMLTVChannel Channel { get; set; }
40 //public string Title { get; set; }
41 //public string SubTitle { get; set; }
42 //public string Description { get; set; }
43
44 private void InternalDictionaryAddKnownProperties()
45 {
46 MetaData = new PropertyDictionary();
47 MetaData.AddProperty("Id", 0);
48 MetaData.AddProperty(XMLTVConstants.Programs.ProgramStart, new DateTime());
49 MetaData.AddProperty(XMLTVConstants.Programs.ProgramStop, new DateTime());
50 MetaData.AddProperty(XMLTVConstants.Programs.ProgramChannelId, string.Empty);
51 MetaData.AddProperty(XMLTVConstants.Programs.ProgramTitle, string.Empty);
52 MetaData.AddProperty(XMLTVConstants.Programs.ProgramSubTitle, string.Empty);
53 MetaData.AddProperty(XMLTVConstants.Programs.ProgramDescription, string.Empty);
54 }
55
56 #region Property Dictionary Support
57 private PropertyDictionary _MetaData;
58 public PropertyDictionary MetaData { get { return _MetaData; } private set { _MetaData = value; } }
59 #endregion
60
61 #endregion
62 public override string ToString()
63 {
64 return string.Format("{0}: {1} - {2} ({3}) ['{4}' <==> '{5}']",
65 MetaData["Id"].ToString(),
66 MetaData[XMLTVConstants.Programs.ProgramTitle].ToString(),
67 MetaData[XMLTVConstants.Programs.ProgramSubTitle].ToString(),
68 MetaData[XMLTVConstants.Programs.ProgramChannelId].ToString(),
69 ((DateTime)MetaData[XMLTVConstants.Programs.ProgramStart]).ToString("yyyy/MM/dd hh:mm tt"),
70 ((DateTime)MetaData[XMLTVConstants.Programs.ProgramStop]).ToString("yyyy/MM/dd hh:mm tt"));
71 }
72
73
74
75
76 private void UpdateInstance()
77 {
78 bool found_field = false;
79 var instance_type = this.GetInstance().GetType();
80 var fields = instance_type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
81 foreach (var field in fields)
82 {
83 if (field.FieldType == typeof(List<IXMLTVProgram>))
84 {
85 found_field = true;
86 try
87 {
88
89 var list = (List<IXMLTVProgram>)field.GetValue(this.GetInstance());
90 MetaData["Id"] = list.Count + 1;
91 list.Add(this);
92 xmltv_logger.Verbose.Debug.WriteLine("Updating instance with program information: {0}", this.ToString());
93 field.SetValue(this.GetInstance(), list);
94 break;
95 }
96 catch (Exception ex)
97 {
98 xmltv_logger.Verbose.Error.WriteLine("Unable to update instance with program information.");
99 xmltv_logger.Verbose.Error.WriteLine(ex.ToString());
100 }
101 }
102 }
103 if (!found_field)
104 {
105 xmltv_logger.Verbose.Error.WriteLine("Unable to update instance with program information.");
106 }
107 }
108
109 private void Create(XElement node)
110 {
111 CreateHandlerForProgramMetaDataNode(node);
112 var nodes = node.Elements().ToList();
113 foreach (var sub_node in nodes)
114 {
115 if (this.GetInstance().IsAborting)
116 {
117 break;
118 }
119 CreateHandlerForProgramMetaDataNode(sub_node);
120 }
121 }
122 private static DateTime ParseDate(string timeStamp)
123 {
124 DateTime dt = new DateTime();
125 try
126 {
127 dt = DateTime.ParseExact(timeStamp, "yyyyMMddHHmmss zzzz", System.Globalization.CultureInfo.CurrentCulture);
128 }
129 catch (Exception ex) { throw ex; }
130 return dt;
131 }
132
133 private void CreateHandlerForProgramMetaDataNode(XElement node)
134 {
135
136 Type t = this.GetType();
137 Assembly asm = t.Assembly;
138 var types = asm.GetTypes();
139 var classes = types.ToList().FindAll(
140 m =>
141 m.DeclaringType == t &&
142 m.IsClass &&
143 !m.IsSealed
144 );
145 classes.TrimExcess();
146
147 object raw_instance = null;
148 BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
149 CultureInfo culture = CultureInfo.CurrentCulture;
150 Type handler_type = null;
151 foreach (var type in classes)
152 {
153 if (type.BaseType != null && type.BaseType == typeof(XMLTVBase<XMLTVProgram>))
154 {
155 var iface = type.GetInterface("IXMLTVHandler", true);
156 if (iface != null)
157 {
158 var handler_prop = type.GetProperty("Handler");
159 if (handler_prop != null)
160 {
161 var ctors = type.GetConstructors(flags);
162 bool has_default_ctor = false;
163 foreach (var ctor in ctors) { if (ctor.GetParameters().Count() == 0) { has_default_ctor = true; } }
164 ctors = null;
165 if (!has_default_ctor) { continue; }
166 raw_instance = Activator.CreateInstance(type, flags, null, new object[0], culture);
167 if (raw_instance != null)
168 {
169 object handler_value = handler_prop.GetValue(raw_instance, null);
170 if (handler_value != null && handler_value.ToString() == node.Name.ToString())
171 {
172 handler_type = type;
173 handler_value = null;
174 raw_instance = null;
175 handler_prop = null;
176 iface = null;
177 break;
178 }
179 handler_value = null;
180 }
181 raw_instance = null;
182 }
183 handler_prop = null;
184 }
185 iface = null;
186 }
187 }
188 t = null;
189 asm = null;
190 types = null;
191 classes = null;
192 if (handler_type == null)
193 {
194 try
195 {
196 raw_instance = Activator.CreateInstance(typeof(UnhandledExtraProgramMetaData), flags, null, new object[] { this, node }, culture);
197 }
198 catch (Exception ex) { throw ex; }
199
200 if (raw_instance == null)
201 {
202 StringBuilder node_builder = new StringBuilder();
203 node_builder.AppendFormat("<{0} ", node.Name);
204 if (node.HasAttributes) { foreach (var attribute in node.Attributes()) { node_builder.AppendFormat("{0}=\"{1}\" ", attribute.Name, attribute.Value); } }
205 string node_text = string.Format("{0}>", node_builder.ToString().TrimEnd(new char[] { ' ' }));
206 xmltv_logger.Verbose.Warn.WriteLine("Ignoring unhandled extra meta-data: {0}", node_text);
207 }
208 }
209 else
210 {
211 try
212 {
213 raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] { this, node }, culture);
214 }
215 catch (Exception ex) { throw ex; }
216 }
217 raw_instance = null;
218 flags = 0;
219 culture = null;
220 node = null;
221 }
222
223
224
225 #region sub-classes
226 #region programme: stop/start/channelid
227 private class programme : XMLTVBase<XMLTVProgram>
228 {
229 public programme() : base(null, XMLTVConstants.Programs.RootElement) { }
230 public programme(XMLTVProgram instance, XElement node)
231 : base(instance, XMLTVConstants.Programs.RootElement)
232 {
233 if (node == null) { throw new NullReferenceException("The node instance was null"); }
234 if (node.HasAttributes)
235 {
236 var start = node.Attribute(XMLTVConstants.Programs.ProgramStart);
237 var t_start = start == null ? new DateTime() : ParseDate(start.Value);
238 if (!t_start.Equals(new DateTime())) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_start: {0}", start); }
239 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramStart, t_start);
240
241 var stop = node.Attribute(XMLTVConstants.Programs.ProgramStop);
242 var t_stop = stop == null ? new DateTime() : ParseDate(stop.Value);
243 if (!t_stop.Equals(new DateTime())) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_stop: {0}", stop); }
244 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramStop, t_stop);
245
246 var channelid = node.Attribute(XMLTVConstants.Programs.ProgramChannelId);
247 if (channelid != null)
248 {
249 if (!string.IsNullOrEmpty(channelid.Value)) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_channelid: {0}", channelid.Value); }
250 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramChannelId, channelid.Value);
251 }
252
253 }
254 node = null;
255 }
256 }
257 #endregion
258 #region title
259 private class title : XMLTVBase<XMLTVProgram>
260 {
261 public title() : base(null, XMLTVConstants.Programs.ProgramTitle) { }
262 public title(XMLTVProgram instance, XElement node)
263 : base(instance, XMLTVConstants.Programs.ProgramTitle)
264 {
265 if (node == null) { throw new NullReferenceException("The node instance was null"); }
266 if (node.Value != null)
267 {
268 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramTitle, node.Value);
269 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_title: {0}", node.Value);
270 }
271 node = null;
272 }
273 }
274 #endregion
275 #region sub-title
276 private class subtitle : XMLTVBase<XMLTVProgram>
277 {
278 public subtitle() : base(null, XMLTVConstants.Programs.ProgramSubTitle) { }
279 public subtitle(XMLTVProgram instance, XElement node)
280 : base(instance, XMLTVConstants.Programs.ProgramSubTitle)
281 {
282 if (node == null) { throw new NullReferenceException("The node instance was null"); }
283 if (node.Value != null)
284 {
285 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramSubTitle, node.Value);
286 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_subtitle: {0}", node.Value);
287 }
288 node = null;
289 }
290 }
291 #endregion
292 #region description
293 private class description : XMLTVBase<XMLTVProgram>
294 {
295 public description() : base(null, XMLTVConstants.Programs.ProgramDescription) { }
296 public description(XMLTVProgram instance, XElement node)
297 : base(instance, XMLTVConstants.Programs.ProgramDescription)
298 {
299 if (node == null) { throw new NullReferenceException("The node instance was null"); }
300 if (node.Value != null)
301 {
302 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramDescription, node.Value);
303 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_description: {0}", node.Value);
304 }
305 node = null;
306 }
307 }
308 #endregion
309
310 #region UnhandledExtraMetaData
311 private class UnhandledExtraProgramMetaData : XMLTVBase<XMLTVProgram>
312 {
313 public UnhandledExtraProgramMetaData() : base(null, null) { }
314 public UnhandledExtraProgramMetaData(XMLTVProgram instance, XElement node)
315 : base(instance, null)
316 {
317 if (node == null) { throw new NullReferenceException("The node instance was null"); }
318 xmltv_logger.Verbose.Debug.WriteLine("Parsng unhandled extra program meta-data: {0}", node.Name.ToString());
319 if (this.GetInstance() != null)
320 {
321 List<IExtraMetaData> list = new List<IExtraMetaData>();
322 if (!instance.MetaData.ContainsProperty(XMLTVConstants.Programs.ProgramExtraMetaData)) { instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramExtraMetaData, new List<ExtraMetaData>()); }
323 else { list = (List<IExtraMetaData>)instance.MetaData[XMLTVConstants.Programs.ProgramExtraMetaData]; }
324 ExtraMetaData data = new ExtraMetaData(node);
325 list.Add(data);
326 instance.MetaData[XMLTVConstants.Programs.ProgramExtraMetaData] = list;
327 data = null;
328 }
329 node = null;
330 }
331 }
332 #endregion
333 #endregion
334 }
335 }

  ViewVC Help
Powered by ViewVC 1.1.22