/// <summary>sets up the correct credentials for this call, pending /// security scheme</summary> protected override void EnsureCredentials() { Tracing.Assert(this.Request != null, "We should have a webrequest now"); if (this.Request == null) { return; } // if the token is NULL, we need to get a token. if (this.factory.GAuthToken == null) { // we will take the standard credentials for that GDataCredentials gc = this.Credentials; Tracing.TraceMsg(gc == null ? "No Network credentials set" : "Network credentials found"); if (gc != null) { // only now we have something to do... this.factory.GAuthToken = QueryAuthToken(gc); } } if (this.factory.GAuthToken != null && this.factory.GAuthToken.Length > 0) { // Tracing.Assert(this.factory.GAuthToken != null, "We should have a token now"); Tracing.TraceMsg("Using auth token: " + this.factory.GAuthToken); string strHeader = GoogleAuthentication.Header + this.factory.GAuthToken; this.Request.Headers.Add(strHeader); } }
/// <summary> /// reads the current positioned reader and creates a operationtype enum /// </summary> /// <param name="reader">XmlReader positioned at the start of the status element</param> /// <returns>GDataBatchOperationType</returns> protected GDataBatchOperationType ParseOperationType(XmlReader reader) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } GDataBatchOperationType type = GDataBatchOperationType.Default; object localname = reader.LocalName; if (localname.Equals(this.nameTable.BatchOperation)) { if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { localname = reader.LocalName; if (localname.Equals(this.nameTable.Type)) { type = (GDataBatchOperationType)Enum.Parse( typeof(GDataBatchOperationType), Utilities.DecodedValue(reader.Value), true); } } } } return(type); }
/// <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>basic constructor for the atomUri</summary> public AtomUri(Uri uri) { Tracing.Assert(uri != null, "uri should not be null"); if (uri == null) { throw new ArgumentNullException("uri"); } this.strContent = HttpUtility.UrlDecode(uri.ToString()); }
/// <summary> /// adding an extension factory for extension elements /// </summary> /// <param name="factory">The factory</param> // public void AddExtension(IExtensionElementFactory factory) public void AddExtension(IExtensionElementFactory factory) { Tracing.Assert(factory != null, "factory should not be null"); if (factory == null) { throw new ArgumentNullException("factory"); } this.ExtensionFactories.Add(factory); }
/// <summary>Calls the action on this object and all children.</summary> /// <param name="action">an IBaseWalkerAction interface to call </param> /// <returns>true or false, pending outcome of the passed in action</returns> public virtual bool WalkTree(IBaseWalkerAction action) { Tracing.Assert(action != null, "action should not be null"); if (action == null) { throw new ArgumentNullException("action"); } return(action.Go(this)); }
/// <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> /// removing an extension factory for extension elements /// </summary> /// <param name="factory">The factory</param> public void RemoveExtension(IExtensionElementFactory factory) { Tracing.Assert(factory != null, "factory should not be null"); if (factory == null) { throw new ArgumentNullException("factory"); } this.ExtensionFactories.Remove(factory.XmlNameSpace, factory.XmlName); }
/// <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) { 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(); return(f); }
/// <summary> /// reads the current positioned reader and creates a batchstatus element /// </summary> /// <param name="reader">XmlReader positioned at the start of the status element</param> /// <param name="parser">The Feedparser to be used</param> /// <returns>GDataBatchStatus</returns> public static GDataBatchStatus ParseBatchStatus(XmlReader reader, AtomFeedParser parser) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } GDataBatchStatus status = null; object localname = reader.LocalName; if (localname.Equals(parser.Nametable.BatchStatus)) { status = new GDataBatchStatus(); if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { localname = reader.LocalName; if (localname.Equals(parser.Nametable.BatchReason)) { status.Reason = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(parser.Nametable.BatchContentType)) { status.ContentType = Utilities.DecodedValue(reader.Value); } else if (localname.Equals(parser.Nametable.BatchStatusCode)) { status.Code = int.Parse(Utilities.DecodedValue(reader.Value), CultureInfo.InvariantCulture); } } } reader.MoveToElement(); // FIX: THIS CODE SEEMS TO MAKE AN INFINITE LOOP WITH NextChildElement() int lvl = -1; // status can have one child element, errors while (Utilities.NextChildElement(reader, ref lvl)) { localname = reader.LocalName; if (localname.Equals(parser.Nametable.BatchErrors)) { GDataBatchError.ParseBatchErrors(reader, parser, status); } } } return(status); }
/// <summary>Checks to see if the URI is valid to be used for an Atom query.</summary> /// <returns>Throws a client exception if not</returns> static protected void ValidateUri(Uri uriToTest) { Tracing.Assert(uriToTest != null, "uriToTest should not be null"); if (uriToTest == null) { throw new ArgumentNullException("uriToTest"); } if (uriToTest.Scheme == Uri.UriSchemeFile || uriToTest.Scheme == Uri.UriSchemeHttp || uriToTest.Scheme == Uri.UriSchemeHttps) { return; } throw new ClientQueryException("Only HTTP/HTTPS 1.1 protocol is currently supported"); }
/// <summary>moves to the next element</summary> /// <param name="reader">the xmlreader to skip </param> static protected bool NextElement(XmlReader reader) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } while (reader.Read() && reader.NodeType != XmlNodeType.Element) { ; } return(!reader.EOF); }
/// <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>Event chaining. We catch this by the baseFeedParsers, which /// would not do anything with the gathered data. We pass the event up /// to the user; if the user doesn't discard it, we add the entry to our /// collection</summary> /// <param name="sender"> the object which send the event</param> /// <param name="e">FeedParserEventArguments, holds the feed entry</param> /// <returns> </returns> ////////////////////////////////////////////////////////////////////// protected void OnNewExtensionElement(object sender, ExtensionElementEventArgs e) { // by default, if our event chain is not hooked, the underlying parser will add it Tracing.TraceCall("received new extension element notification"); Tracing.Assert(e != null, "e should not be null"); if (e == null) { throw new ArgumentNullException("e"); } if (this.NewExtensionElement != null) { Tracing.TraceMsg("\t calling event dispatcher"); this.NewExtensionElement(sender, e); } }
/// <summary>checks to see if the passed in namespace is the current one</summary> /// <param name="reader">correctly positioned xmlreader</param> /// <param name="namespaceToCompare">the namespace to test for</param> /// <returns> true if this is the one</returns> static protected bool IsCurrentNameSpace(XmlReader reader, string namespaceToCompare) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } string curNamespace = reader.NamespaceURI; if (curNamespace.Length == 0) { curNamespace = reader.LookupNamespace(String.Empty); } return(curNamespace == namespaceToCompare); }
/// <summary>Inserts an AtomBase entry against a Uri</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 virtual Stream EntrySend(Uri feedUri, AtomBase baseEntry, GDataRequestType type, AsyncSendData data) { Tracing.Assert(feedUri != null, "feedUri should not be null"); if (feedUri == null) { throw new ArgumentNullException("feedUri"); } Tracing.Assert(baseEntry != null, "baseEntry should not be null"); if (baseEntry == null) { throw new ArgumentNullException("baseEntry"); } this.versionInfo.ImprintVersion(baseEntry); IGDataRequest request = this.RequestFactory.CreateRequest(type, feedUri); request.Credentials = this.Credentials; ISupportsEtag eTarget = request as ISupportsEtag; ISupportsEtag eSource = baseEntry as ISupportsEtag; if (eTarget != null && eSource != null) { eTarget.Etag = eSource.Etag; } request.ContentStore = baseEntry; request.IsBatch = type == GDataRequestType.Batch; if (data != null) { GDataGAuthRequest gr = request as GDataGAuthRequest; if (gr != null) { gr.AsyncData = data; } } Stream outputStream = request.GetRequestStream(); baseEntry.SaveToXml(outputStream); request.Execute(); outputStream.Close(); return(request.GetResponseStream()); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>Event chaining. We catch this by the baseFeedParsers, which /// would not do anything with the gathered data. We pass the event up /// to the user; if the user doesn't discard it, we add the entry to our /// collection</summary> /// <param name="sender"> the object which send the event</param> /// <param name="e">FeedParserEventArguments, holds the feed entry</param> /// <returns> </returns> ////////////////////////////////////////////////////////////////////// protected void OnParsedNewEntry(object sender, FeedParserEventArgs e) { // by default, if our event chain is not hooked, add it to the collection Tracing.TraceCall("received new item notification"); Tracing.Assert(e != null, "e should not be null"); if (e == null) { throw new ArgumentNullException("e"); } if (this.NewAtomEntry != null) { Tracing.TraceMsg("\t calling event dispatcher"); this.NewAtomEntry(this, e); } // now check the return if (!e.DiscardEntry) { if (!e.CreatingEntry) { if (e.Entry != null) { // add it to the collection Tracing.TraceMsg("\t new AtomEntry found, adding to collection"); e.Entry.Service = this.Service; this.Entries.Add(e.Entry); } else if (e.Feed != null) { // parsed a feed, set ourselves to it... Tracing.TraceMsg("\t Feed parsed found, parsing is done..."); } } else { IVersionAware v = e.Entry as IVersionAware; if (v != null) { v.ProtocolMajor = this.ProtocolMajor; v.ProtocolMinor = this.ProtocolMinor; } } } if (e.DoneParsing) { this.BaseUriChanged(this.ImpliedBase); } }
/// <summary>Saves the object as XML.</summary> /// <param name="stream">stream to save to</param> /// <returns>how many bytes written</returns> public void SaveToXml(Stream stream) { Tracing.Assert(stream != null, "stream should not be null"); if (stream == null) { throw new ArgumentNullException("stream"); } XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8); writer.Formatting = Formatting.Indented; writer.WriteStartDocument(); SaveToXml(writer); writer.Flush(); }
/// <summary>Sets the gDataBatch namespace, if it's not already set. /// </summary> /// <param name="writer"> the xmlwriter to use</param> /// <returns> the namespace prefix</returns> static public string EnsureGDataBatchNamespace(XmlWriter writer) { Tracing.Assert(writer != null, "writer should not be null"); if (writer == null) { throw new ArgumentNullException("writer"); } string strPrefix = writer.LookupPrefix(BaseNameTable.gBatchNamespace); if (strPrefix == null) { writer.WriteAttributeString("xmlns", BaseNameTable.gBatchPrefix, null, BaseNameTable.gBatchNamespace); } return(strPrefix); }
/// <summary>protected WriteElementStart(XmlWriter writer)</summary> /// <param name="writer"> the xmlwriter to use</param> /// <param name="elementName"> the elementToPersist to use</param> protected void WriteElementStart(XmlWriter writer, string elementName) { Tracing.Assert(writer != null, "writer should not be null"); if (writer == null) { throw new ArgumentNullException("writer"); } if (!IsAtomDefaultNamespace(writer)) { writer.WriteStartElement("atom", elementName, BaseNameTable.NSAtom); } else { writer.WriteStartElement(elementName); } }
/// <summary> /// returns the next child element of the xml reader, based on the /// depth passed in. /// </summary> /// <param name="reader">the xml reader to use</param> /// <param name="depth">the depth to start with</param> /// <returns></returns> public static bool NextChildElement(XmlReader reader, ref int depth) { Tracing.Assert(reader != null, "reader should not be null"); if (reader == null) { throw new ArgumentNullException("reader"); } if (reader.Depth == depth) { // assume we gone around circle, a child read and moved to the next element of the same KIND return(false); } if (reader.NodeType == XmlNodeType.Element && depth >= 0 && reader.Depth > depth) { // assume we gone around circle, a child read and moved to the next element of the same KIND // but now we are in the parent/containing element, hence we return TRUE without reading further return(true); } if (depth == -1) { depth = reader.Depth; } while (reader.Read()) { if (reader.NodeType == XmlNodeType.EndElement && reader.Depth <= depth) { return(false); } else if (reader.NodeType == XmlNodeType.Element && reader.Depth > depth) { return(true); } else if (reader.NodeType == XmlNodeType.Element && reader.Depth == depth) { // assume that we had no children. We read once and we are at the // next element, same level as the previous one. return(false); } } return(!reader.EOF); }
/// <summary>saves the object as XML</summary> /// <param name="writer">the xmlwriter to save to</param> public void SaveToXml(XmlWriter writer) { Tracing.Assert(writer != null, "writer should not be null"); if (writer == null) { throw new ArgumentNullException("writer"); } if (IsPersistable()) { WriteElementStart(writer, this.XmlName); SaveXmlAttributes(writer); SaveInnerXml(writer); writer.WriteEndElement(); } this.MarkElementDirty(false); }
/// <summary>WebResponse Update(Uri updateUri, Stream entryStream, ICredentials credentials)</summary> /// <param name="entry">the old entry to update</param> /// <param name="data">the async data block used</param> /// <returns> the new Entry, as returned from the server</returns> private AtomEntry Update(AtomEntry entry, AsyncSendData data) { Tracing.Assert(entry != null, "entry should not be null"); if (entry == null) { throw new ArgumentNullException("entry"); } if (entry.ReadOnly) { throw new GDataRequestException("Can not update a read-only entry"); } Uri target = new Uri(entry.EditUri.ToString()); Stream returnStream = EntrySend(target, entry, GDataRequestType.Update, data); return(CreateAndParseEntry(returnStream, target)); }
/// <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) { 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>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>public WebResponse Insert(Uri insertUri, Stream entryStream, ICredentials credentials)</summary> /// <param name="feedUri">the uri for the feed this entry should be inserted into</param> /// <param name="newEntry">the entry to be inserted</param> /// <param name="data">the data used for an async request</param> /// <returns> the inserted entry</returns> private AtomEntry Insert(Uri feedUri, AtomEntry newEntry, AsyncSendData data) { Tracing.Assert(feedUri != null, "feedUri should not be null"); if (feedUri == null) { throw new ArgumentNullException("feedUri"); } Tracing.Assert(newEntry != null, "newEntry should not be null"); if (newEntry == null) { throw new ArgumentNullException("newEntry"); } this.versionInfo.ImprintVersion(newEntry); Stream returnStream = EntrySend(feedUri, newEntry, GDataRequestType.Insert, data); return(CreateAndParseEntry(returnStream, feedUri)); }