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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.73  
changed lines
  Added in v.87

  ViewVC Help
Powered by ViewVC 1.1.22