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

  ViewVC Help
Powered by ViewVC 1.1.22