Mercurial > projects > orange
comparison orange/serialization/archives/XMLArchive.d @ 9:99c52d46822a
Serialization works now with D2, deserialization still doesn't work
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sat, 24 Jul 2010 18:58:18 +0200 |
parents | ae24aae69a3b |
children | d17ae98330bf |
comparison
equal
deleted
inserted
replaced
8:613a0bb20207 | 9:99c52d46822a |
---|---|
6 */ | 6 */ |
7 module orange.serialization.archives.XMLArchive; | 7 module orange.serialization.archives.XMLArchive; |
8 | 8 |
9 version (Tango) | 9 version (Tango) |
10 { | 10 { |
11 import tango.text.xml.DocPrinter; | 11 /*import tango.text.xml.DocPrinter; |
12 import tango.text.xml.Document; | 12 import tango.text.xml.Document;*/ |
13 import tango.util.Convert : to; | 13 import tango.util.Convert : to; |
14 } | 14 } |
15 | 15 |
16 else | |
17 import std.conv; | |
18 | |
16 import orange.serialization.archives._; | 19 import orange.serialization.archives._; |
17 import orange.util._; | 20 import orange.util._; |
21 import orange.xml.XMLDocument; | |
18 | 22 |
19 private enum ArchiveMode | 23 private enum ArchiveMode |
20 { | 24 { |
21 archiving, | 25 archiving, |
22 unarchiving | 26 unarchiving |
58 private | 62 private |
59 { | 63 { |
60 DataType archiveType = "org.dsource.orange.xml"; | 64 DataType archiveType = "org.dsource.orange.xml"; |
61 DataType archiveVersion = "0.1"; | 65 DataType archiveVersion = "0.1"; |
62 | 66 |
63 Document!(U) doc; | 67 XMLDocument!(U) doc; |
64 doc.Node lastElement; | 68 doc.Node lastElement; |
65 DocPrinter!(U) printer; | 69 //DocPrinter!(U) printer; |
66 doc.Node lastElementSaved; | 70 doc.Node lastElementSaved; |
67 | 71 |
68 bool hasBegunArchiving; | 72 bool hasBegunArchiving; |
69 bool hasBegunUnarchiving; | 73 bool hasBegunUnarchiving; |
70 | 74 |
74 size_t idCounter; | 78 size_t idCounter; |
75 } | 79 } |
76 | 80 |
77 this () | 81 this () |
78 { | 82 { |
79 doc = new Document!(U); | 83 doc = new XMLDocument!(U); |
80 } | 84 } |
81 | 85 |
82 public void beginArchiving () | 86 public void beginArchiving () |
83 { | 87 { |
84 if (!hasBegunArchiving) | 88 if (!hasBegunArchiving) |
85 { | 89 { |
86 doc.header; | 90 doc.header; |
87 lastElement = doc.tree.element(null, Tags.archiveTag) | 91 lastElement = doc.tree.element(Tags.archiveTag) |
88 .attribute(null, Attributes.typeAttribute, archiveType) | 92 .attribute(Attributes.typeAttribute, archiveType) |
89 .attribute(null, Attributes.versionAttribute, archiveVersion); | 93 .attribute(Attributes.versionAttribute, archiveVersion); |
90 lastElement = lastElement.element(null, Tags.dataTag); | 94 lastElement = lastElement.element(Tags.dataTag); |
91 | 95 |
92 hasBegunArchiving = true; | 96 hasBegunArchiving = true; |
93 } | 97 } |
94 } | 98 } |
95 | 99 |
113 } | 117 } |
114 } | 118 } |
115 | 119 |
116 public DataType data () | 120 public DataType data () |
117 { | 121 { |
118 if (!printer) | 122 /*if (!printer) |
119 printer = new DocPrinter!(U); | 123 printer = new DocPrinter!(U); |
120 | 124 |
121 return printer.print(doc); | 125 return printer.print(doc);*/ |
126 | |
127 return doc.toString(); | |
122 } | 128 } |
123 | 129 |
124 public void reset () | 130 public void reset () |
125 { | 131 { |
126 hasBegunArchiving = false; | 132 hasBegunArchiving = false; |
184 | 190 |
185 private void archiveObject (T) (T value, DataType key, ref bool callDelegate) | 191 private void archiveObject (T) (T value, DataType key, ref bool callDelegate) |
186 { | 192 { |
187 if (!value) | 193 if (!value) |
188 { | 194 { |
189 lastElement.element(null, Tags.nullTag) | 195 lastElement.element(Tags.nullTag) |
190 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) | 196 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
191 .attribute(null, Attributes.keyAttribute, key); | 197 .attribute(Attributes.keyAttribute, key); |
192 callDelegate = false; | 198 callDelegate = false; |
193 } | 199 } |
194 | 200 |
195 else if (auto reference = getArchivedReference(value)) | 201 else if (auto reference = getArchivedReference(value)) |
196 { | 202 { |
200 | 206 |
201 else | 207 else |
202 { | 208 { |
203 DataType id = nextId; | 209 DataType id = nextId; |
204 | 210 |
205 lastElement = lastElement.element(null, Tags.objectTag) | 211 lastElement = lastElement.element(Tags.objectTag) |
206 .attribute(null, Attributes.runtimeTypeAttribute, toDataType(value.classinfo.name)) | 212 .attribute(Attributes.runtimeTypeAttribute, toDataType(value.classinfo.name)) |
207 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) | 213 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
208 .attribute(null, Attributes.keyAttribute, key) | 214 .attribute(Attributes.keyAttribute, key) |
209 .attribute(null, Attributes.idAttribute, id); | 215 .attribute(Attributes.idAttribute, id); |
210 | 216 |
211 addArchivedReference(value, id); | 217 addArchivedReference(value, id); |
212 } | 218 } |
213 } | 219 } |
214 | 220 |
215 private void archiveStruct (T) (T value, DataType key) | 221 private void archiveStruct (T) (T value, DataType key) |
216 { | 222 { |
217 lastElement = lastElement.element(null, Tags.structTag) | 223 lastElement = lastElement.element(Tags.structTag) |
218 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) | 224 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
219 .attribute(null, Attributes.keyAttribute, key); | 225 .attribute(Attributes.keyAttribute, key); |
220 } | 226 } |
221 | 227 |
222 private void archiveString (T) (T value, DataType key) | 228 private void archiveString (T) (T value, DataType key) |
223 { | 229 { |
224 lastElement.element(null, Tags.stringTag, toDataType(value)) | 230 lastElement.element(Tags.stringTag, toDataType(value)) |
225 .attribute(null, Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) | 231 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) |
226 .attribute(null, Attributes.keyAttribute, key); | 232 .attribute(Attributes.keyAttribute, key); |
227 } | 233 } |
228 | 234 |
229 private void archiveArray (T) (T value, DataType key) | 235 private void archiveArray (T) (T value, DataType key) |
230 { | 236 { |
231 lastElement = lastElement.element(null, Tags.arrayTag) | 237 lastElement = lastElement.element(Tags.arrayTag) |
232 .attribute(null, Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) | 238 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfArray!(T).stringof)) |
233 .attribute(null, Attributes.lengthAttribute, toDataType(value.length)) | 239 .attribute(Attributes.lengthAttribute, toDataType(value.length)) |
234 .attribute(null, Attributes.keyAttribute, key); | 240 .attribute(Attributes.keyAttribute, key); |
235 } | 241 } |
236 | 242 |
237 private void archiveAssociativeArray (T) (T value, DataType key) | 243 private void archiveAssociativeArray (T) (T value, DataType key) |
238 { | 244 { |
239 lastElement = lastElement.element(null, Tags.associativeArrayTag) | 245 lastElement = lastElement.element(Tags.associativeArrayTag) |
240 .attribute(null, Attributes.keyTypeAttribute, toDataType(KeyTypeOfAssociativeArray!(T).stringof)) | 246 .attribute(Attributes.keyTypeAttribute, toDataType(KeyTypeOfAssociativeArray!(T).stringof)) |
241 .attribute(null, Attributes.valueTypeAttribute, toDataType(ValueTypeOfAssociativeArray!(T).stringof)) | 247 .attribute(Attributes.valueTypeAttribute, toDataType(ValueTypeOfAssociativeArray!(T).stringof)) |
242 .attribute(null, Attributes.lengthAttribute, toDataType(value.length)) | 248 .attribute(Attributes.lengthAttribute, toDataType(value.length)) |
243 .attribute(null, Attributes.keyAttribute, key); | 249 .attribute(Attributes.keyAttribute, key); |
244 } | 250 } |
245 | 251 |
246 private void archivePointer (T) (T value, DataType key, ref bool callDelegate) | 252 private void archivePointer (T) (T value, DataType key, ref bool callDelegate) |
247 { | 253 { |
248 if (auto reference = getArchivedReference(value)) | 254 if (auto reference = getArchivedReference(value)) |
253 | 259 |
254 else | 260 else |
255 { | 261 { |
256 DataType id = nextId; | 262 DataType id = nextId; |
257 | 263 |
258 lastElement = lastElement.element(null, Tags.pointerTag) | 264 lastElement = lastElement.element(Tags.pointerTag) |
259 .attribute(null, Attributes.keyAttribute, key) | 265 .attribute(Attributes.keyAttribute, key) |
260 .attribute(null, Attributes.idAttribute, id); | 266 .attribute(Attributes.idAttribute, id); |
261 | 267 |
262 addArchivedReference(value, id); | 268 addArchivedReference(value, id); |
263 } | 269 } |
264 } | 270 } |
265 | 271 |
266 private void archiveEnum (T) (T value, DataType key) | 272 private void archiveEnum (T) (T value, DataType key) |
267 { | 273 { |
268 lastElement.element(null, Tags.enumTag, toDataType(value)) | 274 lastElement.element(Tags.enumTag, toDataType(value)) |
269 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) | 275 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
270 .attribute(null, Attributes.keyAttribute, key); | 276 .attribute(Attributes.keyAttribute, key); |
271 } | 277 } |
272 | 278 |
273 private void archivePrimitive (T) (T value, DataType key) | 279 private void archivePrimitive (T) (T value, DataType key) |
274 { | 280 { |
275 lastElement.element(null, toDataType(T.stringof), toDataType(value)) | 281 lastElement.element(toDataType(T.stringof), toDataType(value)) |
276 .attribute(null, Attributes.keyAttribute, key); | 282 .attribute(Attributes.keyAttribute, key); |
277 } | 283 } |
278 | 284 |
279 private void archiveTypeDef (T) (T value, DataType key) | 285 private void archiveTypeDef (T) (T value, DataType key) |
280 { | 286 { |
281 lastElement = lastElement.element(null, Tags.typedefTag) | 287 lastElement = lastElement.element(Tags.typedefTag) |
282 .attribute(null, Attributes.typeAttribute, toDataType(BaseTypeOfTypeDef!(T).stringof)); | 288 .attribute(Attributes.typeAttribute, toDataType(BaseTypeOfTypeDef!(T).stringof)); |
283 .attribute(null, Attributes.key, key); | 289 .attribute(Attributes.key, key); |
284 } | 290 } |
285 | 291 |
286 public T unarchive (T) (DataType key, T delegate (T) dg = null) | 292 public T unarchive (T) (DataType key, T delegate (T) dg = null) |
287 { | 293 { |
288 if (!hasBegunUnarchiving) | 294 if (!hasBegunUnarchiving) |
340 return *reference; | 346 return *reference; |
341 } | 347 } |
342 | 348 |
343 auto tmp = getElement(Tags.objectTag, key, Attributes.keyAttribute, false); | 349 auto tmp = getElement(Tags.objectTag, key, Attributes.keyAttribute, false); |
344 | 350 |
345 if (!tmp) | 351 if (!tmp.isValid) |
346 { | 352 { |
353 println(T.stringof); | |
354 println(key); | |
347 lastElement = getElement(Tags.nullTag, key); | 355 lastElement = getElement(Tags.nullTag, key); |
348 callDelegate = false; | 356 callDelegate = false; |
349 return null; | 357 return null; |
350 } | 358 } |
351 | 359 |
355 auto name = fromDataType!(string)(runtimeType); | 363 auto name = fromDataType!(string)(runtimeType); |
356 id = getValueOfAttribute(Attributes.idAttribute); | 364 id = getValueOfAttribute(Attributes.idAttribute); |
357 | 365 |
358 T result; | 366 T result; |
359 | 367 |
360 static if (is(typeof(T._ctor))) | 368 /*static if (is(typeof(T._ctor))) |
361 { | 369 { |
362 ParameterTupleOf!(typeof(T._ctor)) params; | 370 ParameterTupleOf!(typeof(T._ctor)) params; |
363 result = factory!(T, typeof(params))(name, params); | 371 result = factory!(T, typeof(params))(name, params); |
364 } | 372 } |
365 | 373 |
366 else | 374 else*/ |
367 result = factory!(T)(name); | 375 result = cast(T) newInstance(name); |
368 | 376 |
369 addUnarchivedReference(result, id); | 377 addUnarchivedReference(result, id); |
370 | 378 |
371 return result; | 379 return result; |
372 } | 380 } |
443 return AssociativeArrayVisitor!(KeyTypeOfAssociativeArray!(T), ValueTypeOfAssociativeArray!(T))(this); | 451 return AssociativeArrayVisitor!(KeyTypeOfAssociativeArray!(T), ValueTypeOfAssociativeArray!(T))(this); |
444 } | 452 } |
445 | 453 |
446 public void archiveBaseClass (T : Object) (DataType key) | 454 public void archiveBaseClass (T : Object) (DataType key) |
447 { | 455 { |
448 lastElement = lastElement.element(null, Tags.baseTag) | 456 lastElement = lastElement.element(Tags.baseTag) |
449 .attribute(null, Attributes.typeAttribute, toDataType(T.stringof)) | 457 .attribute(Attributes.typeAttribute, toDataType(T.stringof)) |
450 .attribute(null, Attributes.keyAttribute, key); | 458 .attribute(Attributes.keyAttribute, key); |
451 } | 459 } |
452 | 460 |
453 public void unarchiveBaseClass (T : Object) (DataType key) | 461 public void unarchiveBaseClass (T : Object) (DataType key) |
454 { | 462 { |
455 lastElement = getElement(Tags.baseTag, key); | 463 lastElement = getElement(Tags.baseTag, key); |
456 } | 464 } |
457 | 465 |
458 template errorMessage (ArchiveMode mode = ArchiveMode.archiving) | 466 version (Tango) |
459 { | 467 { |
460 static if (mode == ArchiveMode.archiving) | 468 template errorMessage (ArchiveMode mode = ArchiveMode.archiving) |
461 const errorMessage = "Could not continue archiving due to unrecognized data format: "; | 469 { |
462 | 470 static if (mode == ArchiveMode.archiving) |
463 else static if (mode == ArchiveMode.unarchiving) | 471 const errorMessage = "Could not continue archiving due to unrecognized data format: "; |
464 const errorMessage = "Could not continue unarchiving due to unrecognized data format: "; | 472 |
473 else static if (mode == ArchiveMode.unarchiving) | |
474 const errorMessage = "Could not continue unarchiving due to unrecognized data format: "; | |
475 } | |
476 } | |
477 | |
478 else | |
479 { | |
480 mixin( | |
481 `template errorMessage (ArchiveMode mode = ArchiveMode.archiving) | |
482 { | |
483 static if (mode == ArchiveMode.archiving) | |
484 enum errorMessage = "Could not continue archiving due to unrecognized data format: "; | |
485 | |
486 else static if (mode == ArchiveMode.unarchiving) | |
487 enum errorMessage = "Could not continue unarchiving due to unrecognized data format: "; | |
488 }` | |
489 ); | |
465 } | 490 } |
466 | 491 |
467 private doc.Node getElement (DataType tag, DataType key, DataType attribute = Attributes.keyAttribute, bool throwOnError = true) | 492 private doc.Node getElement (DataType tag, DataType key, DataType attribute = Attributes.keyAttribute, bool throwOnError = true) |
468 { | 493 { |
469 auto set = lastElement.query[tag].attribute((doc.Node node) { | 494 auto set = lastElement.query[tag].attribute((doc.Node node) { |
470 if (node.name == attribute && node.value == key) | 495 if (node.name == attribute && node.value == key) |
471 return true; | 496 return true; |
472 | 497 |
473 return false; | 498 return false; |
474 }); | 499 }); |
478 | 503 |
479 else | 504 else |
480 { | 505 { |
481 if (throwOnError) | 506 if (throwOnError) |
482 { | 507 { |
483 if (set.nodes.length == 0) | 508 if (set.nodes.length == 0) |
484 throw new ArchiveException(`Could not find an element "` ~ to!(string)(tag) ~ `" with the attribute "` ~ to!(string)(Attributes.keyAttribute) ~ `" with the value "` ~ to!(string)(key) ~ `".`, __FILE__, __LINE__); | 509 throw new ArchiveException(`Could not find an element "` ~ to!(string)(tag) ~ `" with the attribute "` ~ to!(string)(Attributes.keyAttribute) ~ `" with the value "` ~ to!(string)(key) ~ `".`, __FILE__, __LINE__); |
485 | 510 |
486 else | 511 else |
487 throw new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__); | 512 throw new ArchiveException(`Could not unarchive the value with the key "` ~ to!(string)(key) ~ `" due to malformed data.`, __FILE__, __LINE__); |
488 } | 513 } |
489 | 514 |
490 return null; | 515 return doc.Node.invalid; |
491 } | 516 } |
492 } | 517 } |
493 | 518 |
494 private DataType getValueOfAttribute (DataType attribute) | 519 private DataType getValueOfAttribute (DataType attribute) |
495 { | 520 { |
540 return toDataType(idCounter++); | 565 return toDataType(idCounter++); |
541 } | 566 } |
542 | 567 |
543 private void archiveReference (DataType key, DataType id) | 568 private void archiveReference (DataType key, DataType id) |
544 { | 569 { |
545 lastElement.element(null, Tags.referenceTag, id) | 570 lastElement.element(Tags.referenceTag, id) |
546 .attribute(null, Attributes.keyAttribute, key); | 571 .attribute(Attributes.keyAttribute, key); |
547 } | 572 } |
548 | 573 |
549 private DataType unarchiveReference (DataType key) | 574 private DataType unarchiveReference (DataType key) |
550 { | 575 { |
551 auto element = getElement(Tags.referenceTag, key, Attributes.keyAttribute, false); | 576 auto element = getElement(Tags.referenceTag, key, Attributes.keyAttribute, false); |
552 | 577 |
553 if (element) | 578 if (element.isValid) |
554 return element.value; | 579 return element.value; |
555 | 580 |
556 return cast(DataType) null; | 581 return cast(DataType) null; |
557 } | 582 } |
558 | 583 |