/core/externals/update-engine/externals/gdata-objectivec-client/Source/Elements/GDataEntryContent.m

http://macfuse.googlecode.com/ · Objective C · 266 lines · 158 code · 68 blank · 40 comment · 23 complexity · d7f4ce8a76d89fe43b785643c3469b66 MD5 · raw file

  1. /* Copyright (c) 2007-2008 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. //
  16. // GDataEntryContent.m
  17. //
  18. #define GDATAENTRYCONTENT_DEFINE_GLOBALS 1
  19. #import "GDataEntryContent.h"
  20. static NSString* const kLangAttr = @"xml:lang";
  21. static NSString* const kTypeAttr = @"type";
  22. static NSString* const kSourceAttr = @"src";
  23. static BOOL IsTypeEqualToText(NSString *str) {
  24. // internal utility routine
  25. return (str == nil)
  26. || [str isEqual:@"text"]
  27. || [str hasPrefix:@"text/"]
  28. || [str isEqual:@"html"]
  29. || [str isEqual:@"xhtml"];
  30. }
  31. @implementation GDataEntryContent
  32. + (NSString *)extensionElementURI { return kGDataNamespaceAtom; }
  33. + (NSString *)extensionElementPrefix { return kGDataNamespaceAtomPrefix; }
  34. + (NSString *)extensionElementLocalName { return @"content"; }
  35. + (id)contentWithString:(NSString *)str {
  36. // RFC4287 Sec 4.1.3.1. says that omitted type attributes are assumed to be
  37. // "text", so we don't need to explicitly set it to text
  38. GDataEntryContent *obj = [self object];
  39. [obj setStringValue:str];
  40. return obj;
  41. }
  42. + (id)contentWithSourceURI:(NSString *)str type:(NSString *)type {
  43. GDataEntryContent *obj = [self object];
  44. [obj setSourceURI:str];
  45. [obj setType:type];
  46. return obj;
  47. }
  48. + (id)contentWithXMLValue:(NSXMLNode *)node type:(NSString *)type {
  49. GDataEntryContent *obj = [self object];
  50. // declare that we'll be using child elements as XML values
  51. [obj addChildXMLElementsDeclaration];
  52. [obj setType:type];
  53. if (node != nil) {
  54. [obj addXMLValue:node];
  55. }
  56. return obj;
  57. }
  58. + (id)textConstructWithString:(NSString *)str {
  59. // deprecated; kept for compatibility with the previous
  60. // implementation of GDataEntryContent
  61. GDATA_DEBUG_LOG(@"GDataEntryContent: +textConstructWithString deprecated, use +contentWithString");
  62. return [self contentWithString:str];
  63. }
  64. - (void)addParseDeclarations {
  65. NSArray *attrs = [NSArray arrayWithObjects:
  66. kTypeAttr, kLangAttr, kSourceAttr, nil];
  67. [self addLocalAttributeDeclarations:attrs];
  68. // we're not calling -addContentValueDeclaration since the content may not
  69. // be plain text but rather XML for an entry or feed that we will parse
  70. }
  71. - (NSArray *)attributesIgnoredForEquality {
  72. // ignore the "type" attribute since we test for it uniquely below
  73. return [NSArray arrayWithObject:kTypeAttr];
  74. }
  75. - (void)parseAttributesForElement:(NSXMLElement *)element {
  76. // override the attribute parsing method
  77. //
  78. // once we have parsed the attributes, we can decide
  79. // how to parse the contents or children
  80. [super parseAttributesForElement:element];
  81. NSString *type = [self type];
  82. if (IsTypeEqualToText(type)) {
  83. // content is plain text
  84. [self addContentValueDeclaration];
  85. } else if ([type hasPrefix:@"application/atom+xml;"]) {
  86. // content is a feed or entry stored in unknownChildren
  87. GDataObject *obj = [self objectForChildOfElement:element
  88. qualifiedName:@"*"
  89. namespaceURI:@"*"
  90. objectClass:nil];
  91. [self setChildObject:obj];
  92. } else if ([type hasPrefix:kGDataContentTypeKML]) {
  93. // content is KML
  94. [self addChildXMLElementsDeclaration];
  95. }
  96. }
  97. - (void)dealloc {
  98. [childObject_ release];
  99. [super dealloc];
  100. }
  101. - (NSXMLElement *)XMLElement {
  102. NSXMLElement *element = [self XMLElementWithExtensionsAndDefaultName:nil];
  103. GDataObject *obj = [self childObject];
  104. if (obj) {
  105. NSXMLElement *elem = [obj XMLElement];
  106. [element addChild:elem];
  107. }
  108. return element;
  109. }
  110. - (id)copyWithZone:(NSZone *)zone {
  111. GDataEntryContent* newObj = [super copyWithZone:zone];
  112. [newObj setChildObject:[[[self childObject] copy] autorelease]];
  113. return newObj;
  114. }
  115. - (BOOL)isEqual:(GDataEntryContent *)other {
  116. // override isEqual: to allow nil types to be considered equal to "text"
  117. return [super isEqual:other]
  118. // a missing type attribute is equal to "text" per RFC 4287 3.1.1
  119. //
  120. // consider them equal if both are some flavor of "text"
  121. && (AreEqualOrBothNil([self type], [other type])
  122. || (IsTypeEqualToText([self type]) && IsTypeEqualToText([other type])))
  123. && AreEqualOrBothNil([self childObject], [other childObject]);
  124. }
  125. #if !GDATA_SIMPLE_DESCRIPTIONS
  126. - (NSMutableArray *)itemsForDescription {
  127. NSMutableArray *items = [super itemsForDescription];
  128. // if the base class is not storing the content value, we must provide the
  129. // description item here
  130. if (![self hasDeclaredContentValue]) {
  131. [self addToArray:items objectDescriptionIfNonNil:[self stringValue] withName:@"content"];
  132. }
  133. [self addToArray:items objectDescriptionIfNonNil:[self XMLValues] withName:@"xml"];
  134. GDataObject *obj = [self childObject];
  135. if (obj != nil) {
  136. NSString *className = NSStringFromClass([obj class]);
  137. [self addToArray:items objectDescriptionIfNonNil:className withName:@"childObject"];
  138. }
  139. return items;
  140. }
  141. #endif
  142. #pragma mark -
  143. - (NSString *)lang {
  144. return [self stringValueForAttribute:kLangAttr];
  145. }
  146. - (void)setLang:(NSString *)str {
  147. [self setStringValue:str forAttribute:kLangAttr];
  148. }
  149. - (NSString *)type {
  150. return [self stringValueForAttribute:kTypeAttr];
  151. }
  152. - (NSString *)sourceURI {
  153. return [self stringValueForAttribute:kSourceAttr];
  154. }
  155. - (void)setSourceURI:(NSString *)str {
  156. [self setStringValue:str forAttribute:kSourceAttr];
  157. }
  158. - (NSURL *)sourceURL {
  159. NSString *sourceURI = [self sourceURI];
  160. if ([sourceURI length] > 0) {
  161. NSURL *url = [NSURL URLWithString:sourceURI];
  162. return url;
  163. }
  164. return nil;
  165. }
  166. - (void)setType:(NSString *)str {
  167. [self setStringValue:str forAttribute:kTypeAttr];
  168. }
  169. - (NSString *)stringValue {
  170. if ([self hasDeclaredContentValue]) {
  171. return [self contentStringValue];
  172. }
  173. return nil;
  174. }
  175. - (void)setStringValue:(NSString *)str {
  176. if (![self hasDeclaredContentValue]) {
  177. // if we emit XML later on, we'll want to emit this string
  178. [self addContentValueDeclaration];
  179. }
  180. [self setContentStringValue:str];
  181. }
  182. - (GDataObject *)childObject {
  183. return childObject_;
  184. }
  185. - (void)setChildObject:(GDataObject *)obj {
  186. [childObject_ autorelease];
  187. childObject_ = [obj retain];
  188. }
  189. - (NSArray *)XMLValues {
  190. return [super childXMLElements];
  191. }
  192. - (void)setXMLValues:(NSArray *)arr {
  193. [self setChildXMLElements:arr];
  194. }
  195. - (void)addXMLValue:(NSXMLNode *)node {
  196. [self addChildXMLElement:node];
  197. }
  198. @end