Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: pkg/serialization/lib/serialization.dart

Issue 12136002: Some fixes to work better with the services framework (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changes from review comments Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/serialization/lib/src/basic_rule.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 * Setup 10 * Setup
11 * ===== 11 * =====
12 * A simple example of usage is 12 * A simple example of usage is
13 * 13 *
14 * var address = new Address(); 14 * var address = new Address();
15 * address.street = 'N 34th'; 15 * address.street = 'N 34th';
16 * address.city = 'Seattle'; 16 * address.city = 'Seattle';
17 * var serialization = new Serialization() 17 * var serialization = new Serialization()
18 * ..addRuleFor(address); 18 * ..addRuleFor(address);
19 * String output = serialization.write(address); 19 * String output = serialization.write(address);
20 * 20 *
21 * This creates a new serialization and adds a rule for address objects. Right 21 * This creates a new serialization and adds a rule for address objects. Right
22 * now it has to be passed an address instance because of limitations using 22 * now it has to be passed an address instance because of limitations using
23 * Address as a literal. Then we ask the Serialization to write the address 23 * Address as a literal. Then we ask the Serialization to write the address
24 * and we get back a String which is a [JSON] representation of the state of 24 * and we get back a Map which is a [json]able representation of the state of
25 * it and related objects. 25 * the address and related objects.
26 * 26 *
27 * The version above used reflection to automatically identify the public 27 * The version above used reflection to automatically identify the public
28 * fields of the address object. We can also specify those fields explicitly. 28 * fields of the address object. We can also specify those fields explicitly.
29 * 29 *
30 * var serialization = new Serialization() 30 * var serialization = new Serialization()
31 * ..addRuleFor(address, 31 * ..addRuleFor(address,
32 * constructor: "create", 32 * constructor: "create",
33 * constructorFields: ["number", "street"], 33 * constructorFields: ["number", "street"],
34 * fields: ["city"]); 34 * fields: ["city"]);
35 * 35 *
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 * [ClosureRule]. In this case we've also had them use maps rather than 98 * [ClosureRule]. In this case we've also had them use maps rather than
99 * lists for the state, but either would work as long as the rule is 99 * lists for the state, but either would work as long as the rule is
100 * consistent with the representation it uses. We pass it the runtimeType 100 * consistent with the representation it uses. We pass it the runtimeType
101 * of the object, and functions equivalent to the methods on [CustomRule] 101 * of the object, and functions equivalent to the methods on [CustomRule]
102 * 102 *
103 * Constant Values 103 * Constant Values
104 * =============== 104 * ===============
105 * There are cases where the constructor needs values that we can't easily get 105 * There are cases where the constructor needs values that we can't easily get
106 * from the serialized object. For example, we may just want to pass null, or a 106 * from the serialized object. For example, we may just want to pass null, or a
107 * constant value. To support this, we can specify as constructor fields 107 * constant value. To support this, we can specify as constructor fields
108 * values that aren't field names. If any value isn't a String, it will be 108 * values that aren't field names. If any value isn't a String, or is a string
109 * that doesn't correspond to a field name, it will be
109 * treated as a constant and passed unaltered to the constructor. 110 * treated as a constant and passed unaltered to the constructor.
110 * 111 *
111 * In some cases a non-constructor field should not be set using field 112 * In some cases a non-constructor field should not be set using field
112 * access or a setter, but should be done by calling a method. For example, it 113 * access or a setter, but should be done by calling a method. For example, it
113 * may not be possible to set a List field "foo", and you need to call an 114 * may not be possible to set a List field "foo", and you need to call an
114 * addFoo() method for each entry in the list. In these cases, if you are using 115 * addFoo() method for each entry in the list. In these cases, if you are using
115 * a BasicRule for the object you can call the setFieldWith() method. 116 * a BasicRule for the object you can call the setFieldWith() method.
116 * 117 *
117 * s..addRuleFor(fooHolderInstance).setFieldWith("foo", 118 * s..addRuleFor(fooHolderInstance).setFieldWith("foo",
118 * (parent, value) => for (var each in value) parent.addFoo(value)); 119 * (parent, value) => for (var each in value) parent.addFoo(value));
119 * 120 *
120 * Writing 121 * Writing
121 * ======= 122 * =======
122 * To write objects, we use the write() method. 123 * To write objects, we use the write() method.
123 * 124 *
124 * var output = serialization.write(someObject); 125 * var output = serialization.write(someObject);
125 * 126 *
126 * By default this uses a representation in which objects are represented as 127 * By default this uses a representation in which objects are represented as
127 * maps keyed by field name, but in which references between objects have been 128 * maps keyed by field name, but in which references between objects have been
128 * converted into Reference objects. This is then encoded as a [json] string. 129 * converted into Reference objects. This is then typically encoded as
130 * a [json] string, but can also be used in other ways, e.g. sent to another
131 * isolate.
129 * 132 *
130 * We can write objects in different formats by passing a [Format] object to 133 * We can write objects in different formats by passing a [Format] object to
131 * the [write] method or by getting a [Writer] object. The available formats 134 * the [write] method or by getting a [Writer] object. The available formats
132 * include the default, a simple "flat" format that doesn't include field names, 135 * include the default, a simple "flat" format that doesn't include field names,
133 * and a simple JSON format that produces output more suitable for talking to 136 * and a simple JSON format that produces output more suitable for talking to
134 * services that expect JSON in a predefined format. Examples of these are 137 * services that expect JSON in a predefined format. Examples of these are
135 * 138 *
136 * String output = serialization.write(address, new SimpleMapFormat()); 139 * Map output = serialization.write(address, new SimpleMapFormat());
137 * List output = serialization.write(address, new SimpleFlatFormat()); 140 * List output = serialization.write(address, new SimpleFlatFormat());
138 * Map output = serialization.write(address, new SimpleJsonFormat()); 141 * var output = serialization.write(address, new SimpleJsonFormat());
139 * Or, using a [Writer] explicitly 142 * Or, using a [Writer] explicitly
140 * var writer = serialization.newWriter(new SimpleFlatFormat()); 143 * var writer = serialization.newWriter(new SimpleFlatFormat());
141 * var output = writer.write(address); 144 * List output = writer.write(address);
142 * 145 *
143 * These representations are not yet considered stable. 146 * These representations are not yet considered stable.
144 * 147 *
145 * Reading 148 * Reading
146 * ======= 149 * =======
147 * To read objects, the corresponding [read] method can be used. 150 * To read objects, the corresponding [read] method can be used.
148 * 151 *
149 * Address input = serialization.read(aString); 152 * Address input = serialization.read(input);
150 * 153 *
151 * When reading, the serialization instance doing the reading must be configured 154 * When reading, the serialization instance doing the reading must be configured
152 * with compatible rules to the one doing the writing. It's possible for the 155 * with compatible rules to the one doing the writing. It's possible for the
153 * rules to be different, but they need to be able to read the same 156 * rules to be different, but they need to be able to read the same
154 * representation. For most practical purposes right now they should be the 157 * representation. For most practical purposes right now they should be the
155 * same. The simplest way to achieve this is by having the serialization 158 * same. The simplest way to achieve this is by having the serialization
156 * variable [selfDescribing] be true. In that case the rules themselves are also 159 * variable [selfDescribing] be true. In that case the rules themselves are also
157 * stored along with the serialized data, and can be read back on the receiving 160 * stored along with the serialized data, and can be read back on the receiving
158 * end. Note that this may not work for all rules or all formats. The 161 * end. Note that this may not work for all rules or all formats. The
159 * [selfDescribing] variable is true by default, but the [SimpleJsonFormat] does 162 * [selfDescribing] variable is true by default, but the [SimpleJsonFormat] does
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 */ 231 */
229 bool _selfDescribing; 232 bool _selfDescribing;
230 233
231 /** 234 /**
232 * When we write out data using this serialization, should we also write 235 * When we write out data using this serialization, should we also write
233 * out a description of the rules. This is on by default unless using 236 * out a description of the rules. This is on by default unless using
234 * CustomRule subclasses, in which case it requires additional setup and 237 * CustomRule subclasses, in which case it requires additional setup and
235 * is off by default. 238 * is off by default.
236 */ 239 */
237 bool get selfDescribing { 240 bool get selfDescribing {
241 // TODO(alanknight): Should this be moved to the format?
242 // TODO(alanknight): Allow self-describing in the presence of CustomRule.
238 if (_selfDescribing != null) return _selfDescribing; 243 if (_selfDescribing != null) return _selfDescribing;
239 return !_rules.any((x) => x is CustomRule); 244 return !_rules.any((x) => x is CustomRule);
240 } 245 }
241 246
242 /** 247 /**
243 * When we write out data using this serialization, should we also write 248 * When we write out data using this serialization, should we also write
244 * out a description of the rules. This is on by default unless using 249 * out a description of the rules. This is on by default unless using
245 * CustomRule subclasses, in which case it requires additional setup and 250 * CustomRule subclasses, in which case it requires additional setup and
246 * is off by default. 251 * is off by default.
247 */ 252 */
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 /** 342 /**
338 * Return a new [Writer] object for this serialization. This is useful if you 343 * Return a new [Writer] object for this serialization. This is useful if you
339 * want to do something more complex with the writer than just returning 344 * want to do something more complex with the writer than just returning
340 * the final result. 345 * the final result.
341 */ 346 */
342 Writer newWriter([Format format]) => 347 Writer newWriter([Format format]) =>
343 new Writer(this, format); 348 new Writer(this, format);
344 349
345 /** 350 /**
346 * Read the serialized data from [input] and return the root object 351 * Read the serialized data from [input] and return the root object
347 * from the result. If there are objects that need to be resolved 352 * from the result. The [input] can be of any type that the [Format]
353 * reads/writes, but normally will be a [List], [Map], or a simple type.
354 * If there are objects that need to be resolved
348 * in the current context, they should be provided in [externals] as a 355 * in the current context, they should be provided in [externals] as a
349 * Map from names to values. In particular, in the current implementation 356 * Map from names to values. In particular, in the current implementation
350 * any class mirrors needed should be provided in [externals] using the 357 * any class mirrors needed should be provided in [externals] using the
351 * class name as a key. In addition to the [externals] map provided here, 358 * class name as a key. In addition to the [externals] map provided here,
352 * values will be looked up in the [externalObjects] map. 359 * values will be looked up in the [namedObjects] map.
353 */ 360 */
354 read(String input, [Map externals = const {}]) { 361 read(input, [Map externals = const {}]) {
355 return newReader().read(input, externals); 362 return newReader().read(input, externals);
356 } 363 }
357 364
358 /** 365 /**
359 * Return a new [Reader] object for this serialization. This is useful if 366 * Return a new [Reader] object for this serialization. This is useful if
360 * you want to do something more complex with the reader than just returning 367 * you want to do something more complex with the reader than just returning
361 * the final result. 368 * the final result.
362 */ 369 */
363 Reader newReader([Format format]) => new Reader(this, format); 370 Reader newReader([Format format]) => new Reader(this, format);
364 371
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 } 467 }
461 468
462 /** 469 /**
463 * An exception class for errors during serialization. 470 * An exception class for errors during serialization.
464 */ 471 */
465 class SerializationException implements Exception { 472 class SerializationException implements Exception {
466 final String message; 473 final String message;
467 const SerializationException([this.message]); 474 const SerializationException([this.message]);
468 toString() => "SerializationException($message)"; 475 toString() => "SerializationException($message)";
469 } 476 }
OLDNEW
« no previous file with comments | « no previous file | pkg/serialization/lib/src/basic_rule.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698