~ubuntu-branches/debian/squeeze/gnome-do-plugins/squeeze

« back to all changes in this revision

Viewing changes to BundledLibraries/libgoogle-data-mono-1.4.0.2/src/gbase/gbaseattribute.cs

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2009-06-27 16:11:49 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090627161149-b74nc297di2842u1
* New upstream release
  + Pidgin plugin now supports initial text for messages (LP: #338608)
  + Pidgin plugin opens conversations on the correct IM network (LP: #370965)
* debian/rules:
  + Update get-orig-source target.  Upstream no longer ships gdata* binaries,
    so we no longer need to strip them
* debian/patches/00_use_system_gdata
  + Drop.  Upstream now builds against system libgdata.
* debian/patches/04_fix_pidgin_dbus_ints
* debian/patches/10_fix_rhythmbox_file
* debian/patches/15_twitter_api
* debian/patches/20_twitter_overflow:
  + Drop.  Included upstream.
* debian/patches/01_firefox_iceweasel_rename:
  + Refresh for new version
* debian/patches/02_fix_banshee_plugin:
  + Drop refernce to /usr/lib/banshee-1/Banshee.CollectionIndexer.dll.
    This is unnecessary, and causes errors when Banshee isn't installed.
* debian/patches/00_debian_default_plugins:
  + Enable a bunch of useful plugins that do not require configuration from 
    the "Official" plugin set by default.  Makes Do more useful out of the 
    box.
* debian/control:
  + Bump versioned build-dep on gnome-do to 0.8.2
  + Split out gnome-do-plugin-evolution package, now that this is possible.
    libevolution5.0-cil has an annoyingly large dependency stack.
    (LP: #351535) (Closes: #524993).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2006-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
 
/* Change history
16
 
* Oct 13 2008  Joe Feser       joseph.feser@gmail.com
17
 
* Converted ArrayLists and other .NET 1.1 collections to use Generics
18
 
* Combined IExtensionElement and IExtensionElementFactory interfaces
19
 
20
 
*/
21
 
#region Using directives
22
 
using System;
23
 
using System.Collections;
24
 
using System.Text;
25
 
using System.Xml;
26
 
using Google.GData.Client;
27
 
#endregion
28
 
 
29
 
namespace Google.GData.GoogleBase {
30
 
 
31
 
    ///////////////////////////////////////////////////////////////////////
32
 
    /// <summary>Identifiers for standard Google Base attribute types.
33
 
    /// All non-standard types share the type otherType</summary>
34
 
    ///////////////////////////////////////////////////////////////////////
35
 
    public enum StandardGBaseAttributeTypeIds
36
 
    {
37
 
        /// <summary>Id of the standard type <c>text</c></summary>
38
 
        textType,
39
 
        /// <summary>Id of the standard type <c>boolean</c></summary>
40
 
        booleanType,
41
 
 
42
 
        /// <summary>Id of the standard type <c>location</c></summary>
43
 
        locationType,
44
 
 
45
 
        /// <summary>Id of the standard type <c>url</c></summary>
46
 
        urlType,
47
 
 
48
 
        /// <summary>Id of the standard type <c>int</c></summary>
49
 
        intType,
50
 
 
51
 
        /// <summary>Id of the standard type <c>float</c></summary>
52
 
        floatType,
53
 
 
54
 
        /// <summary>Id of the standard type <c>number</c></summary>
55
 
        numberType,
56
 
 
57
 
        /// <summary>Id of the standard type <c>intUnit</c></summary>
58
 
        intUnitType,
59
 
 
60
 
        /// <summary>Id of the standard type <c>floatUnit</c></summary>
61
 
        floatUnitType,
62
 
 
63
 
        /// <summary>Id of the standard type <c>numberUnit</c></summary>
64
 
        numberUnitType,
65
 
 
66
 
        /// <summary>Id of the standard type <c>date</c></summary>
67
 
        dateType,
68
 
 
69
 
        /// <summary>Id of the standard type <c>dateTime</c></summary>
70
 
        dateTimeType,
71
 
 
72
 
        /// <summary>Id of the standard type <c>dateTimeRange</c></summary>
73
 
        dateTimeRangeType,
74
 
 
75
 
        /// <summary>Id of the standard type <c>shipping</c></summary>
76
 
        shippingType,
77
 
 
78
 
        /// <summary>An attribute type that could not be recognized by
79
 
        /// the library. See the attribute name.</summary>
80
 
        otherType
81
 
    }
82
 
 
83
 
    ///////////////////////////////////////////////////////////////////////
84
 
    /// <summary>Object representation of Google Base attribute types.
85
 
    ///
86
 
    /// To get GBaseAttributeType instance, use one of the predefined
87
 
    /// constants or call GBaseAttributeType.ForName(string)
88
 
    /// </summary>
89
 
    ///////////////////////////////////////////////////////////////////////
90
 
    public class GBaseAttributeType
91
 
    {
92
 
        private readonly string name;
93
 
        private readonly StandardGBaseAttributeTypeIds id;
94
 
        private readonly GBaseAttributeType supertype;
95
 
 
96
 
        /// <summary>Text attributes.</summary>
97
 
        public static readonly GBaseAttributeType Text =
98
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.textType,
99
 
                                   "text");
100
 
 
101
 
        /// <summary>Boolean attributes.</summary>
102
 
        public static readonly GBaseAttributeType Boolean =
103
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.booleanType,
104
 
                                   "boolean");
105
 
 
106
 
        /// <summary>Location attributes, as a free string.</summary>
107
 
        public static readonly GBaseAttributeType Location =
108
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.locationType,
109
 
                                   "location");
110
 
 
111
 
        /// <summary>Url attributes.</summary>
112
 
        public static readonly GBaseAttributeType Url =
113
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.urlType,
114
 
                                   "url");
115
 
 
116
 
        /// <summary>Number attribute: a float or an int.</summary>
117
 
        public static readonly GBaseAttributeType Number =
118
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.numberType,
119
 
                                   "number");
