Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * This provides a general-purpose serialization facility for Dart objects. A | 6 * This provides a general-purpose serialization facility for Dart objects. A |
| 7 * [Serialization] is defined in terms of [SerializationRule]s and supports | 7 * [Serialization] is defined in terms of [SerializationRule]s and supports |
| 8 * reading and writing to different formats. | 8 * reading and writing to different formats. |
| 9 * | 9 * |
| 10 * ## Installing ## | 10 * ## Installing ## |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 * var address = new Address(); | 27 * var address = new Address(); |
| 28 * address.street = 'N 34th'; | 28 * address.street = 'N 34th'; |
| 29 * address.city = 'Seattle'; | 29 * address.city = 'Seattle'; |
| 30 * var serialization = new Serialization() | 30 * var serialization = new Serialization() |
| 31 * ..addRuleFor(address); | 31 * ..addRuleFor(address); |
| 32 * Map output = serialization.write(address); | 32 * Map output = serialization.write(address); |
| 33 * | 33 * |
| 34 * This creates a new serialization and adds a rule for address objects. Right | 34 * This creates a new serialization and adds a rule for address objects. Right |
| 35 * now it has to be passed an address instance because of limitations using | 35 * now it has to be passed an address instance because of limitations using |
| 36 * Address as a literal. Then we ask the [Serialization] to write the address | 36 * Address as a literal. Then we ask the [Serialization] to write the address |
| 37 * and we get back a Map which is a [json]able representation of the state of | 37 * and we get back a Map which is a JSONable representation of the state of |
|
Alan Knight
2013/06/26 19:26:29
The point of that syntax was to provide a link in
| |
| 38 * the address and related objects. Note that while the output in this case | 38 * the address and related objects. Note that while the output in this case |
| 39 * is a [Map], the type will vary depending on which output format we've told | 39 * is a [Map], the type will vary depending on which output format we've told |
| 40 * the [Serialization] to use. | 40 * the [Serialization] to use. |
| 41 * | 41 * |
| 42 * The version above used reflection to automatically identify the public | 42 * The version above used reflection to automatically identify the public |
| 43 * fields of the address object. We can also specify those fields explicitly. | 43 * fields of the address object. We can also specify those fields explicitly. |
| 44 * | 44 * |
| 45 * var serialization = new Serialization() | 45 * var serialization = new Serialization() |
| 46 * ..addRuleFor(address, | 46 * ..addRuleFor(address, |
| 47 * constructor: "create", | 47 * constructor: "create", |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 * | 137 * |
| 138 * Writing | 138 * Writing |
| 139 * ======= | 139 * ======= |
| 140 * To write objects, we use the write() method. | 140 * To write objects, we use the write() method. |
| 141 * | 141 * |
| 142 * var output = serialization.write(someObject); | 142 * var output = serialization.write(someObject); |
| 143 * | 143 * |
| 144 * By default this uses a representation in which objects are represented as | 144 * By default this uses a representation in which objects are represented as |
| 145 * maps keyed by field name, but in which references between objects have been | 145 * maps keyed by field name, but in which references between objects have been |
| 146 * converted into Reference objects. This is then typically encoded as | 146 * converted into Reference objects. This is then typically encoded as |
| 147 * a [json] string, but can also be used in other ways, e.g. sent to another | 147 * a JSON string, but can also be used in other ways, e.g. sent to another |
| 148 * isolate. | 148 * isolate. |
| 149 * | 149 * |
| 150 * We can write objects in different formats by passing a [Format] object to | 150 * We can write objects in different formats by passing a [Format] object to |
| 151 * the [Serialization.write] method or by getting a [Writer] object. | 151 * the [Serialization.write] method or by getting a [Writer] object. |
| 152 * The available formats | 152 * The available formats |
| 153 * include the default, a simple "flat" format that doesn't include field names, | 153 * include the default, a simple "flat" format that doesn't include field names, |
| 154 * and a simple JSON format that produces output more suitable for talking to | 154 * and a simple JSON format that produces output more suitable for talking to |
| 155 * services that expect JSON in a predefined format. Examples of these are | 155 * services that expect JSON in a predefined format. Examples of these are |
| 156 * | 156 * |
| 157 * Map output = serialization.write(address, new SimpleMapFormat()); | 157 * Map output = serialization.write(address, new SimpleMapFormat()); |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 * method. | 352 * method. |
| 353 */ | 353 */ |
| 354 void addRule(SerializationRule rule) { | 354 void addRule(SerializationRule rule) { |
| 355 rule.number = rules.length; | 355 rule.number = rules.length; |
| 356 rules.add(rule); | 356 rules.add(rule); |
| 357 } | 357 } |
| 358 | 358 |
| 359 /** | 359 /** |
| 360 * This writes out an object graph rooted at [object] and returns the result. | 360 * This writes out an object graph rooted at [object] and returns the result. |
| 361 * The [format] parameter determines the form of the result. The default | 361 * The [format] parameter determines the form of the result. The default |
| 362 * format returns a String in [json] format. | 362 * format returns a String in JSON format. |
| 363 */ | 363 */ |
| 364 write(Object object, [Format format]) { | 364 write(Object object, {Format format}) { |
| 365 return newWriter(format).write(object); | 365 return newWriter(format).write(object); |
| 366 } | 366 } |
| 367 | 367 |
| 368 /** | 368 /** |
| 369 * Return a new [Writer] object for this serialization. This is useful if you | 369 * Return a new [Writer] object for this serialization. This is useful if you |
| 370 * want to do something more complex with the writer than just returning | 370 * want to do something more complex with the writer than just returning |
| 371 * the final result. | 371 * the final result. |
| 372 */ | 372 */ |
| 373 Writer newWriter([Format format]) => | 373 Writer newWriter([Format format]) => new Writer(this, format); |
| 374 new Writer(this, format); | |
| 375 | 374 |
| 376 /** | 375 /** |
| 377 * Read the serialized data from [input] and return the root object | 376 * Read the serialized data from [input] and return the root object |
| 378 * from the result. The [input] can be of any type that the [Format] | 377 * from the result. The [input] can be of any type that the [Format] |
| 379 * reads/writes, but normally will be a [List], [Map], or a simple type. | 378 * reads/writes, but normally will be a [List], [Map], or a simple type. |
| 379 * The [format] parameter determines the form of the result. The default | |
| 380 * format returns a String in JSON format. | |
| 380 * If there are objects that need to be resolved | 381 * If there are objects that need to be resolved |
| 381 * in the current context, they should be provided in [externals] as a | 382 * in the current context, they should be provided in [externals] as a |
| 382 * Map from names to values. In particular, in the current implementation | 383 * Map from names to values. In particular, in the current implementation |
| 383 * any class mirrors needed should be provided in [externals] using the | 384 * any class mirrors needed should be provided in [externals] using the |
| 384 * class name as a key. In addition to the [externals] map provided here, | 385 * class name as a key. In addition to the [externals] map provided here, |
| 385 * values will be looked up in the [namedObjects] map. | 386 * values will be looked up in the [namedObjects] map. |
| 386 */ | 387 */ |
| 387 read(input, [Map externals = const {}]) { | 388 read(input, {Format format, Map externals: const {}}) { |
| 388 return newReader().read(input, externals); | 389 return newReader(format).read(input, externals); |
| 389 } | 390 } |
| 390 | 391 |
| 391 /** | 392 /** |
| 392 * Return a new [Reader] object for this serialization. This is useful if | 393 * Return a new [Reader] object for this serialization. This is useful if |
| 393 * you want to do something more complex with the reader than just returning | 394 * you want to do something more complex with the reader than just returning |
| 394 * the final result. | 395 * the final result. |
| 395 */ | 396 */ |
| 396 Reader newReader([Format format]) => new Reader(this, format); | 397 Reader newReader([Format format]) => new Reader(this, format); |
| 397 | 398 |
| 398 /** | 399 /** |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 423 target = object; | 424 target = object; |
| 424 candidateRules = rules; | 425 candidateRules = rules; |
| 425 } | 426 } |
| 426 Iterable applicable = candidateRules.where( | 427 Iterable applicable = candidateRules.where( |
| 427 (each) => each.appliesTo(target, w)); | 428 (each) => each.appliesTo(target, w)); |
| 428 | 429 |
| 429 if (applicable.isEmpty) { | 430 if (applicable.isEmpty) { |
| 430 return create ? [addRuleFor(target)] : applicable; | 431 return create ? [addRuleFor(target)] : applicable; |
| 431 } | 432 } |
| 432 | 433 |
| 433 if (applicable.length == 1) return applicable; | 434 if (applicable.length == 1) { |
| 435 return applicable; | |
| 436 } | |
|
Alan Knight
2013/06/26 19:26:29
I can see the one directly below, but a guard clau
| |
| 434 var first = applicable.first; | 437 var first = applicable.first; |
| 435 var finalRules = applicable.where( | 438 var finalRules = applicable.where( |
| 436 (x) => !x.mustBePrimary || (x == first)); | 439 (x) => !x.mustBePrimary || (x == first)); |
| 437 | 440 |
| 438 if (finalRules.isEmpty) throw new SerializationException( | 441 if (finalRules.isEmpty) { |
| 439 'No valid rule found for object $object'); | 442 throw new SerializationException( |
| 443 'No valid rule found for object $object'); | |
| 444 } | |
| 440 return finalRules; | 445 return finalRules; |
| 441 } | 446 } |
| 442 | 447 |
| 443 /** | 448 /** |
| 444 * Create a Serialization for serializing SerializationRules. This is used | 449 * Create a Serialization for serializing SerializationRules. This is used |
| 445 * to save the rules in a self-describing format along with the data. | 450 * to save the rules in a self-describing format along with the data. |
| 446 * If there are new rule classes created, they will need to be described | 451 * If there are new rule classes created, they will need to be described |
| 447 * here. | 452 * here. |
| 448 */ | 453 */ |
| 449 Serialization ruleSerialization() { | 454 Serialization ruleSerialization() { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 } | 498 } |
| 494 return ifAbsent == null ? null : ifAbsent(); | 499 return ifAbsent == null ? null : ifAbsent(); |
| 495 } | 500 } |
| 496 } | 501 } |
| 497 | 502 |
| 498 /** | 503 /** |
| 499 * An exception class for errors during serialization. | 504 * An exception class for errors during serialization. |
| 500 */ | 505 */ |
| 501 class SerializationException implements Exception { | 506 class SerializationException implements Exception { |
| 502 final String message; | 507 final String message; |
| 503 const SerializationException([this.message]); | 508 const SerializationException(this.message); |
| 504 toString() => "SerializationException($message)"; | 509 String toString() => "SerializationException($message)"; |
| 505 } | 510 } |
| OLD | NEW |