PageRenderTime 30ms CodeModel.GetById 8ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/ProtoXML/ProtoFile.vb

#
Visual Basic | 344 lines | 330 code | 14 blank | 0 comment | 1 complexity | aa985fa624605732e91804d40673cab6 MD5 | raw file
  1Imports System.Xml
  2Imports System.Text
  3
  4Public Class ProtoFile
  5    Implements IProtoXFile
  6
  7
  8
  9    Public Sub New(ByVal NodeName As String)
 10        Me.NodeName = NodeName
 11    End Sub
 12
 13    Public Property Doc As System.Xml.Linq.XDocument = <?xml version="1.0" encoding="UTF-8" standalone="yes"?><tvshow></tvshow> Implements IProtoXFile.Doc
 14    Public Property CacheDoc As System.Xml.Linq.XDocument = <?xml version="1.0" encoding="UTF-8" standalone="yes"?><tvshow></tvshow> Implements IProtoXFile.CacheDoc
 15
 16    Private _node As XElement = Doc.Root
 17    Public Property Node As System.Xml.Linq.XElement Implements IProtoXBase.Node
 18        Get
 19            Return _node
 20        End Get
 21        Set(ByVal value As System.Xml.Linq.XElement)
 22            _node = value
 23        End Set
 24    End Property
 25
 26    Private _cacheNode As XElement = CacheDoc.Root
 27    Public Property CacheNode As System.Xml.Linq.XElement Implements IProtoXBase.CacheNode
 28        Get
 29            Return _cacheNode
 30        End Get
 31        Set(value As System.Xml.Linq.XElement)
 32            _cacheNode = value
 33        End Set
 34    End Property
 35
 36    Public Property NodeName As String Implements IProtoXBase.NodeName
 37        Get
 38            Return _node.Name.ToString
 39        End Get
 40        Set(ByVal value As String)
 41            _node.Name = value
 42            _cacheNode.Name = value
 43        End Set
 44    End Property
 45
 46    Friend Sub AddChildForLoad(ByRef NewChild As IProtoXChild) Implements IProtoXBase.AddChildForLoad
 47        If Me.ChildrenLookup.ContainsKey(NewChild.NodeName) Then
 48            Throw New Exception("Already contains lookup for this node name)")
 49        End If
 50
 51        Me.ChildrenLookup.Add(NewChild.NodeName, NewChild)
 52    End Sub
 53
 54    Friend Property ChildrenLookup As New System.Collections.Generic.Dictionary(Of String, IProtoXChild) Implements IProtoXBase.ChildrenLookup
 55
 56
 57    Public Property IsCache As Boolean
 58
 59#Region "File Access"
 60    Private _NfoFilePath As String
 61    Public Property NfoFilePath As String Implements IProtoXFile.NfoFilePath
 62        Get
 63            Return _NfoFilePath
 64        End Get
 65        Set(ByVal value As String)
 66            If _NfoFilePath <> value And _NfoFilePath IsNot Nothing Then Me.IsAltered = True
 67            Dim Parts() As String
 68            Parts = value.Split("\")
 69            _FolderPath = Parts(0)
 70            For I = 1 To Parts.GetUpperBound(0) - 1
 71                _FolderPath &= "\" & Parts(I)
 72            Next
 73            _FolderPath &= "\"
 74            _NfoFilePath = value
 75            EditAttribute("NfoPath", _NfoFilePath)
 76        End Set
 77    End Property
 78
 79    Protected Friend Sub EditAttribute(ByVal Name As String, ByVal Value As String)
 80
 81        If Me.Node.Attribute(Name) Is Nothing Then
 82            If Value IsNot Nothing Then
 83                Me.Node.Add(New XAttribute(Name, Value))
 84            Else
 85                Exit Sub
 86            End If
 87        Else
 88            If Value Is Nothing Then
 89                Me.Node.Attribute(Name).Remove()
 90
 91                Exit Sub
 92            End If
 93        End If
 94
 95        Me.Node.Attribute(Name).SetValue(Value)
 96
 97        If Me.CacheNode.Attribute(Name) Is Nothing Then
 98            If Value IsNot Nothing Then
 99                Me.CacheNode.Add(New XAttribute(Name, Value))
100            Else
101                Exit Sub
102            End If
103        Else
104            If Value Is Nothing Then
105                Me.CacheNode.Attribute(Name).Remove()
106
107                Exit Sub
108            End If
109        End If
110
111        Me.CacheNode.Attribute(Name).SetValue(Value)
112    End Sub
113
114
115    Protected Friend Function GetAttribute(ByVal Name As String) As String
116
117        If Me.Node.Attribute(Name) IsNot Nothing Then
118            Return Me.Node.Attribute(Name).Value
119        ElseIf Me.CacheNode.Attribute(Name) IsNot Nothing Then
120            Return Me.CacheNode.Attribute(Name).Value
121        Else
122            Return Nothing
123        End If
124    End Function
125
126    Private _FolderPath As String
127    Public Property FolderPath As String Implements IProtoXBase.FolderPath
128        Get
129            Return _FolderPath
130        End Get
131        Set(value As String)
132            _FolderPath = value
133            If _NfoFilePath IsNot Nothing Then
134                _NfoFilePath = IO.Path.Combine(value, IO.Path.GetFileName(_NfoFilePath))
135            End If
136
137        End Set
138    End Property
139
140    Public Overridable Sub Load() Implements IProtoXFile.Load
141        Me.Load(Me.NfoFilePath)
142        Me.IsAltered = False
143        Me.IsCache = False
144    End Sub
145
146    Public Property FailedLoad As Boolean
147
148    Public Overridable Sub Load(ByVal Path As String) Implements IProtoXFile.Load
149        Me.IsAltered = True
150        Me.CleanDoc()
151        If IO.File.Exists(Path) Then
152            Try
153                Me.Doc = XDocument.Load(Path)
154                Me.Doc.DescendantNodes.OfType(Of XComment)().Remove()
155            Catch
156                FailedLoad = True
157                Exit Sub
158            End Try
159        Else
160            Exit Sub
161        End If
162        LoadDoc()
163    End Sub
164
165
166    Public Sub LoadXml(ByVal Input As XNode)
167        Me.Doc = New XDocument(Input)
168        LoadDoc()
169        Me.IsAltered = False    'These two properties have been moved here from TvCache.vb:Load() as this function is the
170        Me.IsCache = True       'only one that uses LoadXml(XNode) so far. Please note if using this. - HueyHQ 27Feb2013
171    End Sub
172
173
174    Public Sub LoadXml(ByVal Input As String)
175        Me.IsAltered = True
176        Me.Doc = XDocument.Parse(Input)
177
178        LoadDoc()
179    End Sub
180
181    Protected Overridable Sub LoadDoc()
182        If Me.Doc.Root Is Nothing Then Throw New Exception("Invalid NFO file")
183        Me._node = Me.Doc.Root
184        Dim Root As XElement = Me.Doc.Root
185
186        Dim ChildProperty As IProtoXChild
187        Dim XElementList As New List(Of XElement)
188        If Root.Name = "multiepisodenfo" Then
189            For Each episode As XElement In Root.Nodes
190                For Each Child As XNode In episode.Nodes
191                    If TypeOf Child Is XElement Then
192                        XElementList.Add(Child)
193                    Else
194                        Dim Test As Boolean = False
195                    End If
196                Next
197
198            Next
199        Else
200            For Each Child As XNode In Root.Nodes
201                If TypeOf Child Is XElement Then
202                    XElementList.Add(Child)
203                Else
204                    Dim Test As Boolean = False
205                End If
206            Next
207        End If
208
209        For Each Child As XElement In XElementList
210            If Me.ChildrenLookup.ContainsKey(Child.Name.ToString.ToLower) Then
211                ChildProperty = Me.ChildrenLookup.Item(Child.Name.ToString.ToLower)
212
213                ChildProperty.ProcessNode(Child)
214                Dim ChanceToSeeChild As Boolean = True
215            End If
216        Next
217
218        Me.CleanDoc()
219        Me.IsCache = False
220    End Sub
221
222    Public Sub DeleteElement(ByVal elementName As String)
223        CleanNode(Doc.Root, elementName)
224        'Me.SurpressAlter = True
225    End Sub
226
227    Public Sub Save() Implements IProtoXFile.Save
228        Me.IsAltered = False
229        Me.Save(Me.NfoFilePath)
230    End Sub
231
232    Public Sub Save(ByVal Path As String) Implements IProtoXFile.Save
233        'IsAltred shouldn't be set here, Save() isn't called the actual file referenced in NfoFilePath may not match what is in the current file
234        Me.CleanDoc()
235        Dim myloop As Boolean = True
236        Do
237            If Not DirectCast(Doc.FirstNode, System.Xml.Linq.XElement).FirstAttribute Is Nothing Then
238                DirectCast(Doc.FirstNode, System.Xml.Linq.XElement).FirstAttribute.Remove() '   Value = "Removed - Now Not Used!"
239            Else
240                myloop = False
241            End If
242        Loop While myloop
243        Doc.Save(Path)
244        'Dim settings As New XmlWriterSettings()
245        'settings.Encoding = New UTF8Encoding(False)
246        'settings.Indent = True
247        'settings.IndentChars = (ControlChars.Tab)
248        'settings.NewLineHandling = NewLineHandling.None
249        'Dim writer As XmlWriter = XmlWriter.Create(Path, settings)
250        'Doc.Save(writer)
251        'writer.Close()
252        Me.IsCache = False
253    End Sub
254
255    Private Sub CleanDoc()
256        CleanNode(Doc.Root)
257    End Sub
258
259    Private Sub CleanNode(ByVal Element As XElement, ByVal Optional elementName As String = "")
260        Dim Cursor As XElement
261        Dim NextOne As XNode
262        If Element Is Nothing Then Exit Sub
263        If Element.FirstNode Is Nothing Then
264            Element.Remove()
265            Exit Sub
266        End If
267
268        If Element.FirstNode.NodeType = Xml.XmlNodeType.Text Then
269            Exit Sub
270        End If
271
272        Cursor = Element.FirstNode
273
274        Do
275            NextOne = Cursor.NextNode
276            If Cursor.Nodes.Count = 0 AndAlso Cursor.Attributes.Count = 0 OrElse Cursor.Name.LocalName = elementName Then
277                Cursor.Remove()
278            Else
279                CleanNode(Cursor)
280            End If
281            Cursor = NextOne
282        Loop Until Cursor Is Nothing
283
284        If Element.Nodes.Count = 0 AndAlso Element.Attributes.Count = 0 Then
285            Element.Remove()
286        End If
287    End Sub
288
289#End Region
290
291    Public ReadOnly Property FileContainsReadableXml As Boolean Implements IProtoXFile.FileContainsReadableXml
292        Get
293            Try
294                If Me.FileExists Then
295                    Dim Test As XDocument = XDocument.Load(Me.NfoFilePath)
296                Else
297                    Return False
298                End If
299            Catch ex As Exception
300                Return False
301            End Try
302            Return True
303        End Get
304    End Property
305
306    Public ReadOnly Property FileExists As Boolean Implements IProtoXFile.FileExists
307        Get
308            Return IO.File.Exists(Me.NfoFilePath)
309        End Get
310    End Property
311
312    Public Sub HandleChildValueChanged(ByRef ProtoChild As ProtoXChildBase) Implements IProtoXBase.HandleChildValueChanged
313        Me.IsAltered = True
314        RaiseEvent ValueChanged(ProtoChild)
315    End Sub
316
317    Public Sub RaiseValueChanged(ByRef ProtoChild As ProtoXChildBase) Implements IProtoXBase.RaiseValueChanged
318        Me.IsAltered = True
319        RaiseEvent ValueChanged(ProtoChild)
320    End Sub
321
322    Public Event ValueChanged(ByRef ProtoChild As ProtoXChildBase) Implements IProtoXBase.ValueChanged
323
324    Public Property IsAltered As Boolean Implements IProtoXBase.IsAltered
325
326    Private Property SurpressAlter As Boolean Implements IProtoXBase.SurpressAlter
327
328    Public Sub SortNodes()
329        For Each Item In ChildrenLookup.Values
330            Item.Node.Remove()
331        Next
332
333        'Sort decending so that we can add nodes with an order first, and ones without at the bottom
334        For Each Item In (From Items As IProtoXChild In ChildrenLookup.Values Order By Items.SortIndex Descending)
335            If Item.SortIndex = -1 Then
336                Me.Node.Add(Item.Node)
337            Else
338                Me.Node.AddFirst(Item.Node)
339            End If
340
341        Next
342    End Sub
343
344End Class