120
 
 
121
 
        /// <summary>Integer attribute, a subtype of Number.</summary>
122
 
        public static readonly GBaseAttributeType Int =
123
 
            new GBaseAttributeType(Number,
124
 
                                   StandardGBaseAttributeTypeIds.intType,
125
 
                                   "int");
126
 
 
127
 
        /// <summary>Float attribute, a subtype of Number.</summary>
128
 
        public static readonly GBaseAttributeType Float =
129
 
            new GBaseAttributeType(Number,
130
 
                                   StandardGBaseAttributeTypeIds.floatType,
131
 
                                   "float");
132
 
 
133
 
        /// <summary>Number attribute with a unit ("12 km"). A supertype
134
 
        /// of FloatUnit and IntUnit.</summary>
135
 
        public static readonly GBaseAttributeType NumberUnit =
136
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.numberUnitType,
137
 
                                   "numberUnit");
138
 
 
139
 
        /// <summary>Int attribute with a unit, a subtype of NumberUnit.</summary>
140
 
        public static readonly GBaseAttributeType IntUnit =
141
 
            new GBaseAttributeType(NumberUnit,
142
 
                                   StandardGBaseAttributeTypeIds.intUnitType,
143
 
                                   "intUnit");
144
 
 
145
 
        /// <summary>Float attribute with a unit, a subtype of NumberUnit.</summary>
146
 
        public static readonly GBaseAttributeType FloatUnit =
147
 
            new GBaseAttributeType(NumberUnit,
148
 
                                   StandardGBaseAttributeTypeIds.floatUnitType,
149
 
                                   "floatUnit");
150
 
 
151
 
        /// <summary>A time range, with a starting and an end date/time, a
152
 
        /// supertype of DateTime and Date. For example:
153
 
        /// "2006-01-01T12:00:00Z 2006-01-02T14:00:00Z"
154
 
        ///
155
 
        /// Empty time ranges are considered equivalent to DateTime.</summary>
156
 
        public static readonly GBaseAttributeType DateTimeRange =
157
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.dateTimeRangeType,
158
 
                                   "dateTimeRange");
159
 
 
160
 
        /// <summary>A date, a subtype of DateTime and DateTimeRange.</summary>
161
 
        public static readonly GBaseAttributeType Date =
162
 
            new GBaseAttributeType(DateTimeRange,
163
 
                                   StandardGBaseAttributeTypeIds.dateType,
164
 
                                   "date");
165
 
 
166
 
        /// <summary>A date and a time, a subtype of DateTimeRange.</summary>
167
 
        public static readonly GBaseAttributeType DateTime =
168
 
            new GBaseAttributeType(Date,
169
 
                                   StandardGBaseAttributeTypeIds.dateTimeType,
170
 
                                   "dateTime");
171
 
 
172
 
        /// <summary>A Shipping object.</summary>
173
 
        public static readonly GBaseAttributeType Shipping =
