Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json\Linq\JProperty.cs

Symbol Coverage: 80.00% (64 of 80)

Branch Coverage: 71.43% (45 of 63)

Cyclomatic Complexity Avg: 1.59 Max:5

Code Lines: 83


L V Source
1
#region License
2
// Copyright (c) 2007 James Newton-King
3
//
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
11
// conditions:
12
//
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
15
//
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
24
#endregion
25

  
26
using System;
27
using System.Collections.Generic;
28
using System.ComponentModel;
29
using System.Linq;
30
using System.Text;
31
using Newtonsoft.Json.Utilities;
32
using System.Diagnostics;
33
using System.Globalization;
34

  
35
namespace Newtonsoft.Json.Linq
36
{
37
  /// <summary>
38
  /// Represents a JSON property.
39
  /// </summary>
40
  public class JProperty : JContainer
41
  {
42
    private readonly string _name;
43

  
44
    /// <summary>
45
    /// Gets the property name.
46
    /// </summary>
47
    /// <value>The property name.</value>
48
    public string Name
49
    {
50
      [DebuggerStepThrough]
51
 3775
      get { return _name; }
52
    }
53

  
54
    /// <summary>
55
    /// Gets or sets the property value.
56
    /// </summary>
57
    /// <value>The property value.</value>
58
    public JToken Value
59
    {
60
      [DebuggerStepThrough]
61
 1876
      get { return Content; }
62
      set
63
      {
64
 720
        CheckReentrancy();
65

  
66
 720
        JToken newValue = value ?? new JValue((object) null);
67

  
68
 720
        if (Content == null)
69
        {
70
 706
          newValue = EnsureParentToken(newValue);
71

  
72
 706
          Content = newValue;
73
 706
          Content.Parent = this;
74
 706
          Content.Next = Content;
75
        }
76
        else
77
        {
78
 14
          Content.Replace(newValue);
79
        }
80
 720
      }
81
    }
82

  
83
    internal override void ReplaceItem(JToken existing, JToken replacement)
84
    {
85
 14
      if (IsTokenUnchanged(existing, replacement))
86
 5
        return;
87

  
88
 9
      if (Parent != null)
89
 8
        ((JObject)Parent).InternalPropertyChanging(this);
90

  
91
 9
      base.ReplaceItem(existing, replacement);
92

  
93
 9
      if (Parent != null)
94
 8
        ((JObject)Parent).InternalPropertyChanged(this);
95
 14
    }
96

  
97
    /// <summary>
98
    /// Initializes a new instance of the <see cref="JProperty"/> class from another <see cref="JProperty"/> object.
99
    /// </summary>
100
    /// <param name="other">A <see cref="JProperty"/> object to copy from.</param>
101
 6
    public JProperty(JProperty other)
102
 6
      : base(other)
103
    {
104
 6
      _name = other.Name;
105
 6
    }
106

  
107
    internal override void AddItem(bool isLast, JToken previous, JToken item)
108
    {
109
 492
      if (Value != null)
110
 2
        throw new Exception("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
111

  
112
 490
      Value = item;
113
 490
    }
114

  
115
    internal override JToken GetItem(int index)
116
    {
117
 0
      if (index != 0)
118
 0
        throw new ArgumentOutOfRangeException();
119

  
120
 0
      return Value;
121
 0
    }
122

  
123
    internal override void SetItem(int index, JToken item)
124
    {
125
 0
      if (index != 0)
126
 0
        throw new ArgumentOutOfRangeException();
127
      
128
 0
      Value = item;
129
 0
    }
130

  
131
    internal override bool RemoveItem(JToken item)
132
    {
133
 1
      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
134
    }
135

  
136
    internal override void RemoveItemAt(int index)
137
    {
138
 0
      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
139
    }
140

  
141
    internal override void InsertItem(int index, JToken item)
142
    {
143
 0
      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
144
    }
145

  
146
    internal override bool ContainsItem(JToken item)
147
    {
148
 0
      return (Value == item);
149
 0
    }
150

  
151
    internal override void ClearItems()
152
    {
153
 1
      throw new Exception("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty)));
154
    }
155

  
156
    /// <summary>
157
    /// Returns a collection of the child tokens of this token, in document order.
158
    /// </summary>
159
    /// <returns>
160
    /// An <see cref="IEnumerable{T}"/> of <see cref="JToken"/> containing the child tokens of this <see cref="JToken"/>, in document order.
161
    /// </returns>
162
    public override JEnumerable<JToken> Children()
163
    {
164
 239
      return new JEnumerable<JToken>(ChildrenInternal());
165
 239
    }
166

  
167
    private IEnumerable<JToken> ChildrenInternal()
168
    {
169
 239
      yield return Value;
170
    }
171

  
172
    internal override bool DeepEquals(JToken node)
173
    {
174
 14
      JProperty t = node as JProperty;
175
 14
      return (t != null && _name == t.Name && ContentsEqual(t));
176
 14
    }
177

  
178
    internal override JToken CloneToken()
179
    {
180
 6
      return new JProperty(this);
181
 6
    }
182

  
183
    /// <summary>
184
    /// Gets the node type for this <see cref="JToken"/>.
185
    /// </summary>
186
    /// <value>The type.</value>
187
    public override JTokenType Type
188
    {
189
      [DebuggerStepThrough]
190
 1073
      get { return JTokenType.Property; }
191
    }
192

  
193
 486
    internal JProperty(string name)
194
    {
195
      // called from JTokenWriter
196
 486
      ValidationUtils.ArgumentNotNull(name, "name");
197

  
198
 486
      _name = name;
199
 486
    }
200

  
201
    /// <summary>
202
    /// Initializes a new instance of the <see cref="JProperty"/> class.
203
    /// </summary>
204
    /// <param name="name">The property name.</param>
205
    /// <param name="content">The property content.</param>
206
 11
    public JProperty(string name, params object[] content)
207
 11
      : this(name, (object)content)
208
    {
209
 11
    }
210

  
211
    /// <summary>
212
    /// Initializes a new instance of the <see cref="JProperty"/> class.
213
    /// </summary>
214
    /// <param name="name">The property name.</param>
215
    /// <param name="content">The property content.</param>
216
 216
    public JProperty(string name, object content)
217
    {
218
 216
      ValidationUtils.ArgumentNotNull(name, "name");
219

  
220
 216
      _name = name;
221

  
222
 216
      Value = IsMultiContent(content)
223
 216
        ? new JArray(content)
224
 216
        : CreateFromContent(content);
225
 216
    }
226

  
227
    /// <summary>
228
    /// Writes this token to a <see cref="JsonWriter"/>.
229
    /// </summary>
230
    /// <param name="writer">A <see cref="JsonWriter"/> into which this method will write.</param>
231
    /// <param name="converters">A collection of <see cref="JsonConverter"/> which will be used when writing the token.</param>
232
    public override void WriteTo(JsonWriter writer, params JsonConverter[] converters)
233
    {
234
 179
      writer.WritePropertyName(_name);
235
 179
      Value.WriteTo(writer, converters);
236
 179
    }
237

  
238
    internal override int GetDeepHashCode()
239
    {
240
 8
      return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0);
241
 8
    }
242

  
243
    /// <summary>
244
    /// Loads an <see cref="JProperty"/> from a <see cref="JsonReader"/>. 
245
    /// </summary>
246
    /// <param name="reader">A <see cref="JsonReader"/> that will be read for the content of the <see cref="JProperty"/>.</param>
247
    /// <returns>A <see cref="JProperty"/> that contains the JSON that was read from the specified <see cref="JsonReader"/>.</returns>
248
    public static JProperty Load(JsonReader reader)
249
    {
250
 3
      if (reader.TokenType == JsonToken.None)
251
      {
252
 0
        if (!reader.Read())
253
 0
          throw new Exception("Error reading JProperty from JsonReader.");
254
      }
255
 3
      if (reader.TokenType != JsonToken.PropertyName)
256
 0
        throw new Exception(
257
 0
          "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(
258
 0
            CultureInfo.InvariantCulture, reader.TokenType));
259

  
260
 3
      JProperty p = new JProperty((string)reader.Value);
261
 3
      p.SetLineInfo(reader as IJsonLineInfo);
262

  
263
 3
      if (!reader.Read())
264
 0
        throw new Exception("Error reading JProperty from JsonReader.");
265

  
266
 3
      p.ReadContentFrom(reader);
267

  
268
 3
      return p;
269
 3
    }
270
  }
271
}