///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>parses extension elements, needs to happen when known attributes are done</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="baseObject">the base object to set the property on</param> ////////////////////////////////////////////////////////////////////// protected void ParseExtensionElements(XmlReader reader, AtomBase baseObject) { //Tracing.TraceCall(); if (reader == null) { throw new System.ArgumentNullException("reader", "No XmlReader supplied"); } if (baseObject == null) { throw new System.ArgumentNullException("baseObject", "No baseObject supplied"); } if (IsCurrentNameSpace(reader, BaseNameTable.NSAtom)) { //Tracing.TraceInfo("Found an unknown ATOM element = this might be a bug, either in the code or the document"); //Tracing.TraceInfo("element: " + reader.LocalName + " position: " + reader.NodeType.ToString()); // maybe we should throw here, but I rather not - makes parsing more flexible } else { // everything NOT in Atom, call it //Tracing.TraceInfo("Found an unknown element"); this.OnNewExtensionElement(reader, baseObject); // position back to the element reader.MoveToElement(); } }
////////////////////////////////////////////////////////////////////// /// <summary>Walker action. Just gets a property.</summary> /// <param name="atom">object to set the property on</param> /// <returns>the value of the dirty flag</returns> ////////////////////////////////////////////////////////////////////// public bool Go(AtomBase atom) { //Tracing.Assert(atom != null, "atom should not be null"); if (atom == null) { throw new ArgumentNullException("atom"); } return(atom.Dirty); }
////////////////////////////////////////////////////////////////////// /// <summary>Walker action. Just sets a property.</summary> /// <param name="atom">object to set the property on </param> /// <returns> always false, indicating to walk the whole tree</returns> ////////////////////////////////////////////////////////////////////// public bool Go(AtomBase atom) { //Tracing.Assert(atom != null, "atom should not be null"); if (atom == null) { throw new ArgumentNullException("atom"); } atom.SetVersionInfo(v); return(false); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>parses an xml stream to create an AtomCategory object</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="owner">the object containing the person</param> /// <returns> the created AtomCategory object</returns> ////////////////////////////////////////////////////////////////////// protected AtomCategory ParseCategory(XmlReader reader, AtomBase owner) { //Tracing.TraceCall(); //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } if (owner == null) { throw new ArgumentNullException("owner"); } AtomCategory category = owner.CreateAtomSubElement(reader, this) as AtomCategory; if (category != null) { bool noChildren = reader.IsEmptyElement; if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { object localname = reader.LocalName; if (localname.Equals(this.nameTable.Term)) { category.Term = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(this.nameTable.Scheme)) { category.Scheme = new AtomUri(reader.Value); } else if (localname.Equals(this.nameTable.Label)) { category.Label = Utilities.DecodedValue(reader.Value); } else { ParseBaseAttributes(reader, category); } } } if (noChildren == false) { reader.MoveToElement(); int lvl = -1; while (NextChildElement(reader, ref lvl)) { ParseExtensionElements(reader, category); } } } return(category); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>Parses the base attributes and puts the rest in extensions. /// This needs to happen AFTER known attributes are parsed.</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="baseObject">the base object to set the property on</param> /// <returns> true if an unknown attribute was found</returns> ////////////////////////////////////////////////////////////////////// protected bool ParseBaseAttributes(XmlReader reader, AtomBase baseObject) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } //Tracing.Assert(baseObject != null, "baseObject should not be null"); if (baseObject == null) { throw new ArgumentNullException("baseObject"); } bool fRet = false; fRet = true; object localName = reader.LocalName; //Tracing.TraceCall(); if (IsCurrentNameSpace(reader, BaseNameTable.NSXml)) { if (localName.Equals(this.nameTable.Base)) { baseObject.Base = new AtomUri(reader.Value); fRet = false; } else if (localName.Equals(this.nameTable.Language)) { baseObject.Language = Utilities.DecodedValue(reader.Value); fRet = false; } } else if (IsCurrentNameSpace(reader, BaseNameTable.gNamespace)) { ISupportsEtag se = baseObject as ISupportsEtag; if (se != null) { if (localName.Equals(this.nameTable.ETag)) { se.Etag = reader.Value; fRet = false; } } } if (fRet == true) { //Tracing.TraceInfo("Found an unknown attribute"); this.OnNewExtensionElement(reader, baseObject); } return(fRet); }
////////////////////////////////////////////////////////////////////// /// <summary>Walker action. Just gets a property.</summary> /// <param name="atom">object to set the property on </param> /// <returns>returns the value of the ShouldBePersisted() of the object</returns> ////////////////////////////////////////////////////////////////////// public bool Go(AtomBase atom) { //Tracing.Assert(atom != null, "atom should not be null"); if (atom == null) { throw new ArgumentNullException("atom"); } bool f = atom.ShouldBePersisted(); //Tracing.TraceInfo(atom.ToString() + " ... is persistable: " + f.ToString()); return(f); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>parses an AtomGenerator</summary> /// <param name="reader">the xmlreader correctly positioned at the generator </param> /// <param name="owner">the container element</param> /// <returns> </returns> ////////////////////////////////////////////////////////////////////// protected AtomGenerator ParseGenerator(XmlReader reader, AtomBase owner) { // atomGenerator = element atom:generator { // atomCommonAttributes, // attribute url { atomUri }?, // attribute version { text }?, // text // } //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } if (owner == null) { throw new ArgumentNullException("owner"); } //Tracing.TraceCall(); AtomGenerator generator = owner.CreateAtomSubElement(reader, this) as AtomGenerator; if (generator != null) { generator.Text = Utilities.DecodedValue(reader.ReadString()); if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { object attributeName = reader.LocalName; if (attributeName.Equals(this.nameTable.Uri)) { generator.Uri = new AtomUri(reader.Value); } else if (attributeName.Equals(this.nameTable.Version)) { generator.Version = Utilities.DecodedValue(reader.Value); } else { ParseBaseAttributes(reader, generator); } } } } return(generator); }
////////////////////////////////////////////////////////////////////// /// <summary>parses an AtomTextConstruct</summary> /// <param name="reader">the xmlreader correctly positioned at the construct </param> /// <param name="owner">the container element</param> /// <returns>the new text construct </returns> ////////////////////////////////////////////////////////////////////// protected AtomTextConstruct ParseTextConstruct(XmlReader reader, AtomBase owner) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } if (owner == null) { throw new System.ArgumentNullException("owner"); } //Tracing.TraceCall("Parsing atomTextConstruct"); AtomTextConstruct construct = owner.CreateAtomSubElement(reader, this) as AtomTextConstruct; if (reader.NodeType == XmlNodeType.Element) { if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { object attributeName = reader.LocalName; if (attributeName.Equals(this.nameTable.Type)) { construct.Type = (AtomTextConstructType)Enum.Parse( typeof(AtomTextConstructType), Utilities.DecodedValue(reader.Value), true); } else { ParseBaseAttributes(reader, construct); } } } reader.MoveToElement(); switch (construct.Type) { case AtomTextConstructType.html: case AtomTextConstructType.text: construct.Text = Utilities.DecodedValue(reader.ReadString()); break; case AtomTextConstructType.xhtml: default: construct.Text = reader.ReadInnerXml(); break; } } return(construct); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>parses an author/person object</summary> /// <param name="reader"> an XmlReader positioned at the start of the author</param> /// <param name="owner">the object containing the person</param> /// <returns> the created author object</returns> ////////////////////////////////////////////////////////////////////// protected AtomPerson ParsePerson(XmlReader reader, AtomBase owner) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } //Tracing.Assert(owner != null, "owner should not be null"); if (owner == null) { throw new ArgumentNullException("owner"); } //Tracing.TraceCall(); object localname = null; AtomPerson author = owner.CreateAtomSubElement(reader, this) as AtomPerson; ParseBasicAttributes(reader, author); int lvl = -1; while (NextChildElement(reader, ref lvl)) { localname = reader.LocalName; if (localname.Equals(this.nameTable.Name)) { // author.Name = Utilities.DecodeString(Utilities.DecodedValue(reader.ReadString())); author.Name = Utilities.DecodedValue(reader.ReadString()); reader.Read(); } else if (localname.Equals(this.nameTable.Uri)) { author.Uri = new AtomUri(Utilities.DecodedValue(reader.ReadString())); reader.Read(); } else if (localname.Equals(this.nameTable.Email)) { author.Email = Utilities.DecodedValue(reader.ReadString()); reader.Read(); } else { // default extension parsing. ParseExtensionElements(reader, author); } } return(author); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>eventfiring helper for new extensions</summary> /// <param name="node"> the new node that was found</param> /// <param name="baseObject"> the object this node should be added to</param> ////////////////////////////////////////////////////////////////////// protected void OnNewExtensionElement(XmlNode node, AtomBase baseObject) { ExtensionElementEventArgs args = new ExtensionElementEventArgs(); args.ExtensionElement = node; args.Base = baseObject; if (this.NewExtensionElement != null) { this.NewExtensionElement(this, args); } if (args.DiscardEntry == false) { baseObject.ExtensionElements.Add(new XmlExtension(node)); } }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>tries to parse a category collection document</summary> /// <param name="reader"> xmlReader positioned at the start element</param> /// <param name="owner">the base object that the collection belongs to</param> /// <returns></returns> ////////////////////////////////////////////////////////////////////// public AtomCategoryCollection ParseCategories(XmlReader reader, AtomBase owner) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } AtomCategoryCollection ret = new AtomCategoryCollection(); MoveToStartElement(reader); //Tracing.TraceCall("entering Categories Parser"); object localname = reader.LocalName; //Tracing.TraceInfo("localname is: " + reader.LocalName); if (IsCurrentNameSpace(reader, BaseNameTable.AppPublishingNamespace(owner)) && localname.Equals(this.nameTable.Categories)) { //Tracing.TraceInfo("Found categories document"); int depth = -1; while (NextChildElement(reader, ref depth)) { localname = reader.LocalName; if (IsCurrentNameSpace(reader, BaseNameTable.NSAtom)) { if (localname.Equals(this.nameTable.Category)) { AtomCategory category = ParseCategory(reader, owner); ret.Add(category); } } } } else { //Tracing.TraceInfo("ParseCategories called and nothing was parsed" + localname); throw new ClientFeedException("An invalid Atom Document was passed to the parser. This was not an app:categories document: " + localname); } return(ret); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>eventfiring helper for new extensions</summary> /// <param name="reader"> the reader positioned on the extension</param> /// <param name="baseObject"> the object this node should be added to</param> ////////////////////////////////////////////////////////////////////// protected void OnNewExtensionElement(XmlReader reader, AtomBase baseObject) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } //Tracing.Assert(baseObject != null, "baseObject should not be null"); if (baseObject == null) { throw new ArgumentNullException("baseObject"); } if (reader.NodeType == XmlNodeType.Element || reader.NodeType == XmlNodeType.Attribute) { XmlNode node = this.Document.ReadNode(reader); if (node != null) { OnNewExtensionElement(node, baseObject); } } }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>nifty loop to check for base attributes for an object</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="baseObject">the base object to set the property on</param> ////////////////////////////////////////////////////////////////////// protected void ParseBasicAttributes(XmlReader reader, AtomBase baseObject) { //Tracing.TraceCall(); //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } //Tracing.Assert(baseObject != null, "baseObject should not be null"); if (baseObject == null) { throw new ArgumentNullException("baseObject"); } if (reader.NodeType == XmlNodeType.Element && reader.HasAttributes) { while (reader.MoveToNextAttribute()) { ParseBaseAttributes(reader, baseObject); } // position back to the element reader.MoveToElement(); } }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>Inserts an AtomBase entry against a Uri. The overloaded /// version here will check if this is an AbstractEntry and if it has /// a media property set. If so, it will create a mime multipart envelope</summary> /// <param name="feedUri">the uri for the feed this object should be posted against</param> /// <param name="baseEntry">the entry to be inserted</param> /// <param name="type">the type of request to create</param> /// <param name="data">the async data payload</param> /// <returns> the response as a stream</returns> ////////////////////////////////////////////////////////////////////// internal override Stream EntrySend(Uri feedUri, AtomBase baseEntry, GDataRequestType type, AsyncSendData data) { if (feedUri == null) { throw new ArgumentNullException("feedUri"); } //Tracing.Assert(baseEntry != null, "baseEntry should not be null"); if (baseEntry == null) { throw new ArgumentNullException("baseEntry"); } AbstractEntry entry = baseEntry as AbstractEntry; // if the entry is not an abstractentry or if no media is set, do the default if (entry == null || entry.MediaSource == null) { return(base.EntrySend(feedUri, baseEntry, type, data)); } Stream outputStream = null; Stream inputStream = null; try { IGDataRequest request = this.RequestFactory.CreateRequest(type, feedUri); request.Credentials = this.Credentials; GDataRequest r = request as GDataRequest; if (r != null) { r.ContentType = MediaService.MimeContentType; r.Slug = entry.MediaSource.Name; GDataRequestFactory f = this.RequestFactory as GDataRequestFactory; if (f != null) { f.CustomHeaders.Add("MIME-version: 1.0"); } } if (data != null) { GDataGAuthRequest gr = request as GDataGAuthRequest; if (gr != null) { gr.AsyncData = data; } } outputStream = request.GetRequestStream(); inputStream = entry.MediaSource.GetDataStream(); StreamWriter w = new StreamWriter(outputStream); w.WriteLine("Media multipart posting"); CreateBoundary(w, GDataRequestFactory.DefaultContentType); baseEntry.SaveToXml(outputStream); w.WriteLine(); CreateBoundary(w, entry.MediaSource.ContentType); WriteInputStreamToRequest(inputStream, outputStream); w.WriteLine(); w.WriteLine("--" + MediaService.MimeBoundary + "--"); w.Flush(); request.Execute(); outputStream.Close(); outputStream = null; return(request.GetResponseStream()); } catch (Exception) { throw; } finally { if (outputStream != null) { outputStream.Close(); } if (inputStream != null) { inputStream.Close(); } } }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>creates an atomlink object</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="owner">the object containing the person</param> /// <returns> the created AtomLink object</returns> ////////////////////////////////////////////////////////////////////// protected AtomLink ParseLink(XmlReader reader, AtomBase owner) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } if (owner == null) { throw new ArgumentNullException("owner"); } bool noChildren = reader.IsEmptyElement; //Tracing.TraceCall(); AtomLink link = owner.CreateAtomSubElement(reader, this) as AtomLink; object localname = null; if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { localname = reader.LocalName; if (localname.Equals(this.nameTable.HRef)) { link.HRef = new AtomUri(reader.Value); } else if (localname.Equals(this.nameTable.Rel)) { link.Rel = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(this.nameTable.Type)) { link.Type = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(this.nameTable.HRefLang)) { link.HRefLang = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(this.nameTable.Title)) { link.Title = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(this.nameTable.Length)) { link.Length = int.Parse(Utilities.DecodedValue(reader.Value), CultureInfo.InvariantCulture); } else { ParseBaseAttributes(reader, link); } } } if (noChildren == false) { reader.MoveToElement(); int lvl = -1; while (NextChildElement(reader, ref lvl)) { ParseExtensionElements(reader, link); } } return(link); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>creates an AtomContent object by parsing an xml stream</summary> /// <param name="reader">a XMLReader positioned correctly </param> /// <param name="owner">the container element</param> /// <returns> null or an AtomContent object</returns> ////////////////////////////////////////////////////////////////////// protected AtomContent ParseContent(XmlReader reader, AtomBase owner) { //Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } if (owner == null) { throw new ArgumentNullException("owner"); } AtomContent content = owner.CreateAtomSubElement(reader, this) as AtomContent; //Tracing.TraceCall(); if (content != null) { if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { object localname = reader.LocalName; if (localname.Equals(this.nameTable.Type)) { content.Type = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(this.nameTable.Src)) { content.Src = new AtomUri(reader.Value); } else { ParseBaseAttributes(reader, content); } } } if (MoveToStartElement(reader) == true) { if (content.Type.Equals("text") || content.Type.Equals("html") || content.Type.StartsWith("text/")) { // if it's text it get's just the string treatment. No // subelements are allowed here content.Content = Utilities.DecodedValue(reader.ReadString()); } else if (content.Type.Equals("xhtml") || content.Type.Contains("/xml") || content.Type.Contains("+xml")) { // do not get childlists if the element is empty. That would skip to the next element if (reader.IsEmptyElement == false) { // everything else will be nodes in the extension element list // different media type. Create extension elements int lvl = -1; while (NextChildElement(reader, ref lvl)) { ParseExtensionElements(reader, content); } } } else { // everything else SHOULD be base 64 encoded, so one big string // i know the if statement could be combined with the text handling // but i consider it clearer to make a 3 cases statement than combine them content.Content = Utilities.DecodedValue(reader.ReadString()); } } } return(content); }