174
 
            new GBaseAttributeType(StandardGBaseAttributeTypeIds.shippingType,
175
 
                                   "shipping");
176
 
 
177
 
 
178
 
        /// <summary>All standard attribute types.</summary>
179
 
        public static readonly GBaseAttributeType[] AllStandardTypes = {
180
 
                    Text, Boolean, Location, Url,
181
 
                    Int, Float, Number,
182
 
                    IntUnit, FloatUnit, NumberUnit,
183
 
                    Date, DateTime, DateTimeRange
184
 
                };
185
 
 
186
 
        private static readonly IDictionary StandardTypesDict = new Hashtable();
187
 
        static GBaseAttributeType()
188
 
        {
189
 
            foreach(GBaseAttributeType type in AllStandardTypes)
190
 
            {
191
 
                StandardTypesDict.Add(type.Name, type);
192
 
            }
193
 
        }
194
 
 
195
 
        private GBaseAttributeType(GBaseAttributeType supertype,
196
 
                                   StandardGBaseAttributeTypeIds id,
197
 
                                   string name)
198
 
        {
199
 
            this.supertype = supertype;
200
 
            this.name = name;
201
 
            this.id = id;
202
 
        }
203
 
 
204
 
        private GBaseAttributeType(StandardGBaseAttributeTypeIds id, string name)
205
 
                : this(null, id, name)
206
 
        {
207
 
 
208
 
        }
209
 
 
210
 
        ///////////////////////////////////////////////////////////////////////
211
 
        /// <summary>Get or create an attribute with the given name.
212
 
        /// If the name corresponds to a standard attribute, the global
213
 
        /// instance will be returned. Otherwise, a new GBaseAttributeType
214
 
        /// with Id = otherType will be created.</summary>
215
 
        ///////////////////////////////////////////////////////////////////////
216
 
        public static GBaseAttributeType ForName(String name)
217
 
        {
218
 
            if (name == null)
219
 
            {
220
 
                throw new ArgumentNullException("name");
221
 
            }
222
 
            GBaseAttributeType standard =
223
 
                StandardTypesDict[name] as GBaseAttributeType;
224
 
            if (standard != null)
225
 
            {
226
 
                return standard;
227
 
            }
228
 
 
229
 
            return new GBaseAttributeType(StandardGBaseAttributeTypeIds.otherType,
230
 
                                          name);
231
 
        }
232
 
 
233
 
        ///////////////////////////////////////////////////////////////////////
234
 
        /// <summary>Returns the attribute name.</summary>
235
 
        ///////////////////////////////////////////////////////////////////////
236
 
        public override string ToString()
237
 
        {
238
 
            return name;
239
 
        }
240
 
 
241
 
        ///////////////////////////////////////////////////////////////////////
242
 
        /// <summary>Compares two types by comparing their names.</summary>
243
 
        ///////////////////////////////////////////////////////////////////////
244
 
        public override bool Equals(object o)
245
 
        {
246
 
            if (Object.ReferenceEquals(o, this))
247
 
            {
248
 
                return true;
249
 
            }
250
 
 
251
 
            if (!(o is GBaseAttributeType))
252
 
            {
253
 
                return false;
254
 
            }
255
 
 
256
 
            GBaseAttributeType other = o as GBaseAttributeType;
257
 
 
258
 
            if (other.id == id)
259
 
            {
260
 
                if (other.id == StandardGBaseAttributeTypeIds.otherType)
261
 
                {
262
 
                    return name.Equals(other.name);
263
 
                }
264
 
                return true;
265
 
            }
266
 
            return false;
267
 
        }
268
 
 
269
 
        ///////////////////////////////////////////////////////////////////////
270
 
        /// <summary>Generates a hash code for this element that is
271
 
        /// consistent with its Equals() method.</summary>
272
 
        ///////////////////////////////////////////////////////////////////////
273
 
        public override int GetHashCode()
274
 
        {
275
 
            if (id == StandardGBaseAttributeTypeIds.otherType)
276
 
            {
277
 
                return 11 + name.GetHashCode();
278
 
            }
279
 
            else
280
 
            {
281
 
                return (int)id;
282
 
            }
283
 
        }
284
 
 
285
 
 
286
 
        ///////////////////////////////////////////////////////////////////////
287
 
        /// <summary>Checks whether this object is a supertype or the
288
 
        /// same as another type.</summary>
289
 
        /// <param name="subtype">other attribute type.</param>
290
 
        ///////////////////////////////////////////////////////////////////////
