/[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 298 - (show annotations) (download)
Fri Dec 14 19:38:41 2018 UTC (4 months, 1 week ago) by william
File size: 15913 byte(s)
update libxmltv/Core/XMLTVProgram.cs -- check if extra metadata exists before returning a list
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 IPropertyDictionary _MetaData;
58 public IPropertyDictionary MetaData { get { return _MetaData; } private set { _MetaData = value; } }
59 public List<IExtraMetaData> GetExtraMetaData()
60 {
61 if (this.MetaData.ContainsProperty (XMLTVConstants.Programs.ProgramExtraMetaData)) {
62 return (List<IExtraMetaData>)this.MetaData [XMLTVConstants.Programs.ProgramExtraMetaData];
63 } else {
64 return new List<IExtraMetaData>();
65 }
66 }
67 #endregion
68
69 #endregion
70 public override string ToString()
71 {
72 return string.Format("{0}: {1} - {2} ({3}) ['{4}' <==> '{5}']",
73 MetaData["Id"].ToString(),
74 MetaData[XMLTVConstants.Programs.ProgramTitle].ToString(),
75 MetaData[XMLTVConstants.Programs.ProgramSubTitle].ToString(),
76 MetaData[XMLTVConstants.Programs.ProgramChannelId].ToString(),
77 ((DateTime)MetaData[XMLTVConstants.Programs.ProgramStart]).ToDateTimeString(),
78 ((DateTime)MetaData[XMLTVConstants.Programs.ProgramStop]).ToDateTimeString());
79 }
80
81
82
83
84 private void UpdateInstance()
85 {
86 bool found_field = false;
87 var instance_type = this.GetInstance().GetType();
88 var fields = instance_type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
89 foreach (var field in fields)
90 {
91 if (field.FieldType == typeof(ProgramList))
92 {
93 found_field = true;
94 try
95 {
96
97 var list = (ProgramList)field.GetValue(this.GetInstance());
98 MetaData["Id"] = list.Count + 1;
99 list.Add(this);
100 xmltv_logger.Verbose.Debug.WriteLine("Updating instance with program information: {0}", this.ToString());
101 field.SetValue(this.GetInstance(), list);
102 break;
103 }
104 catch (Exception ex)
105 {
106 xmltv_logger.Verbose.Error.WriteLine("Unable to update instance with program information.");
107 xmltv_logger.Verbose.Error.WriteLine(ex.ToString());
108 }
109 }
110 }
111 if (!found_field)
112 {
113 xmltv_logger.Verbose.Error.WriteLine("Unable to update instance with program information.");
114 }
115 }
116
117 private void Create(XElement node)
118 {
119 CreateHandlerForProgramMetaDataNode(node);
120 var nodes = node.Elements().ToList();
121 foreach (var sub_node in nodes)
122 {
123 if (this.GetInstance().IsAborting)
124 {
125 break;
126 }
127 CreateHandlerForProgramMetaDataNode(sub_node);
128 }
129 }
130 private static DateTime ParseDate(string timeStamp)
131 {
132 DateTime dt = new DateTime();
133 try
134 {
135 dt = DateTime.ParseExact(timeStamp, "yyyyMMddHHmmss zzzz", System.Globalization.CultureInfo.CurrentCulture);
136 }
137 catch (Exception ex) { throw ex; }
138 return dt;
139 }
140
141 private void CreateHandlerForProgramMetaDataNode(XElement node)
142 {
143
144 Type t = this.GetType();
145 Assembly asm = t.Assembly;
146 var types = asm.GetTypes();
147 var classes = types.ToList().FindAll(
148 m =>
149 m.DeclaringType == t &&
150 m.IsClass &&
151 !m.IsSealed
152 );
153 classes.TrimExcess();
154
155 object raw_instance = null;
156 BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
157 CultureInfo culture = CultureInfo.CurrentCulture;
158 Type handler_type = null;
159 foreach (var type in classes)
160 {
161 if (type.BaseType != null && type.BaseType == typeof(XMLTVBase<XMLTVProgram>))
162 {
163 var iface = type.GetInterface("IXMLTVHandler", true);
164 if (iface != null)
165 {
166 var handler_prop = type.GetProperty("Handler");
167 if (handler_prop != null)
168 {
169 var ctors = type.GetConstructors(flags);
170 bool has_default_ctor = false;
171 foreach (var ctor in ctors) { if (ctor.GetParameters().Count() == 0) { has_default_ctor = true; } }
172 ctors = null;
173 if (!has_default_ctor) { continue; }
174 raw_instance = Activator.CreateInstance(type, flags, null, new object[0], culture);
175 if (raw_instance != null)
176 {
177 object handler_value = handler_prop.GetValue(raw_instance, null);
178 if (handler_value != null && handler_value.ToString() == node.Name.ToString())
179 {
180 handler_type = type;
181 handler_value = null;
182 raw_instance = null;
183 handler_prop = null;
184 iface = null;
185 break;
186 }
187 handler_value = null;
188 }
189 raw_instance = null;
190 }
191 handler_prop = null;
192 }
193 iface = null;
194 }
195 }
196 t = null;
197 asm = null;
198 types = null;
199 classes = null;
200 if (handler_type == null)
201 {
202 try
203 {
204 raw_instance = Activator.CreateInstance(typeof(UnhandledExtraProgramMetaData), flags, null, new object[] { this, node }, culture);
205 }
206 catch (Exception ex) { throw ex; }
207
208 if (raw_instance == null)
209 {
210 StringBuilder node_builder = new StringBuilder();
211 node_builder.AppendFormat("<{0} ", node.Name);
212 if (node.HasAttributes) { foreach (var attribute in node.Attributes()) { node_builder.AppendFormat("{0}=\"{1}\" ", attribute.Name, attribute.Value); } }
213 string node_text = string.Format("{0}>", node_builder.ToString().TrimEnd(new char[] { ' ' }));
214 xmltv_logger.Verbose.Warn.WriteLine("Ignoring unhandled extra meta-data: {0}", node_text);
215 }
216 }
217 else
218 {
219 try
220 {
221 raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] { this, node }, culture);
222 }
223 catch (Exception ex) { throw ex; }
224 }
225 raw_instance = null;
226 flags = 0;
227 culture = null;
228 node = null;
229 }
230
231
232
233 #region sub-classes
234 #region programme: stop/start/channelid
235 private class programme : XMLTVBase<XMLTVProgram>
236 {
237 public programme() : base(null, XMLTVConstants.Programs.RootElement) { }
238 public programme(XMLTVProgram instance, XElement node)
239 : base(instance, XMLTVConstants.Programs.RootElement)
240 {
241 if (node == null) { throw new NullReferenceException("The node instance was null"); }
242 if (node.HasAttributes)
243 {
244 var start = node.Attribute(XMLTVConstants.Programs.ProgramStart);
245 var t_start = start == null ? new DateTime() : ParseDate(start.Value);
246 if (!t_start.Equals(new DateTime()))
247 {
248 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_start: {0}", start);
249 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_start dt: {0}", t_start.ToString());
250 }
251 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramStart, t_start);
252
253 var stop = node.Attribute(XMLTVConstants.Programs.ProgramStop);
254 var t_stop = stop == null ? new DateTime() : ParseDate(stop.Value);
255 if (!t_stop.Equals(new DateTime()))
256 {
257 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_stop: {0}", stop);
258 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_stop dt: {0}", t_stop.ToString());
259 }
260 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramStop, t_stop);
261
262 var channelid = node.Attribute(XMLTVConstants.Programs.ProgramChannelId);
263 if (channelid != null)
264 {
265 if (!string.IsNullOrEmpty(channelid.Value)) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_channelid: {0}", channelid.Value); }
266 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramChannelId, channelid.Value);
267 }
268
269 }
270 node = null;
271 }
272 }
273 #endregion
274 #region title
275 private class title : XMLTVBase<XMLTVProgram>
276 {
277 public title() : base(null, XMLTVConstants.Programs.ProgramTitle) { }
278 public title(XMLTVProgram instance, XElement node)
279 : base(instance, XMLTVConstants.Programs.ProgramTitle)
280 {
281 if (node == null) { throw new NullReferenceException("The node instance was null"); }
282 if (node.Value != null)
283 {
284 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramTitle, node.Value);
285 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_title: {0}", node.Value);
286 }
287 node = null;
288 }
289 }
290 #endregion
291 #region sub-title
292 private class subtitle : XMLTVBase<XMLTVProgram>
293 {
294 public subtitle() : base(null, XMLTVConstants.Programs.ProgramSubTitle) { }
295 public subtitle(XMLTVProgram instance, XElement node)
296 : base(instance, XMLTVConstants.Programs.ProgramSubTitle)
297 {
298 if (node == null) { throw new NullReferenceException("The node instance was null"); }
299 if (node.Value != null)
300 {
301 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramSubTitle, node.Value);
302 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_subtitle: {0}", node.Value);
303 }
304 node = null;
305 }
306 }
307 #endregion
308 #region description
309 private class description : XMLTVBase<XMLTVProgram>
310 {
311 public description() : base(null, XMLTVConstants.Programs.ProgramDescription) { }
312 public description(XMLTVProgram instance, XElement node)
313 : base(instance, XMLTVConstants.Programs.ProgramDescription)
314 {
315 if (node == null) { throw new NullReferenceException("The node instance was null"); }
316 if (node.Value != null)
317 {
318 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramDescription, node.Value);
319 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_description: {0}", node.Value);
320 }
321 node = null;
322 }
323 }
324 #endregion
325
326 #region UnhandledExtraMetaData
327 private class UnhandledExtraProgramMetaData : XMLTVBase<XMLTVProgram>
328 {
329 public UnhandledExtraProgramMetaData() : base(null, null) { }
330 public UnhandledExtraProgramMetaData(XMLTVProgram instance, XElement node)
331 : base(instance, null)
332 {
333 if (node == null) { throw new NullReferenceException("The node instance was null"); }
334 xmltv_logger.Verbose.Debug.WriteLine("Parsng unhandled extra program meta-data: {0}", node.Name.ToString());
335 if (this.GetInstance() != null)
336 {
337 List<IExtraMetaData> list = new List<IExtraMetaData>();
338 if (!instance.MetaData.ContainsProperty(XMLTVConstants.Programs.ProgramExtraMetaData)) { instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramExtraMetaData, new List<ExtraMetaData>()); }
339 else { list = (List<IExtraMetaData>)instance.MetaData[XMLTVConstants.Programs.ProgramExtraMetaData]; }
340 ExtraMetaData data = new ExtraMetaData(node);
341 list.Add(data);
342 instance.MetaData[XMLTVConstants.Programs.ProgramExtraMetaData] = list;
343 data = null;
344 }
345 node = null;
346 }
347 }
348 #endregion
349 #endregion
350 }
351 }

  ViewVC Help
Powered by ViewVC 1.1.22