/* * Copyright 2012 Splunk, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"): you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ namespace Splunk { using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Xml; /// /// Represents the Atom Entry data. /// public class AtomEntry : AtomObject { /// /// Gets or sets the value of the Atom entry's published element. /// public string Published { get; set; } /// /// Gets or sets the value of the Atom entry's content element. /// public Record Content { get; set; } /// /// Creates a new instance of the class. /// /// An AtomEntry private static AtomEntry Create() { AtomEntry atomEntry = new AtomEntry(); atomEntry.Links = new Dictionary(); return atomEntry; } /// /// Creates a new AtomEntry instance based on a given stream. /// A few endpoints, such as search/jobs/{sid} /// return an Atom entry element as the root of the response. /// /// The IO stream /// An AtomEntry public static AtomEntry Parse(Stream input) { XmlElement root = Xml.Parse(input).DocumentElement; string rname = root.Name; string xmlns = root.GetAttribute("xmlns"); if (!rname.Equals("entry") && !xmlns.Equals("http://www.w3.org/2005/Atom")) { throw new Exception("Unrecognized XML format"); } return AtomEntry.Parse(root); } /// /// Creates a new AtomEntry instance based on a given XML element. /// /// The XML element /// An AtomEntry public static AtomEntry Parse(XmlElement element) { AtomEntry entry = AtomEntry.Create(); entry.Load(element); return entry; } /// /// Initializes the current AtomEntry instance with a given XML element. /// /// The XML element public override void Init(XmlElement element) { string name = element.Name; if (name.Equals("published")) { this.Published = element.InnerText; } else if (name.Equals("content")) { this.Content = this.ParseContent(element); } else { base.Init(element); } } /// /// Returns a filtered list of child XML element nodes. This helper /// function makes it easier to retrieve only the element children /// of a given XML element. /// /// The XML element /// XML element list public static List GetChildElements(XmlElement element) { List result = new List(); foreach (XmlNode child in element.ChildNodes) { if (child.NodeType == XmlNodeType.Element) { result.Add((XmlElement)child); } } return result; } /// /// Parses the content element of an Atom entry. /// /// The XML element /// The content Record public Record ParseContent(XmlElement element) { Trace.Assert(element.LocalName.Equals("content")); Record content = null; List children = GetChildElements(element); int count = children.Count; // Expect content to be empty or a single element Trace.Assert(count == 0 || count == 1); if (count == 1) { XmlElement child = children[0]; content = this.ParseDict(child); } return content; } /// /// Parses a dictinary content element and returns a Record /// object containing the parsed values. /// /// An XML element /// The Record public Record ParseDict(XmlElement element) { Trace.Assert(element.Name.Equals("s:dict")); if (element.FirstChild == null) { return null; } List children = GetChildElements(element); int count = children.Count; if (count == 0) { return null; } Record result = new Record(); foreach (XmlElement child in children) { Trace.Assert(child.Name.Equals("s:key")); string key = child.GetAttribute("name"); object value = this.ParseValue(child); if (value != null) { result.Add(key, value); } } return result; } /// /// Parses a list element and return a List object /// containing the parsed values. /// /// An XML element /// The list of parsed values public List ParseList(XmlElement element) { Trace.Assert(element.Name.Equals("s:list")); if (element.FirstChild == null) { return null; } List children = GetChildElements(element); int count = children.Count; if (count == 0) { return null; } List result = new List(count); foreach (XmlElement child in children) { Trace.Assert(child.Name.Equals("s:item")); object value = this.ParseValue(child); if (value != null) { result.Add(value); } } return result; } /// /// Parses the value content of a dictionary/key or a list/item element. /// The value is either text, a dictionary element, or a list element. /// /// The XML element /// Either the dictionary or list of values public object ParseValue(XmlElement element) { string name = element.Name; Trace.Assert(name.Equals("s:key") || name.Equals("s:item")); if (element.FirstChild == null) { return null; } List children = GetChildElements(element); int count = children.Count; // If no element children, then it must be a text value if (count == 0) { return element.InnerText; } // If its not a text value, then expect a single child element. Trace.Assert(children.Count == 1); XmlElement child = children[0]; name = child.Name; if (name.Equals("s:dict")) { return this.ParseDict(child); } if (name.Equals("s:list")) { return this.ParseList(child); } Trace.Assert(false); // Unreached return null; } } }