291
 
        public bool IsSupertypeOf(GBaseAttributeType subtype)
292
 
        {
293
 
            if (this == subtype)
294
 
            {
295
 
                return true;
296
 
            }
297
 
            GBaseAttributeType otherSupertype = subtype.Supertype;
298
 
            if (otherSupertype == null)
299
 
            {
300
 
                return false;
301
 
            }
302
 
            return IsSupertypeOf(otherSupertype);
303
 
        }
304
 
 
305
 
        ///////////////////////////////////////////////////////////////////////
306
 
        /// <summary>Type name</summary>
307
 
        ///////////////////////////////////////////////////////////////////////
308
 
        public string Name
309
 
        {
310
 
            get
311
 
            {
312
 
                return name;
313
 
            }
314
 
        }
315
 
 
316
 
        ///////////////////////////////////////////////////////////////////////
317
 
        /// <summary>Type identifier, otherType for nonstandard types.</summary>
318
 
        ///////////////////////////////////////////////////////////////////////
319
 
        public StandardGBaseAttributeTypeIds Id
320
 
        {
321
 
            get
322
 
            {
323
 
                return id;
324
 
            }
325
 
        }
326
 
 
327
 
        ///////////////////////////////////////////////////////////////////////
328
 
        /// <summary>This type's supertype or null.</summary>
329
 
        ///////////////////////////////////////////////////////////////////////
330
 
        public GBaseAttributeType Supertype
331
 
        {
332
 
            get
333
 
            {
334
 
                return supertype;
335
 
            }
336
 
        }
337
 
 
338
 
        ///////////////////////////////////////////////////////////////////////
339
 
        /// <summary>Comparison based on the Equals() method.</summary>
340
 
        ///////////////////////////////////////////////////////////////////////
341
 
        public static bool operator ==(GBaseAttributeType a, GBaseAttributeType b)
342
 
        {
343
 
            if (Object.ReferenceEquals(a, b))
344
 
            {
345
 
                return true;
346
 
            }
347
 
 
348
 
            if (((object)a == null) || ((object)b == null))
349
 
            {
350
 
                return false;
351
 
            }
352
 
 
353
 
            return a.Equals(b);
354
 
        }
355
 
 
356
 
        ///////////////////////////////////////////////////////////////////////
357
 
        /// <summary>Comparison based on the Equals() method.</summary>
358
 
        ///////////////////////////////////////////////////////////////////////
359
 
        public static bool operator !=(GBaseAttributeType a, GBaseAttributeType b)
360
 
        {
361
 
            return !(a == b);
362
 
        }
363
 
    }
364
 
 
365
 
 
366
 
    ///////////////////////////////////////////////////////////////////////
367
 
    /// <summary>Extension element corresponding to a g: tag.
368
 
    /// This element contains the logic to convert a g: tag to and from
369
 
    /// XML.
370
 
    ///
371
 
    /// It is usually not accessed through
372
 
    /// <see href="GBaseAttributes">GBaseAttributes</see>.
373
 
    /// </summary>
374
 
    ///////////////////////////////////////////////////////////////////////
375
 
    public class GBaseAttribute : IExtensionElementFactory
