////////////////////////////////////////////////////////////////////// /// <summary>goes over all entries, and updates the ones that are dirty</summary> /// <returns> </returns> ////////////////////////////////////////////////////////////////////// public virtual void Publish() { if (this.Service != null) { for (int i = 0; i < this.Entries.Count; i++) { AtomEntry entry = this.Entries[i]; if (entry.IsDirty()) { if (entry.Id.Uri == null) { // new guy Tracing.TraceInfo("adding new entry: " + entry.Title.Text); this.Entries[i] = Service.Insert(this, entry); } else { // update the entry Tracing.TraceInfo("updating entry: " + entry.Title.Text); entry.Update(); } } } } this.MarkElementDirty(false); }
/// <summary> /// parses the current position in the xml reader and fills /// the provided GDataFeedBatch property on the feed object /// </summary> /// <param name="reader">the xmlreader positioned at a batch element</param> /// <param name="feed">the atomfeed object to fill in</param> protected void ParseBatch(XmlReader reader, AtomFeed feed) { if (reader == null) { throw new ArgumentNullException("reader"); } if (feed == null) { throw new ArgumentNullException("feed"); } if (IsCurrentNameSpace(reader, BaseNameTable.gBatchNamespace)) { object elementName = reader.LocalName; if (feed.BatchData == null) { feed.BatchData = new GDataBatchFeedData(); } GDataBatchFeedData batch = feed.BatchData; if (elementName.Equals(this.nameTable.BatchOperation)) { batch.Type = (GDataBatchOperationType)Enum.Parse(typeof(GDataBatchOperationType), reader.GetAttribute(BaseNameTable.XmlAttributeType), true); } else { Tracing.TraceInfo("got an unknown batch element: " + elementName.ToString()); reader.Skip(); } } }
/// <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>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 the current position in the xml reader and fills /// the provided GDataEntryBatch property on the entry object /// </summary> /// <param name="reader">the xmlreader positioned at a batch element</param> /// <param name="entry">the atomentry object to fill in</param> protected void ParseBatch(XmlReader reader, AtomEntry entry) { if (reader == null) { throw new ArgumentNullException("reader"); } if (entry == null) { throw new ArgumentNullException("entry"); } if (IsCurrentNameSpace(reader, BaseNameTable.gBatchNamespace)) { object elementName = reader.LocalName; if (entry.BatchData == null) { entry.BatchData = new GDataBatchEntryData(); } GDataBatchEntryData batch = entry.BatchData; if (elementName.Equals(this.nameTable.BatchId)) { batch.Id = Utilities.DecodedValue(reader.ReadString()); } else if (elementName.Equals(this.nameTable.BatchOperation)) { batch.Type = ParseOperationType(reader); } else if (elementName.Equals(this.nameTable.BatchStatus)) { batch.Status = GDataBatchStatus.ParseBatchStatus(reader, this); } else if (elementName.Equals(this.nameTable.BatchInterrupt)) { batch.Interrupt = GDataBatchInterrupt.ParseBatchInterrupt(reader, this); } else { Tracing.TraceInfo("got an unknown batch element: " + elementName.ToString()); // default extension parsing ParseExtensionElements(reader, entry); } } }
/// <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>reads in the feed properties, updates the feed object, then starts /// working on the entries...</summary> /// <param name="reader"> xmlReader positioned at the Feed element</param> /// <param name="feed">the basefeed object that should be set</param> /// <returns> notifies user using event mechanism</returns> protected void ParseFeed(XmlReader reader, AtomFeed feed) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } Tracing.Assert(feed != null, "feed should not be null"); if (feed == null) { throw new ArgumentNullException("feed"); } Tracing.TraceCall("entering AtomFeed Parser"); object localname = reader.LocalName; Tracing.TraceInfo("localname is: " + reader.LocalName); if (localname.Equals(this.nameTable.Feed)) { Tracing.TraceInfo("Found standard feed document"); // found the feed...... // now parse the source base of this element ParseSource(reader, feed); // feed parsing complete, send notfication this.OnNewAtomEntry(feed); } else if (localname.Equals(this.nameTable.Entry)) { Tracing.TraceInfo("Found entry document"); ParseEntry(reader); } else { Tracing.TraceInfo("ParseFeed called and nothing was parsed" + localname.ToString()); // throw new ClientFeedException("An invalid Atom Document was passed to the parser. Neither Feed nor Entry started the document"); } OnParsingDone(); feed.MarkElementDirty(false); }
/// <summary>executes the query and returns an AtomFeed object tree</summary> /// <param name="feedQuery">the query parameters as a FeedQuery object </param> /// <returns>AtomFeed object tree</returns> public AtomFeed Query(FeedQuery feedQuery) { AtomFeed feed = null; Tracing.TraceCall("Enter"); if (feedQuery == null) { throw new System.ArgumentNullException("feedQuery", "The query argument MUST not be null"); } // Create a new request to the Uri in the query object... Uri targetUri = null; try { targetUri = feedQuery.Uri; } catch (System.UriFormatException) { throw new System.ArgumentException("The query argument MUST contain a valid Uri", "feedQuery"); } Tracing.TraceInfo("Service:Query - about to query"); Stream responseStream = null; if (feedQuery.Etag != null) { responseStream = Query(targetUri, feedQuery.Etag); } else { responseStream = Query(targetUri, feedQuery.ModifiedSince); } Tracing.TraceInfo("Service:Query - query done"); if (responseStream != null) { feed = CreateAndParseFeed(responseStream, feedQuery.Uri); } Tracing.TraceCall("Exit"); return(feed); }
///////////////////////////////////////////////////////////////////////////// #endregion ////////////////////////////////////////////////////////////////////// /// <summary>given a stream, parses it to construct the Feed object out of it</summary> /// <param name="stream"> a stream representing hopefully valid XML</param> /// <param name="format"> indicates if the stream is Atom or Rss</param> ////////////////////////////////////////////////////////////////////// public void Parse(Stream stream, AlternativeFormat format) { Tracing.TraceCall("parsing stream -> Start:" + format.ToString()); BaseFeedParser feedParser = null; // make sure we reset our collections this.Authors.Clear(); this.Contributors.Clear(); this.Links.Clear(); this.Categories.Clear(); feedParser = new AtomFeedParser(this); // create a new delegate for the parser feedParser.NewAtomEntry += new FeedParserEventHandler(this.OnParsedNewEntry); feedParser.NewExtensionElement += new ExtensionElementEventHandler(this.OnNewExtensionElement); feedParser.Parse(stream, this); Tracing.TraceInfo("Parsing stream -> Done"); // done parsing }
////////////////////////////////////////////////////////////////////// /// <summary>helper method to create a new, decoupled entry based on a feedEntry</summary> /// <param name="entryToImport">the entry from a feed that you want to put somewhere else</param> /// <returns> the new entry ready to be inserted</returns> ////////////////////////////////////////////////////////////////////// public static AtomEntry ImportFromFeed(AtomEntry entryToImport) { Tracing.Assert(entryToImport != null, "entryToImport should not be null"); if (entryToImport == null) { throw new ArgumentNullException("entryToImport"); } AtomEntry entry = null; entry = (AtomEntry)Activator.CreateInstance(entryToImport.GetType()); entry.CopyEntry(entryToImport); entry.Id = null; // if the source is empty, set the source to the old feed if (entry.Source == null) { entry.Source = entryToImport.Feed; } Tracing.TraceInfo("Imported entry: " + entryToImport.Title.Text + " to: " + entry.Title.Text); return(entry); }