[gxml] Collections: added new multi-type collection
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] Collections: added new multi-type collection
- Date: Thu, 27 Feb 2020 17:12:32 +0000 (UTC)
commit 06649c8b0b45204d58ee220a153c87770b27c4bc
Author: Daniel Espinosa <esodan gmail com>
Date: Thu Feb 27 10:52:40 2020 -0600
Collections: added new multi-type collection
A multi-type collection can recognize more than one
object direved from the same type, like an interface
gxml/BaseCollection.vala | 13 +--
gxml/Collections.vala | 86 +++++++++++++++++++
gxml/Parser.vala | 64 ++++++++++----
gxml/XParser.vala | 5 ++
gxml/XdParser.vala | 8 ++
test/SerializationTest.vala | 200 ++++++++++++++++++++++++++++++++++++++------
6 files changed, 331 insertions(+), 45 deletions(-)
---
diff --git a/gxml/BaseCollection.vala b/gxml/BaseCollection.vala
index 6cd91d5..c52e278 100644
--- a/gxml/BaseCollection.vala
+++ b/gxml/BaseCollection.vala
@@ -85,12 +85,15 @@ public abstract class GXml.BaseCollection : GLib.Object, Traversable<DomElement>
* {@inheritDoc}
*/
public void initialize (GLib.Type items_type) throws GLib.Error {
- if (!items_type.is_a (typeof (GXml.Element))) {
+ if (!items_type.is_a (typeof (GXml.DomElement))
+ && !items_type.is_a (typeof (GXml.Object))) {
throw new DomError.INVALID_NODE_TYPE_ERROR
(_("Invalid attempt to initialize a collection using an unsupported type. Only
GXmlGXml.Element is supported"));
}
- var o = GLib.Object.new (items_type) as GXml.Element;
- _items_name = o.local_name;
+ if (!items_type.is_abstract () && items_type.is_instantiatable ()) {
+ var o = GLib.Object.new (items_type) as GXml.Element;
+ _items_name = o.local_name;
+ }
_items_type = items_type;
}
/**
@@ -116,7 +119,7 @@ public abstract class GXml.BaseCollection : GLib.Object, Traversable<DomElement>
public void append (DomElement node) throws GLib.Error {
if (_element == null)
throw new DomError.INVALID_NODE_TYPE_ERROR
- (_("Parent Element is invalid"));
+ (_("Parent Element is invalid. Set 'element' property at construction time"));
if (!(node is GXml.Element))
throw new DomError.INVALID_NODE_TYPE_ERROR
(_("Invalid attempt to set unsupported type. Only GXmlGXml.Element is supported"));
@@ -144,7 +147,7 @@ public abstract class GXml.BaseCollection : GLib.Object, Traversable<DomElement>
clear ();
if (_element == null)
throw new DomError.INVALID_NODE_TYPE_ERROR
- (_("Parent Element is invalid"));
+ (_("Parent Element is invalid. Set 'element' property at construction time"));
for (int i = 0; i < _element.child_nodes.size; i++) {
var n = _element.child_nodes.get (i);
if (n is GXml.Object) {
diff --git a/gxml/Collections.vala b/gxml/Collections.vala
index 4b441d6..0549168 100644
--- a/gxml/Collections.vala
+++ b/gxml/Collections.vala
@@ -337,3 +337,89 @@ public interface GXml.ThreeMap : GLib.Object, GXml.Collection, Traversable<DomEl
*/
public abstract Set<string> third_keys_set (string pkey, string skey);
}
+
+/**
+ * Collection to manage child {@link GXml.DomElement} objects
+ * mapped to different classes, derived or child type of
+ * {@link Collection.items_type}
+ *
+ * A collection using {@link Collection.items_type} as a common
+ * parent {@link GLib.Type} of a set of instantiatable {@link GLib.Type}.
+ *
+ * In the next example, is possible to setup a class for Top element,
+ * having a {@link GXml.CollectionParent} implementation class, supporting
+ * reading any kind of derived classes from the {@link Collection.items_type};
+ * for the example, Time, Goal and Reque are implementations of, say, Child
+ * interface, so they will be added to the collection and deserialized
+ * as an instance of the object, based in the node's name.
+ *
+ * {{{
+ * <Top>
+ * <Time/>
+ * <Goal/>
+ * <Resque/>
+ * }}}
+ *
+ * Implementators, should override {@link types} property
+ * setting up a hash table and use {@link add_supported_type} or
+ * {@link add_supported_types} to add one or a set of types to be supported.
+ * {@link types} is used by {@link GXml.Parser} to detect the types
+ * suuported in a collection to create the corresponding objects of the
+ * currect instantiable {@link GLib.Type} at runtime, adding them to the
+ * collection, corresponding to the element's tag's name.
+ */
+public interface GXml.CollectionParent : GLib.Object, GXml.Collection {
+ /**
+ * Creates a hash map with a set of child instantiable {@link GLib.Type}
+ * of the {@link Collection.items_type}
+ *
+ * Implementators, should override this property in order to create
+ * its own collection of supported instantiatable types.
+ */
+ public virtual GLib.HashTable<string,GLib.Type> types {
+ owned get {
+ return new GLib.HashTable<string,GLib.Type> (str_hash, str_equal);
+ }
+ }
+ /**
+ * Insert a new supported instantiatable type in given hash table, by
+ * instantiating the type, getting its node's local name
+ * as key.
+ *
+ * @param types a {@link GLib.HashTable} to hold supported types
+ * @param parent_type a {@link GLib.Type} as parent of supported types, it is
+ * not necesarry to be an instantiatable type, like interfaces, should be
+ * the same of {@link GXml.Collection.items_type}
+ * @param type a supported instantiatable {@link GLib.Type}
+ * to be added in the collection
+ */
+ public static void add_supported_type (GLib.HashTable<string,GLib.Type> types,
+ GLib.Type parent_type,
+ GLib.Type type)
+ requires (type.is_a (typeof (GXml.Element)))
+ {
+ var o = GLib.Object.new (type) as GXml.Element;
+ string name = o.local_name.down ().dup ();
+ types.insert (name, type);
+ }
+ /**
+ * Insert a set of supported instantiatable type in given hash table, by
+ * instantiating the type, getting its node's local name
+ * as key.
+ *
+ * @param table a {@link GLib.HashTable} to hold supported types
+ * @param parent_type a {@link GLib.Type} as parent of supported types, it is
+ * not necesarry to be an instantiatable type, like interfaces, should be
+ * the same of {@link GXml.Collection.items_type}
+ * @param types an array of supported instantiatable {@link GLib.Type}
+ * to be added in the collection
+ */
+ public static void add_supported_types (GLib.HashTable<string,GLib.Type> table,
+ GLib.Type parent_type,
+ GLib.Type[] types)
+ {
+ for (int i = 0; i < types.length; i++) {
+ add_supported_type (table, parent_type, types[i]);
+ }
+ }
+}
diff --git a/gxml/Parser.vala b/gxml/Parser.vala
index 9fc661c..dbb83c3 100644
--- a/gxml/Parser.vala
+++ b/gxml/Parser.vala
@@ -51,6 +51,18 @@ public interface GXml.Parser : GLib.Object {
* A {@link GXml.DomDocument} to read to or write from
*/
public abstract DomNode node { get; }
+ /**
+ * A collection of child types of found {@link GXml.CollectionParent}
+ * objects, used to instantiate the correct class based on the
+ * node's name.
+ *
+ * The map use the {@link GLib.Type} of the object implementing
+ * {@link GXml.CollectionParent} as the key, to get a {@link GLib.HashTable}
+ * holding a set of instantiable child classes, with the key as the
+ * lowercase of the node's local name to get the {@link GLib.Type}
+ * of the instantiable class to create and add to the collection.
+ */
+ public abstract GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> types { get; }
/**
* Writes a {@link GXml.DomDocument} to a {@link GLib.File}
*/
@@ -252,23 +264,43 @@ public interface GXml.Parser : GLib.Object {
throw new DomError.INVALID_NODE_TYPE_ERROR
(_("Collection '%s' hasn't been constructed properly: items' type property was not set
at construction time or set to invalid type"), col.get_type ().name ());
}
- if (col.items_name == "" || col.items_name == null) {
- throw new DomError.INVALID_NODE_TYPE_ERROR
- (_("Collection '%s' hasn't been constructed properly: items' name property was not set
at construction time"), col.get_type ().name ());
- }
- if (col.element == null || !(col.element is GXml.Object)) {
- throw new DomError.INVALID_NODE_TYPE_ERROR
- (_("Collection '%s' hasn't been constructed properly: element property was not set at
construction time"), col.get_type ().name ());
- }
- if (!(col.element is GXml.Object)) {
- throw new DomError.INVALID_NODE_TYPE_ERROR
- (_("Invalid object of type '%s' doesn't implement GXml.Object interface: can't be
handled by the collection"), col.element.get_type ().name ());
+ GLib.Type obj_type = GLib.Type.INVALID;
+ if (col is CollectionParent) {
+ HashTable<string,GLib.Type> obj_types = null;
+ if (!types.contains (col.get_type ())) {
+ obj_types = ((CollectionParent) col).types;
+ types.insert (col.get_type (), obj_types);
+ } else {
+ obj_types = types.lookup (col.get_type ());
+ }
+ if (obj_types != null) {
+ string n = current_node_name ().down ();
+ if (obj_types.contains (n)) {
+ obj_type = obj_types.lookup (n);
+ }
+ }
+ } else {
+ if (col.items_name == "" || col.items_name == null) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Collection '%s' hasn't been constructed properly: items' name property was not set
at construction time"), col.get_type ().name ());
+ }
+ if (col.element == null || !(col.element is GXml.Object)) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Collection '%s' hasn't been constructed properly: element property was not set at
construction time"), col.get_type ().name ());
+ }
+ if (!(col.element is GXml.Object)) {
+ throw new DomError.INVALID_NODE_TYPE_ERROR
+ (_("Invalid object of type '%s' doesn't implement GXml.Object interface: can't be
handled by the collection"), col.element.get_type ().name ());
+ }
+ if (col.items_name.down () == current_node_name ().down ()) {
+ if (parent.owner_document == null)
+ throw new DomError.HIERARCHY_REQUEST_ERROR
+ (_("No document is set to node"));
+ obj_type = col.items_type;
+ }
}
- if (col.items_name.down () == current_node_name ().down ()) {
- if (parent.owner_document == null)
- throw new DomError.HIERARCHY_REQUEST_ERROR
- (_("No document is set to node"));
- var obj = GLib.Object.new (col.items_type,
+ if (obj_type != GLib.Type.INVALID) {
+ var obj = GLib.Object.new (obj_type,
"owner-document", node.owner_document) as DomElement;
parent.append_child (obj);
read_element (obj as DomElement);
diff --git a/gxml/XParser.vala b/gxml/XParser.vala
index abfc402..f0266b3 100644
--- a/gxml/XParser.vala
+++ b/gxml/XParser.vala
@@ -32,9 +32,13 @@ public class GXml.XParser : GLib.Object, GXml.Parser {
private TextReader tr;
private Xml.TextWriter tw;
private DataInputStream tistream;
+ private GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> _types;
public bool backup { get; set; }
public bool indent { get; set; }
+ public GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> types {
+ get { return _types; }
+ }
public DomNode node { get { return _node; } }
@@ -54,6 +58,7 @@ public class GXml.XParser : GLib.Object, GXml.Parser {
indent = false;
cancellable = null;
tistream = null;
+ _types = new GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> (int_hash, int_equal);
}
public void write_stream (OutputStream stream) throws GLib.Error {
diff --git a/gxml/XdParser.vala b/gxml/XdParser.vala
index aa87d9d..12353d3 100644
--- a/gxml/XdParser.vala
+++ b/gxml/XdParser.vala
@@ -27,6 +27,11 @@
private class GXml.XdParser : GLib.Object, Parser {
private XDocument document;
private DomNode _node;
+ private GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> _types;
+
+ construct {
+ _types = new GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> (int_hash, int_equal);
+ }
public XdParser (XDocument doc) {
document = doc;
@@ -110,6 +115,9 @@ private class GXml.XdParser : GLib.Object, Parser {
}
public bool backup { get; set; }
public bool indent { get; set; }
+ public GLib.HashTable<GLib.Type,GLib.HashTable<string,GLib.Type>> types {
+ get { return _types; }
+ }
public GXml.DomNode node { get { return _node; } }
public Cancellable? cancellable { get; set; }
}
diff --git a/test/SerializationTest.vala b/test/SerializationTest.vala
index b7c0452..87e4ba7 100644
--- a/test/SerializationTest.vala
+++ b/test/SerializationTest.vala
@@ -215,6 +215,93 @@ class GomBasicTypes : GXml.Element {
}
}
+interface Item : GLib.Object, GXml.Object {}
+
+
+class Items : GXml.ArrayList, GXml.CollectionParent {
+ construct {
+ try { initialize (typeof (Item)); } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+ // Override supported types
+ public GLib.HashTable<string,GLib.Type> types {
+ owned get {
+ var c = new GLib.HashTable<string,GLib.Type> (str_hash, str_equal);
+ GXml.CollectionParent.add_supported_types (c, items_type,
+ {
+ typeof (Monitor),
+ typeof (Keyword),
+ typeof (Cpu)
+ });
+ return c;
+ }
+ }
+}
+
+class Monitor : GXml.Element, Item {
+ [Description (nick="::size")]
+ public int size { get; set; }
+ construct {
+ try { initialize ("Monitor"); } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+}
+class Keyword : GXml.Element, Item {
+ [Description (nick="::language")]
+ public string size { get; set; }
+ construct {
+ try { initialize ("Keyword"); } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+}
+class Cpu : GXml.Element, Item {
+ [Description (nick="::language")]
+ public string size { get; set; }
+ construct {
+ try { initialize ("Cpu"); } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+}
+
+abstract interface Container : GLib.Object, GXml.Object {}
+
+class StoreShelf : GXml.Element, Container {
+ [Description (nick="::Id")]
+ public int id { get; set; default = 1; }
+ public Items items { get; set; }
+ construct {
+ try {
+ initialize ("Shelf");
+ set_instance_property ("items");
+ } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+}
+
+class Containers : GXml.ArrayList, GXml.CollectionParent {
+ construct {
+ var s = new StoreShelf ();
+ try { initialize (typeof (Container)); } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+ // Override supported types
+ public GLib.HashTable<string,GLib.Type> types {
+ owned get {
+ var c = new GLib.HashTable<string,GLib.Type> (str_hash, str_equal);
+ GXml.CollectionParent.add_supported_type (c, items_type, typeof (StoreShelf));
+ assert (c.contains ("shelf"));
+ assert (c.lookup ("shelf") != GLib.Type.INVALID);
+ assert (((GLib.Type) c.lookup ("shelf")) == typeof (StoreShelf));
+ return c;
+ }
+ }
+}
+class ComputerStore : GXml.Element {
+ [Description (nick="::name")]
+ public string name { get; set; }
+ public Containers containers { get; set; default = new Containers (); }
+ construct {
+ try {
+ initialize ("ComputerStore");
+ set_instance_property ("containers");
+ } catch (GLib.Error e) { warning ("Error: %s", e.message); }
+ }
+}
+
class SerializationTest : GXmlTest {
public class Book : GXml.Element {
[Description (nick="::Name")]
@@ -545,7 +632,7 @@ class SerializationTest : GXmlTest {
}
}
public static void add_tests () {
- Test.add_func ("/gxml/gom-serialization/write/properties", () => {
+ Test.add_func ("/gxml/serialization/write/properties", () => {
try {
var b = new Book ();
var parser = new XParser (b);
@@ -563,7 +650,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/write/property-ignore", () => {
+ Test.add_func ("/gxml/serialization/write/property-ignore", () => {
var c = new Computer ();
string s = c.to_string ();
assert (s != null);
@@ -579,7 +666,7 @@ class SerializationTest : GXmlTest {
GLib.message ("DOC:"+s);
#endif
});
- Test.add_func ("/gxml/gom-serialization/write/property-long-name", () => {
+ Test.add_func ("/gxml/serialization/write/property-long-name", () => {
var t = new Taxes ();
string s = t.to_string ();
assert (s != null);
@@ -608,7 +695,7 @@ class SerializationTest : GXmlTest {
GLib.message ("DOC:"+s);
#endif
});
- Test.add_func ("/gxml/gom-serialization/write/property-date", () => {
+ Test.add_func ("/gxml/serialization/write/property-date", () => {
var t = new Taxes ();
string s = t.to_string ();
assert (s != null);
@@ -644,7 +731,7 @@ class SerializationTest : GXmlTest {
assert (gd.get_date ().valid ());
assert (gd.value == "2076-03-17");
});
- Test.add_func ("/gxml/gom-serialization/read/property-date", () => {
+ Test.add_func ("/gxml/serialization/read/property-date", () => {
try {
var t = new Taxes ();
t.read_from_string ("<Taxes PayDate=\"2050-12-09\"/>");
@@ -666,7 +753,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/write/property-datetime", () => {
+ Test.add_func ("/gxml/serialization/write/property-datetime", () => {
var t = new Taxes ();
string s = t.to_string ();
assert (s != null);
@@ -699,7 +786,7 @@ class SerializationTest : GXmlTest {
#endif
assert ("Timestamp=\"2023-03-10T15:23:10\"" in s2);
});
- Test.add_func ("/gxml/gom-serialization/write/property-arraylist", () => {
+ Test.add_func ("/gxml/serialization/write/property-arraylist", () => {
try {
var bs = new BookStand ();
string s = bs.to_string ();
@@ -779,7 +866,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/write/property-hashmap", () => {
+ Test.add_func ("/gxml/serialization/write/property-hashmap", () => {
try {
var bs = new BookStore ();
string s = bs.to_string ();
@@ -834,7 +921,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/mappeable", () => {
+ Test.add_func ("/gxml/serialization/mappeable", () => {
try {
var bs = new BookStand ();
assert (bs.hashmap_registers != null);
@@ -861,7 +948,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/write/mappeablepairedkey", () => {
+ Test.add_func ("/gxml/serialization/write/mappeablepairedkey", () => {
try {
var bs = new BookStand ();
assert (bs.hashpair_registers != null);
@@ -883,7 +970,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/write/mappeablethreekey", () => {
+ Test.add_func ("/gxml/serialization/write/mappeablethreekey", () => {
try {
var bs = new BookStand ();
assert (bs.hashthree_registers != null);
@@ -925,7 +1012,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/write/gom-property", () => {
+ Test.add_func ("/gxml/serialization/write/property", () => {
var m = new Motor ();
string s = m.to_string ();
assert (s != null);
@@ -1008,7 +1095,7 @@ class SerializationTest : GXmlTest {
m.model.value = "MODEL1";
assert (m.model.is_valid_value ());
});
- Test.add_func ("/gxml/gom-serialization/read/properties", () => {
+ Test.add_func ("/gxml/serialization/read/properties", () => {
try {
var b = new Book ();
var parser = new XParser (b);
@@ -1036,7 +1123,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/read/bad-node-name", () => {
+ Test.add_func ("/gxml/serialization/read/bad-node-name", () => {
try {
var b = new Book ();
b.read_from_string ("<chair name=\"Tall\"/>");
@@ -1053,7 +1140,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/read/object-property", () => {
+ Test.add_func ("/gxml/serialization/read/object-property", () => {
try {
var b = new BookRegister ();
string s = b.to_string ();
@@ -1072,7 +1159,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/read/gom-property", () => {
+ Test.add_func ("/gxml/serialization/read/property", () => {
try {
var m = new Motor ();
string s = m.to_string ();
@@ -1108,7 +1195,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/read/property-arraylist", () => {
+ Test.add_func ("/gxml/serialization/read/property-arraylist", () => {
try {
var bs = new BookStand ();
string s = bs.to_string ();
@@ -1145,7 +1232,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/read/property-hashmap", () => {
+ Test.add_func ("/gxml/serialization/read/property-hashmap", () => {
try {
var bs = new BookStand ();
string s = bs.to_string ();
@@ -1190,7 +1277,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/multiple-child-collections",
+ Test.add_func ("/gxml/serialization/multiple-child-collections",
() => {
try {
double time;
@@ -1250,7 +1337,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/collections/hashpairedmap/keys",
+ Test.add_func ("/gxml/serialization/collections/hashpairedmap/keys",
() => {
try {
var ops = new Operations ();
@@ -1302,7 +1389,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/collections/hashthreemap/keys",
+ Test.add_func ("/gxml/serialization/collections/hashthreemap/keys",
() => {
try {
var ks = new ThreeKeys ();
@@ -1358,7 +1445,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/basic-types",
+ Test.add_func ("/gxml/serialization/basic-types",
() => {
try {
var bt = new GomBasicTypes ();
@@ -1399,7 +1486,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/collection/iteration", () => {
+ Test.add_func ("/gxml/serialization/collection/iteration", () => {
try {
var bs = new BookStore ();
assert (bs.books == null);
@@ -1502,12 +1589,77 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
}
});
- Test.add_func ("/gxml/gom-serialization/attribute-gobject", () => {
+ Test.add_func ("/gxml/serialization/attribute-gobject", () => {
var tk = new ThreeKey ();
assert (tk.code == null);
assert (tk.get_attribute ("Code") == null);
tk.code = "code";
assert (tk.get_attribute ("Code") == "code");
});
+ Test.add_func ("/gxml/serialization/collection-parent/list/read", () => {
+ try {
+ var cs = new ComputerStore ();
+ assert (cs.containers.types.contains ("shelf"));
+ assert (cs.containers.types.lookup ("shelf") == typeof (StoreShelf));
+ string str = """
+ <ComputerStore><Shelf Id="2"><Cpu/></Shelf></ComputerStore>
+ """;
+ cs.read_from_string (str);
+ bool found_shelf = false;
+ bool found_cpu = false;
+ foreach (GXml.DomNode n in cs.child_nodes) {
+ message ("Found Type: %s", n.get_type ().name ());
+ if (n is StoreShelf) {
+ found_shelf = true;
+ foreach (GXml.DomNode cn in n.child_nodes) {
+ message ("Found Type: %s", n.get_type ().name ());
+ if (cn is Cpu) {
+ found_cpu = true;
+ }
+ }
+ }
+ }
+ assert (found_shelf);
+ assert (found_cpu);
+ message ("Read:\n%s", cs.write_string ());
+ assert ("""<ComputerStore><Shelf Id="2"><Cpu/></Shelf></ComputerStore>""" in cs.write_string ());
+ str = """
+ <ComputerStore><Shelf Id="2"><Cpu/><Monitor size="32"/><Keyword/></Shelf></ComputerStore>
+ """;
+ cs = new ComputerStore ();
+ cs.read_from_string (str);
+ message ("Read:\n%s", cs.write_string ());
+ assert ("""<ComputerStore><Shelf Id="2"><Cpu/><Monitor
size="32"/><Keyword/></Shelf></ComputerStore>""" in cs.write_string ());
+ found_shelf = false;
+ bool found_monitor = false;
+ bool found_keyword = false;
+ found_cpu = false;
+ foreach (GXml.DomNode n in cs.child_nodes) {
+ message ("Found Type: %s", n.get_type ().name ());
+ if (n is StoreShelf) {
+ found_shelf = true;
+ foreach (GXml.DomNode cn in n.child_nodes) {
+ message ("Found Type: %s", n.get_type ().name ());
+ if (cn is Monitor) {
+ found_monitor = true;
+ assert (((Monitor) cn).size == 32);
+ }
+ if (cn is Keyword) {
+ found_keyword = true;
+ }
+ if (cn is Cpu) {
+ found_cpu = true;
+ }
+ }
+ }
+ }
+ assert (found_shelf);
+ assert (found_monitor);
+ assert (found_keyword);
+ assert (found_cpu);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]