376
 
    {
377
 
        private static readonly char[] kXmlWhitespaces = { ' ', '\t', '\n', '\r' };
378
 
        private string name;
379
 
        private GBaseAttributeType type;
380
 
        private bool isPrivate;
381
 
        /// <summary>Content, null if subElements != null.</summary>
382
 
        private string content;
383
 
        private string adjustedValue;
384
 
        private string adjustedName;
385
 
 
386
 
        /// <summary>Dictionary of: subElementName x subElementValue.
387
 
        /// Null if content != null</summary>
388
 
        private IDictionary subElements;
389
 
 
390
 
 
391
 
        ///////////////////////////////////////////////////////////////////////
392
 
        /// <summary>Creates an empty GBaseAttribute.</summary>
393
 
        ///////////////////////////////////////////////////////////////////////
394
 
        public GBaseAttribute()
395
 
        {
396
 
        }
397
 
 
398
 
        ///////////////////////////////////////////////////////////////////////
399
 
        /// <summary>Creates a GBaseAttribute with a name and an undefined
400
 
        ///  type.</summary>
401
 
        /// <param name="name">attribute name</param>
402
 
        ///////////////////////////////////////////////////////////////////////
403
 
        public GBaseAttribute(String name)
404
 
                : this(name, null, null)
405
 
        {
406
 
        }
407
 
 
408
 
 
409
 
        ///////////////////////////////////////////////////////////////////////
410
 
        /// <summary>Creates a GBaseAttribute with a name and a type.</summary>
411
 
        /// <param name="name">attribute name</param>
412
 
        /// <param name="type">attribute type or null if unknown</param>
413
 
        ///////////////////////////////////////////////////////////////////////
414
 
        public GBaseAttribute(String name, GBaseAttributeType type)
415
 
                : this(name, type, null)
416
 
        {
417
 
        }
418
 
 
419
 
        ///////////////////////////////////////////////////////////////////////
420
 
        /// <summary>Creates a GBaseAttribute</summary>
421
 
        /// <param name="name">attribute name</param>
422
 
        /// <param name="type">attribute type or null if unknown</param>
423
 
        /// <param name="content">value</param>
424
 
        ///////////////////////////////////////////////////////////////////////
425
 
        public GBaseAttribute(String name, GBaseAttributeType type, String content)
426
 
        {
427
 
            this.name = name;
428
 
            this.type = type;
429
 
            this.content = content;
430
 
        }
431
 
 
432
 
        ///////////////////////////////////////////////////////////////////////
433
 
        /// <summary>Attribute name</summary>
434
 
        ///////////////////////////////////////////////////////////////////////
435
 
        public string Name
436
 
        {
437
 
            get
438
 
            {
439
 
                return name;
440
 
            }
441
 
            set
442
 
            {
443
 
                name = value;
444
 
            }
445
 
        }
446
 
 
447
 
        ///////////////////////////////////////////////////////////////////////
448
 
        /// <summary>Attribute type</summary>
449
 
        ///////////////////////////////////////////////////////////////////////
450
 
        public GBaseAttributeType Type
451
 
        {
452
 
            get
453
 
            {
454
 
                return type;
455
 
            }
456
 
            set
457
 
            {
458
 
                type = value;
459
 
            }
460
 
        }
461
 
 
462
 
        ///////////////////////////////////////////////////////////////////////
463
 
        /// <summary>Attribute content, as a string.</summary>
464
 
        ///////////////////////////////////////////////////////////////////////
465
 
        public string Content
466
 
        {
467
 
            get
468
 
            {
469
 
                return content;
470
 
            }
471
 
            set
472
 
            {
473
 
                content = value;
474
 
            }
475
 
        }
476
 
 
477
 
        ///////////////////////////////////////////////////////////////////////
478
 
        /// <summary>Private access (XML attribute access="private")</summary>
479
 
        ///////////////////////////////////////////////////////////////////////
480
 
        public bool IsPrivate
481
 
        {
482
 
            get
483
 
            {
484
 
                return isPrivate;
485
 
            }
486
 
            set
487
 
            {
488
 
                isPrivate = value;
489
 
            }
490
 
        }
491
 
 
492
 
 
493
 
        ///////////////////////////////////////////////////////////////////////
494
 
        /// <summary>A better name for this attribute, recommended by 
495
 
        /// Google (when adjustments are turned on)</summary>
496
 
        ///////////////////////////////////////////////////////////////////////
497
 
        public string AdjustedName
498
 
        {
499
 
            get
500
 
            {
501
 
                return adjustedName;
502
 
            }
503
 
            set
504
 
            {
505
 
                adjustedName = value;
506
 
            }
507
 
        }
508
 
 
509
 
 
510
 
        ///////////////////////////////////////////////////////////////////////
511
 
        /// <summary>A better value for this string attribute, recommended by 
512
 
        /// Google (when adjustments are turned on)</summary>
513
 
        ///////////////////////////////////////////////////////////////////////
514
 
        public string AdjustedValue
515
 
        {
516
 
            get
517
 
            {
518
 
                return adjustedValue;
519
 
            }
520
 
            set
521
 
            {
522
 
                adjustedValue = value;
523
 
            }
524
 
        }
525
 
 
526
 
        //////////////////////////////////////////////////////////////////////
527
 
        /// <summary>Accesses sub-elements.
528
 
        ///
529
 
        /// Sub-elements are XML elements put inside the attribute
530
 
        /// tag. Such as:
531
 
        /// &lt;g:shipping&gt;
532
 
        ///   &lt;g:country&gt;FR&lt;/g:country&gt;
533
 
        ///   &lt;g:price&gt;12 EUR&lt;/g:price&gt;
534
 
        /// &lt;/g:shipping&gt;
535
 
        ///
536
 
        /// An attribute cannot contain both sub-elements and text (content)
537
 
        /// </summary>
538
 
        //////////////////////////////////////////////////////////////////////
539
 
        public string this[string subElementName]
540
 
        {
541
 
            get
542
 
            {
543
 
                if (subElements == null)
544
 
                {
545
 
                    return null;
546
 
                }
547
 
                return (string)subElements[subElementName];
548
 
            }
549
 
            set
550
 
            {
551
 
                if (subElements == null)
552
 
                {
553
 
                    subElements = new Hashtable();
554
 
                }
555
 
 
556
 
                if (value == null)
557
 
                {
558
 
                    subElements.Remove(subElementName);
559
 
                }
560
 
                else
561
 
                {
562
 
                    subElements[subElementName] = value;
563
 
                }
564
 
            }
565
 
        }
566
 
 
567
 
        //////////////////////////////////////////////////////////////////////
568
 
        /// <summary>Checks whether the attribute has sub-elements.
569
 
        /// You can access sub-element names using the property
570
 
        /// SubElementSames.</summary>
571
 
        //////////////////////////////////////////////////////////////////////
572
 
        public bool HasSubElements
573
 
        {
574
 
            get
575
 
            {
576
 
                return subElements != null && subElements.Count > 0;
577
 
            }
578
 
        }
579
 
 
580
 
        //////////////////////////////////////////////////////////////////////
581
 
        /// <summary>The list of sub-elements name, which might be empty.
582
 
        ///
583
 
        /// The sub-elements names are returned in no particular order.
584
 
        ///
585
 
        /// You can get the value of these sub-elements using this[name].
586
 
        /// </summary>
587
 
        //////////////////////////////////////////////////////////////////////
588
 
        public string[] SubElementNames
589
 
        {
590
 
            get
591
 
            {
592
 
                if (subElements == null)
593
 
                {
594
 
                    return new string[0];
595
 
                }
596
 
                string[] retval = new string[subElements.Count];
597
 
                subElements.Keys.CopyTo(retval, 0);
598
 
                return retval;
599
 
            }
600
 
        }
601
 
 
602
 
 
603
 
        ///////////////////////////////////////////////////////////////////////
604
 
        /// <summary>Parses an XML node and create the corresponding
605
 
        /// GBaseAttribute.</summary>
606
 
        ///////////////////////////////////////////////////////////////////////
607
 
        public static GBaseAttribute ParseGBaseAttribute(XmlNode node)
608
 
        {
609
 
            if (node == null)
610
 
            {
611
 
                throw new ArgumentNullException("node");
612
 
            }
613
 
 
614
 
            GBaseAttribute attribute = new GBaseAttribute();
615
 
            attribute.Name = FromXmlTagName(node.LocalName);
616
 
            String value = Utilities.GetAttributeValue("type", node);
617
 
            if (value != null)
618
 
            {
619
 
                attribute.Type = GBaseAttributeType.ForName(value);
620
 
            }
621
 
            value =  Utilities.GetAttributeValue("access",node);
622
 
            attribute.IsPrivate = "private".Equals(value);
623
 
 
624
 
            foreach (XmlNode child in node.ChildNodes)
625
 
            {
626
 
                if (child.NodeType == XmlNodeType.Element)
627
 
                {
628
 
                    bool parsed = false;
629
 
                    if (child.NamespaceURI == GBaseNameTable.NSGBaseMeta)
630
 
                    {
631
 
                        object localName = child.LocalName;
632
 
                        if (localName.Equals("adjusted_name"))
633
 
                        {
634
 
                            attribute.AdjustedName = child.InnerText;
635
 
                            parsed = true;
636
 
                        }
637
 
                        else if (localName.Equals("adjusted_value"))
638
 
                        {
639
 
                            attribute.AdjustedValue = child.InnerText;
640
 
                            parsed = true;
641
 
                        }
642
 
                    }
643
 
                    // Keep everything else as XML
644
 
                    if (!parsed)
645
 
                    {
646
 
                        attribute[child.LocalName] = child.InnerXml;
647
 
                    }
648
 
                }
649
 
            }
650
 
 
651
 
            // If there are sub-elements, set the Content to null unless
652
 
            // there is clearly something in there.
653
 
            string content = ExtractDirectTextChildren(node);
654
 
            if (!"".Equals(content.Trim(kXmlWhitespaces)))
655
 
            {
656
 
                attribute.Content = content;
657
 
            }
658
 
            return attribute;
659
 
        }
660
 
 
661
 
        ///////////////////////////////////////////////////////////////////////
662
 
        /// <summary>Extracts all text nodes inside an element, ignoring
663
 
        /// text nodes inside children (contrary to XmlNode.InnerText).
664
 
        /// </summary>
665
 
        ///////////////////////////////////////////////////////////////////////
666
 
        private static string ExtractDirectTextChildren(XmlNode parent)
667
 
        {
668
 
            StringBuilder retval = new StringBuilder();
669
 
            for (XmlNode child = parent.FirstChild; child != null; child = child.NextSibling)
670
 
            {
671
 
                if (child.NodeType == XmlNodeType.Text || child.NodeType == XmlNodeType.CDATA) {
672
 
                    retval.Append(child.Value);
673
 
                }
674
 
            }
675
 
            return retval.ToString();
676
 
        }
677
 
 
678
 
        ///////////////////////////////////////////////////////////////////////
679
 
        /// <summary>Converts the current GBaseAttribute to XML.</summary>
680
 
        ///////////////////////////////////////////////////////////////////////
681
 
        public void Save(XmlWriter writer)
682
 
        {
683
 
            writer.WriteStartElement(XmlPrefix,
684
 
                                     ToXmlTagName(name),
685
 
                                     XmlNameSpace);
686
 
            if (type != null)
687
 
            {
688
 
                writer.WriteAttributeString("type", type.Name);
689
 
            }
690
 
            if (isPrivate)
691
 
            {
692
 
                writer.WriteAttributeString("access", "private");
693
 
            }
694
 
 
695
 
            if (adjustedValue != null)
696
 
            {
697
 
                writer.WriteStartElement(GBaseNameTable.GBaseMetaPrefix,
698
 
                                         "adjusted_value",
699
 
                                         GBaseNameTable.NSGBaseMeta);
700
 
                writer.WriteString(adjustedValue);
701
 
                writer.WriteEndElement();
702
 
            }
703
 
 
704
 
            if (adjustedName != null)
705
 
            {
706
 
                writer.WriteStartElement(GBaseNameTable.GBaseMetaPrefix,
707
 
                                         "adjusted_name",
708
 
                                         GBaseNameTable.NSGBaseMeta);
709
 
                writer.WriteString(adjustedName);
710
 
                writer.WriteEndElement();
711
 
            }
712
 
 
713
 
            if (content != null)
714
 
            {
715
 
                writer.WriteString(content);
716
 
            }
717
 
            if (subElements != null)
718
 
            {
719
 
                foreach (string elementName in subElements.Keys)
720
 
                {
721
 
                    string elementValue = (string)subElements[elementName];
722
 
                    if (elementValue != null)
723
 
                    {
724
 
                        writer.WriteStartElement(GBaseNameTable.GBasePrefix,
725
 
                                                 ToXmlTagName(elementName),
726
 
                                                 GBaseNameTable.NSGBase);
727
 
                        writer.WriteString(elementValue);
728
 
                        writer.WriteEndElement();
729
 
                    }
730
 
                }
731
 
            }
732
 
            writer.WriteEndElement();
733
 
        }
734
 
 
735
 
        ///////////////////////////////////////////////////////////////////////
736
 
        /// <summary>A partial text representation, to help
737
 
        /// debugging.</summary>
738
 
        ///////////////////////////////////////////////////////////////////////
739
 
        public override string ToString()
740
 
        {
741
 
            StringBuilder retval = new StringBuilder();
742
 
            retval.Append(name);
743
 
            retval.Append('(');
744
 
            retval.Append(type);
745
 
            retval.Append("):");
746
 
            if (HasSubElements)
747
 
            {
748
 
                bool isFirst = true;
749
 
                foreach (string elementName in subElements.Keys)
750
 
                {
751
 
                    if (isFirst)
752
 
                    {
753
 
                        isFirst = false;
754
 
                    }
755
 
                    else
756
 
                    {
757
 
                        retval.Append(",");
758
 
                    }
759
 
                    retval.Append(elementName);
760
 
                    retval.Append(":\"");
761
 
                    retval.Append(subElements[elementName]);
762
 
                    retval.Append('"');
763
 
                }
764
 
            }
765
 
            else if (content != null)
766
 
            {
767
 
                retval.Append('"');
768
 
                retval.Append(content);
769
 
                retval.Append('"');
770
 
            }
771
 
            return retval.ToString();
772
 
        }
773
 
 
774
 
        ///////////////////////////////////////////////////////////////////////
775
 
        /// <summary>Compares two attribute names, types, content and
776
 
        /// private flag.</summary>
777
 
        ///////////////////////////////////////////////////////////////////////
778
 
        public override bool Equals(object o)
779
 
        {
780
 
            if (!(o is GBaseAttribute))
781
 
            {
782
 
                return false;
783
 
            }
784
 
 
785
 
            if (Object.ReferenceEquals(this, o))
786
 
            {
787
 
                return true;
788
 
            }
789
 
 
790
 
            GBaseAttribute other = o as GBaseAttribute;
791
 
            return name == other.name && type == other.type &&
792
 
                   content == other.content && isPrivate == other.isPrivate &&
793
 
                   adjustedName == other.adjustedName && adjustedValue == other.adjustedValue &&
794
 
                   HashTablesEquals(subElements, other.subElements);
795
 
        }
796
 
 
797
 
        /// <summary>Compares two hash tables.</summary>
798
 
        private bool HashTablesEquals(IDictionary a, IDictionary b)
799
 
        {
800
 
            if (a == null)
801
 
            {
802
 
                return b == null;
803
 
            }
804
 
            if (b == null)
805
 
            {
806
 
                return false;
807
 
            }
808
 
            ICollection aKeys = a.Keys;
809
 
            ICollection bKeys = b.Keys;
810
 
            if (aKeys.Count != bKeys.Count)
811
 
            {
812
 
                return false;
813
 
            }
814
 
            foreach (string key in aKeys)
815
 
            {
816
 
                object aValue = a[key];
817
 
                object bValue = b[key];
818
 
                if (aValue != bValue && (aValue == null || !aValue.Equals(bValue)))
819
 
                {
820
 
                    return false;
821
 
                }
822
 
            }
823
 
            return true;
824
 
        }
825
 
 
826
 
        ///////////////////////////////////////////////////////////////////////
827
 
        /// <summary>Generates a hash code for this element that is
828
 
        /// consistent with its Equals() method.</summary>
829
 
        ///////////////////////////////////////////////////////////////////////
830
 
        public override int GetHashCode()
831
 
        {
832
 
            int retval = 49 * (27 + name.GetHashCode()) + type.GetHashCode();
833
 
            if (content != null)
834
 
            {
835
 
                retval = 49 * retval + content.GetHashCode();
836
 
            }
837
 
            return retval;
838
 
        }
839
 
 
840
 
        ///////////////////////////////////////////////////////////////////////
841
 
        /// <summary>Given an attribute name, with spaces, generates
842
 
        /// the corresponding XML tag name.</summary>
843
 
        /// <param name="name">attribute name</param>
844
 
        /// <returns>the name with all spaces replaced with underscores
845
 
        /// </returns>
846
 
        ///////////////////////////////////////////////////////////////////////
847
 
        static string ToXmlTagName(string name)
848
 
        {
849
 
            return name.Replace(' ', '_');
850
 
        }
851
 
 
852
 
        ///////////////////////////////////////////////////////////////////////
853
 
        /// <summary>Given an XML tag name, with underscores, generates
854
 
        /// the corresponding attribute name.</summary>
855
 
        /// <param name="name">XML tag name, without namespace prefix</param>
856
 
        /// <returns>the name with all underscores replaced with spaces
857
 
        /// </returns>
858
 
        ///////////////////////////////////////////////////////////////////////
859
 
        static string FromXmlTagName(string name)
860
 
        {
861
 
            return name.Replace('_', ' ');
862
 
        }
863
 
 
864
 
        #region IExtensionElementFactory Members
865
 
 
866
 
        public string XmlName
867
 
        {
868
 
            get
869
 
            {
870
 
                return ToXmlTagName(Name);
871
 
            }
872
 
        }
873
 
 
874
 
        public string XmlNameSpace
875
 
        {
876
 
            get
877
 
            {
878
 
                return GBaseNameTable.NSGBase;
879
 
            }
880
 
        }
881
 
 
882
 
        public string XmlPrefix
883
 
        {
884
 
            get
885
 
            {
886
 
                return GBaseNameTable.GBasePrefix;
887
 
            }
888
 
        }
889
 
 
890
 
        public IExtensionElementFactory CreateInstance(XmlNode node, AtomFeedParser parser)
891
 
        {
892
 
            return ParseGBaseAttribute(node);
893
 
        }
894
 
 
895
 
        #endregion
896
 
    }
897
 
 
898
 
}