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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 106 - (show annotations) (download)
Sun Mar 10 12:25:54 2013 UTC (6 years, 4 months ago) by william
File size: 14413 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 #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 if (!has_default_ctor) { continue; }
165 raw_instance = Activator.CreateInstance(type, flags, null, new object[0], culture);
166 if (raw_instance != null)
167 {
168 object handler_value = handler_prop.GetValue(raw_instance, null);
169 if (handler_value != null && handler_value.ToString() == node.Name.ToString())
170 {
171 handler_type = type;
172 break;
173 }
174 }
175 }
176 }
177 }
178 }
179 if (handler_type == null)
180 {
181 try
182 {
183 raw_instance = Activator.CreateInstance(typeof(UnhandledExtraMetaData), flags, null, new object[] { this, node }, culture);
184 }
185 catch (Exception ex) { throw ex; }
186
187 if (raw_instance == null)
188 {
189 StringBuilder node_builder = new StringBuilder();
190 node_builder.AppendFormat("<{0} ", node.Name);
191 if (node.HasAttributes) { foreach (var attribute in node.Attributes()) { node_builder.AppendFormat("{0}=\"{1}\" ", attribute.Name, attribute.Value); } }
192 string node_text = string.Format("{0}>", node_builder.ToString().TrimEnd(new char[] { ' ' }));
193 xmltv_logger.Verbose.Warn.WriteLine("Ignoring unhandled extra meta-data: {0}", node_text);
194 }
195 }
196 else
197 {
198 try
199 {
200 raw_instance = Activator.CreateInstance(handler_type, flags, null, new object[] { this, node }, culture);
201 }
202 catch (Exception ex) { throw ex; }
203 }
204 }
205
206
207
208 #region sub-classes
209 #region programme: stop/start/channelid
210 private class programme : XMLTVBase<XMLTVProgram>
211 {
212 public programme() : base(null, XMLTVConstants.Programs.RootElement) { }
213 public programme(XMLTVProgram instance, XElement node)
214 : base(instance, XMLTVConstants.Programs.RootElement)
215 {
216 if (node == null) { throw new NullReferenceException("The node instance was null"); }
217 if (node.HasAttributes)
218 {
219 var start = node.Attribute(XMLTVConstants.Programs.ProgramStart);
220 var t_start = start == null ? new DateTime() : ParseDate(start.Value);
221 if (!t_start.Equals(new DateTime())) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_start: {0}", start); }
222 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramStart, t_start);
223
224 var stop = node.Attribute(XMLTVConstants.Programs.ProgramStop);
225 var t_stop = stop == null ? new DateTime() : ParseDate(stop.Value);
226 if (!t_stop.Equals(new DateTime())) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_stop: {0}", stop); }
227 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramStop, t_stop);
228
229 var channelid = node.Attribute(XMLTVConstants.Programs.ProgramChannelId);
230 if (channelid != null)
231 {
232 if (!string.IsNullOrEmpty(channelid.Value)) { xmltv_logger.Verbose.Debug.WriteLine("\tprogram_channelid: {0}", channelid.Value); }
233 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramChannelId, channelid.Value);
234 }
235
236 }
237 }
238 }
239 #endregion
240 #region title
241 private class title : XMLTVBase<XMLTVProgram>
242 {
243 public title() : base(null, XMLTVConstants.Programs.ProgramTitle) { }
244 public title(XMLTVProgram instance, XElement node)
245 : base(instance, XMLTVConstants.Programs.ProgramTitle)
246 {
247 if (node == null) { throw new NullReferenceException("The node instance was null"); }
248 if (node.Value != null)
249 {
250 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramTitle, node.Value);
251 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_title: {0}", node.Value);
252 }
253 }
254 }
255 #endregion
256 #region sub-title
257 private class subtitle : XMLTVBase<XMLTVProgram>
258 {
259 public subtitle() : base(null, XMLTVConstants.Programs.ProgramSubTitle) { }
260 public subtitle(XMLTVProgram instance, XElement node)
261 : base(instance, XMLTVConstants.Programs.ProgramSubTitle)
262 {
263 if (node == null) { throw new NullReferenceException("The node instance was null"); }
264 if (node.Value != null)
265 {
266 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramSubTitle, node.Value);
267 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_subtitle: {0}", node.Value);
268 }
269 }
270 }
271 #endregion
272 #region description
273 private class description : XMLTVBase<XMLTVProgram>
274 {
275 public description() : base(null, XMLTVConstants.Programs.ProgramDescription) { }
276 public description(XMLTVProgram instance, XElement node)
277 : base(instance, XMLTVConstants.Programs.ProgramDescription)
278 {
279 if (node == null) { throw new NullReferenceException("The node instance was null"); }
280 if (node.Value != null)
281 {
282 instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramDescription, node.Value);
283 xmltv_logger.Verbose.Debug.WriteLine("\tprogram_description: {0}", node.Value);
284 }
285 }
286 }
287 #endregion
288
289 #region UnhandledExtraMetaData
290 private class UnhandledExtraMetaData : XMLTVBase<XMLTVProgram>
291 {
292 public UnhandledExtraMetaData() : base(null, null) { }
293 public UnhandledExtraMetaData(XMLTVProgram instance, XElement node)
294 : base(instance, null)
295 {
296 if (node == null) { throw new NullReferenceException("The node instance was null"); }
297 xmltv_logger.Verbose.Debug.WriteLine("Parsng unhandled extra meta-data: {0}", node.Name.ToString());
298 if (this.GetInstance() != null)
299 {
300 List<ExtraMetaData> list = new List<ExtraMetaData>();
301 if (!instance.MetaData.ContainsProperty(XMLTVConstants.Programs.ProgramExtraMetaData)) { instance.MetaData.AddProperty(XMLTVConstants.Programs.ProgramExtraMetaData, new List<ExtraMetaData>()); }
302 else { list = (List<ExtraMetaData>)instance.MetaData[XMLTVConstants.Programs.ProgramExtraMetaData]; }
303 ExtraMetaData data = new ExtraMetaData(node);
304 list.Add(data);
305 instance.MetaData[XMLTVConstants.Programs.ProgramExtraMetaData] = list;
306 }
307 }
308 }
309
310 #endregion
311 #endregion
312 }
313 }

  ViewVC Help
Powered by ViewVC 1.1.22