[gxml] Moved Xom/Json implementation to Xom library
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] Moved Xom/Json implementation to Xom library
- Date: Tue, 15 Apr 2014 00:04:29 +0000 (UTC)
commit 1f9d1bbc4d29b6cc1e5bffb453fff98b62283e84
Author: Daniel Espinosa <esodan gmail com>
Date: Mon Apr 14 19:03:09 2014 -0500
Moved Xom/Json implementation to Xom library
Cleaned out GXml from any serialization framework.
gxml/Document.vala | 4 +-
gxml/Makefile.am | 5 +-
gxml/Serializable.vala | 567 ----------------------------------
gxml/Serialization.vala | 12 +-
gxml/xom/Makefile.am | 7 +-
gxml/{ => xom}/SerializableJson.vala | 15 +-
gxml/xom/Serialization.vala | 439 ++++++++++++++++++++++++++
test/SerializableTest.vala | 10 +-
test/SerializationTest.vala | 11 +-
9 files changed, 472 insertions(+), 598 deletions(-)
---
diff --git a/gxml/Document.vala b/gxml/Document.vala
index 7ed2244..7a777e1 100644
--- a/gxml/Document.vala
+++ b/gxml/Document.vala
@@ -1,4 +1,4 @@
-/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
/* Document.vala
*
* Copyright (C) 2011-2013 Richard Schwarting <aquarichy gmail com>
@@ -1020,7 +1020,7 @@ namespace GXml {
return (xmldoc->children != null);
}
- internal unowned Node copy_node (Node foreign_node, bool deep = true) {
+ public unowned Node copy_node (Node foreign_node, bool deep = true) {
Xml.Node *our_copy_xml = ((BackedNode)foreign_node).node->doc_copy (this.xmldoc, deep
? 1 : 0);
// TODO: do we need to append this to this.new_nodes? Do we need to append the
result to this.nodes_to_free? Test memory implications
return this.lookup_node (our_copy_xml); // inducing a GXmlNode
diff --git a/gxml/Makefile.am b/gxml/Makefile.am
index ae2f5d7..ac68611 100644
--- a/gxml/Makefile.am
+++ b/gxml/Makefile.am
@@ -35,10 +35,7 @@ sources = \
NodeType.vala \
Notation.vala \
ProcessingInstruction.vala \
- Text.vala \
- Serializable.vala \
- SerializableJson.vala \
- Serialization.vala
+ Text.vala
### General Compilation flags
diff --git a/gxml/Serialization.vala b/gxml/Serialization.vala
index f90ff54..3c3dc01 100644
--- a/gxml/Serialization.vala
+++ b/gxml/Serialization.vala
@@ -1,4 +1,4 @@
-/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
/* Serialization.vala
*
* Copyright (C) 2012-2013 Richard Schwarting <aquarichy gmail com>
@@ -27,7 +27,7 @@
using GXml;
-namespace GXml {
+namespace Xom {
private static void print_object_properties (GLib.Object obj) {
ParamSpec[] properties;
properties = obj.get_class ().list_properties ();
@@ -106,7 +106,7 @@ namespace GXml {
{
Type type;
Value value;
- Node value_node;
+ GXml.Node value_node;
Serializable serializable = null;
if (object.get_type ().is_a (typeof (Serializable))) {
@@ -174,7 +174,7 @@ namespace GXml {
on the interface 'GeeBidirSortedSet' */
child_object = value.get_object ();
Document value_doc = Serialization.serialize_object (child_object);
// catch serialisation errors?
-
+ // TODO: Make copy_node public to allow others to use it
value_node = doc.copy_node (value_doc.document_element);
} else if (type.name () == "gpointer") {
GLib.warning ("DEBUG: skipping gpointer with name '%s' of object '%s'",
prop_spec.name, object.get_type ().name ());
@@ -216,7 +216,7 @@ namespace GXml {
Element root;
ParamSpec[] prop_specs;
Element prop;
- Node value_prop = null;
+ GXml.Node value_prop = null;
string oid;
Serialization.init_caches ();
@@ -413,7 +413,7 @@ namespace GXml {
Serialization.deserialize_cache.set (oid, obj);
specs = obj_class.list_properties ();
- foreach (Node child_node in obj_elem.child_nodes) {
+ foreach (GXml.Node child_node in obj_elem.child_nodes) {
if (child_node.node_name == "Property") {
Element prop_elem;
string pname;
diff --git a/gxml/xom/Makefile.am b/gxml/xom/Makefile.am
index 1a31949..d239b86 100644
--- a/gxml/xom/Makefile.am
+++ b/gxml/xom/Makefile.am
@@ -21,7 +21,9 @@ sources = \
SerializableGeeDualKeyMap.vala \
SerializableMapDualKey.vala \
SerializableGeeArrayList.vala \
- SerializableContainer.vala
+ SerializableContainer.vala \
+ SerializableJson.vala \
+ Serialization.vala
### General Compilation flags
@@ -51,8 +53,7 @@ AM_VALAFLAGS = \
--library=xom-0.4 \
$(top_srcdir)/vapi/config.vapi \
--vapidir=. \
- --vapidir=$(top_srcdir)/vapi \
- --vapidir=../gxml \
+ --vapidir=.. \
--pkg gxml-0.4 \
--pkg libxml-2.0 \
--pkg gee-0.8 \
diff --git a/gxml/SerializableJson.vala b/gxml/xom/SerializableJson.vala
similarity index 95%
rename from gxml/SerializableJson.vala
rename to gxml/xom/SerializableJson.vala
index 376776a..e80eda6 100644
--- a/gxml/SerializableJson.vala
+++ b/gxml/xom/SerializableJson.vala
@@ -22,6 +22,7 @@
* Daniel Espinosa <esodan gmail com>
*/
+using GXml;
/*
Version 3: json-glib version
@@ -60,7 +61,7 @@
* serialization themselves, including non-public properties or
* data types not automatically supported by { link GXml.Serialization}.
*/
-public class GXml.SerializableJson : GLib.Object, Serializable
+public class Xom.SerializableJson : GLib.Object, Xom.Serializable
{
/* Serializable Interface properties */
protected ParamSpec[] properties { get; set; }
@@ -115,7 +116,7 @@ public class GXml.SerializableJson : GLib.Object, Serializable
* Is up to you to add convenient Element node to a Document, in order to be
* used by serialize and add new <Object> tags per object to serialize.
*/
- public Node? serialize (Node node) throws GLib.Error
+ public GXml.Node? serialize (GXml.Node node) throws GLib.Error
{
Document doc;
Element root;
@@ -144,7 +145,7 @@ public class GXml.SerializableJson : GLib.Object, Serializable
{
Type type;
Value val;
- Node value_node = null;
+ GXml.Node value_node = null;
Element prop_node;
type = prop.value_type;
@@ -195,7 +196,9 @@ public class GXml.SerializableJson : GLib.Object, Serializable
this.get_property_value (prop, ref val);
child_object = val.get_object ();
Document value_doc = Serialization.serialize_object (child_object);
- value_node = doc.copy_node (value_doc.document_element);
+ value_node = doc.create_element ("fake");
+ value_doc.document_element.copy (ref value_node, true);
+ //value_node = doc.copy_node (value_doc.document_element);
prop_node.append_child (value_node);
return prop_node;
}
@@ -204,7 +207,7 @@ public class GXml.SerializableJson : GLib.Object, Serializable
return prop_node;
}
- public Node? deserialize (Node node) throws GLib.Error
+ public GXml.Node? deserialize (GXml.Node node) throws GLib.Error
{
Element obj_elem;
ParamSpec[] specs;
@@ -218,7 +221,7 @@ public class GXml.SerializableJson : GLib.Object, Serializable
specs = this.list_serializable_properties ();
- foreach (Node child_node in obj_elem.child_nodes) {
+ foreach (GXml.Node child_node in obj_elem.child_nodes) {
deserialize_property (child_node);
}
return obj_elem;
diff --git a/gxml/xom/Serialization.vala b/gxml/xom/Serialization.vala
new file mode 100644
index 0000000..db48ceb
--- /dev/null
+++ b/gxml/xom/Serialization.vala
@@ -0,0 +1,439 @@
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* Serialization.vala
+ *
+ * Copyright (C) 2012-2013 Richard Schwarting <aquarichy gmail com>
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Richard Schwarting <aquarichy gmail com>
+ */
+
+/* TODO: so it seems we can get property information from GObjectClass
+ but that's about it. Need to definitely use introspection for anything
+ tastier */
+/* TODO: document memory management for the C side */
+
+using GXml;
+
+namespace Xom {
+ private static void print_object_properties (GLib.Object obj) {
+ ParamSpec[] properties;
+ properties = obj.get_class ().list_properties ();
+ stdout.printf ("object has %d properties\n", properties.length);
+ foreach (ParamSpec prop_spec in properties) {
+ stdout.printf ("---\n");
+ stdout.printf ("name %s\n", prop_spec.name);
+ stdout.printf (" value_type %s\n", prop_spec.value_type.name ());
+ stdout.printf (" owner_type %s\n", prop_spec.owner_type.name ());
+ stdout.printf (" get_name () %s\n", prop_spec.get_name ());
+ stdout.printf (" get_blurb () %s\n", prop_spec.get_blurb ());
+ stdout.printf (" get_nick () %s\n", prop_spec.get_nick ());
+ }
+ }
+
+ /**
+ * Errors from { link Serialization}.
+ */
+ public errordomain SerializationError {
+ /**
+ * An unknown { link GLib.Type} was encountered.
+ */
+ UNKNOWN_TYPE,
+ /**
+ * A property was described in XML that is not known { link GLib.Type}.
+ */
+ UNKNOWN_PROPERTY,
+ /**
+ * Serialization/Deserialization is unsupported for given object type
+ */
+ UNSUPPORTED_OBJECT_TYPE,
+ /**
+ * Serialization/Deserialization is unsupported for given property type
+ */
+ UNSUPPORTED_PROPERTY_TYPE,
+ /**
+ * Serialization/Deserialization is unsupported for given { link GLib.Type}
+ */
+ UNSUPPORTED_TYPE,
+ /**
+ * Serialization/Deserialization is unsupported for given XML structure
+ */
+ UNSUPPORTED_FILE_FORMAT
+ }
+
+ /**
+ * Serializes and deserializes { link GLib.Object}s to and from
+ * { link GXml.Node}.
+ *
+ * Serialization can automatically serialize a variety of public
+ * properties. { link GLib.Object}s can also implement the
+ * { link GXml.Serializable} to partially or completely manage
+ * serialization themselves, including non-public properties or
+ * data types not automatically supported by { link GXml.Serialization}.
+ */
+ public class Serialization : GLib.Object {
+ private static void print_debug (GXml.Document doc, GLib.Object object) {
+ stdout.printf ("Object XML\n---\n%s\n", doc.to_string ());
+
+ stdout.printf ("object\n---\n");
+ stdout.printf ("get_type (): %s\n", object.get_type ().name ());
+ stdout.printf ("get_class ().get_type (): %s\n", object.get_class ().get_type ().name
());
+ Xom.print_object_properties (object);
+ }
+
+ /*
+ * This coordinates the automatic serialization of individual
+ * properties. As of 0.2, it supports enums, anything that
+ * { link GLib.Value} can transform into a string, and
+ * operates recursively.
+ */
+ private static GXml.Node serialize_property (GLib.Object object,
+ ParamSpec prop_spec,
+ GXml.Document doc)
+ throws GLib.Error
+ {
+ Type type;
+ Value value;
+ GXml.Node value_node;
+ Serializable serializable = null;
+
+ if (object.get_type ().is_a (typeof (Serializable))) {
+ serializable = (Serializable)object;
+ }
+
+ type = prop_spec.value_type;
+
+ if (prop_spec.value_type.is_enum ()) {
+ /* We're going to handle this simply by saving it
+ as an int. If we save a string representation,
+ we can't easily convert it back to the number
+ in a generic fashion unless we can use GEnumClass,
+ but I can't figure out how to get that right now,
+ except from a GParamSpecEnum, but I don't know
+ how to get that, at least in Vala (e.g. is it
+ supposed to be as simple in C as casting the
+ GParamSpec for an enum to GParamSpecEnum (assuming
+ it truly is the latter, but is returned as the
+ former by list_properties) */
+ value = Value (typeof (int));
+ object.get_property (prop_spec.name, ref value);
+ value_node = doc.create_text_node ("%d".printf (value.get_int ()));
+ /* TODO: in the future, perhaps figure out GEnumClass
+ and save it as the human readable enum value :D */
+ } else if (Value.type_transformable (prop_spec.value_type, typeof (string))) { //
e.g. int, double, string, bool
+ value = Value (typeof (string));
+ object.get_property (prop_spec.name, ref value);
+ value_node = doc.create_text_node (value.get_string ());
+ } else if (type == typeof (GLib.Type)) {
+ value_node = doc.create_text_node (type.name ());
+/*
+ } else if (type.is_a (typeof (Gee.Collection))) {
+ // We need to be able to figure out
+ // * what generics it has, and
+ // * any parametres for delegates it might have used.
+ GXml.print_object_properties (object);
+ value_node = null;
+ } else if (type == typeof (GLib.HashTable)) {
+
+ } else if (type == typeof (Gee.List)) {
+ // TODO: can we do a catch all for Gee.Collection and have <Collection /> ?
+ } else if (type.is_a (typeof (Gee.TreeSet))) {
+ object.get_property (prop_spec, ref value);
+ doc.create_element ("Collection");
+ foreach (Object member in
+ } else if {
+ g-dup-func gpointer
+ GParamPointer
+ $43 = {g_type_instance = {g_class = 0x67ad30}, name = 0x7ffff7b7d685
"g-dup-func", flags = 234, value_type = 68, owner_type = 14758512, _nick = 0x7ffff7b7d67c "dup func", _blurb =
+ 0x7ffff7b7d67c "dup func", qdata = 0x0, ref_count = 4, param_id = 2}
+*/
+ } else if (type.is_a (typeof (GLib.Object))
+ && ! type.is_a (typeof (Gee.Collection)))
+ {
+ GLib.Object child_object;
+
+ // TODO: this is going to get complicated
+ value = Value (typeof (GLib.Object));
+ object.get_property (prop_spec.name, ref value);
+ /* This can fail; consider case of Gee.TreeSet that isn't special
cased above, gets error
+
(/home/richard/mine/development/gnome/gdom/gxml/test/.libs/gxml_test:10996):
+ GLib-GObject-CRITICAL **: Read-only property
'read-only-view' on class 'GeeReadOnlyBidirSortedSet' has type
+ 'GeeSortedSet' which is not equal to or more restrictive
than the type 'GeeBidirSortedSet' of the property
+ on the interface 'GeeBidirSortedSet' */
+ child_object = value.get_object ();
+ Document value_doc = Serialization.serialize_object (child_object);
// catch serialisation errors?
+ // TODO: Make copy_node public to allow others to use it
+ value_node = doc.copy_node (value_doc.document_element);
+ } else if (type.name () == "gpointer") {
+ GLib.warning ("DEBUG: skipping gpointer with name '%s' of object '%s'",
prop_spec.name, object.get_type ().name ());
+ value_node = doc.create_text_node (prop_spec.name);
+ } else {
+ throw new SerializationError.UNSUPPORTED_PROPERTY_TYPE ("Can't currently
serialize type '%s' for property '%s' of object '%s'", type.name (), prop_spec.name, object.get_type ().name
());
+ }
+
+ return value_node;
+ }
+
+ /**
+ * Serializes a { link GLib.Object} into a { link GXml.Document}.
+ *
+ * This takes a { link GLib.Object} and serializes it
+ * into a { link GXml.Document} which can be saved to
+ * disk or transferred over a network. It handles
+ * serialization of primitive properties and some more
+ * complex ones like enums, other { link GLib.Object}s
+ * recursively, and some collections.
+ *
+ * The serialization process can be customised for an object
+ * by having the object implement the { link GXml.Serializable}
+ * interface, which allows direct control over the
+ * conversation of individual properties into { link GXml.Node}s
+ * and the object's list of properties as used by
+ * { link GXml.Serialization}.
+ *
+ * A { link GXml.SerializationError} may be thrown if there is
+ * a problem serializing a property (e.g. the type is unknown,
+ * unsupported, or the property isn't known to the object).
+ *
+ * @param object A { link GLib.Object} to serialize
+ * @return a { link GXml.Document} representing the serialized `object`
+ */
+ public static GXml.Document serialize_object (GLib.Object object) throws GLib.Error
+ {
+ Document doc;
+ Element root;
+ ParamSpec[] prop_specs;
+ Element prop;
+ GXml.Node value_prop = null;
+ string oid;
+
+ Serialization.init_caches ();
+ /* Create an XML Document to return the object
+ in. TODO: consider just returning an
+ <Object> node; but then we'd probably want
+ a separate document for it to already be a
+ part of as its owner_document. */
+ doc = new Document ();
+ if (object is Serializable) {
+ ((Serializable) object).serialize (doc);
+ return doc;
+ }
+ // If the object has been serialized before, let's not do it again!
+ oid = "%p".printf (object);
+ // first, check if its been serialised already, and if so, just return an ObjectRef
element for it.
+ if (oid != "" && Serialization.serialize_cache.contains (oid)) {
+ // GLib.message ("cache hit on oid %s", oid);
+ root = doc.create_element ("ObjectRef");
+ doc.append_child (root);
+ root.set_attribute ("otype", object.get_type ().name ());
+ root.set_attribute ("oid", oid);
+ return doc;
+ }
+
+ if (object is Serializable) {
+ ((Serializable) object).serialize (doc);
+ Serialization.serialize_cache.set (oid, doc.document_element);
+ return doc;
+ }
+ // For now and on assume is not a Serializable object
+ root = doc.create_element ("Object");
+ doc.append_child (root);
+ root.set_attribute ("otype", object.get_type ().name ());
+ root.set_attribute ("oid", oid);
+ // Cache this before we start exploring properties in case there's a cycle
+ Serialization.serialize_cache.set (oid, root);
+
+ /* TODO: make sure we don't use an out param for our returned list
+ size in our interface's list_properties (), using
+ [CCode (array_length_type = "guint")] */
+ prop_specs = object.get_class ().list_properties ();
+
+ /* Exam the properties of the object and store
+ them with their name, type and value in XML
+ Elements. Use GValue to convert them to
+ strings. (Too bad deserialising isn't that
+ easy w.r.t. string conversion.) */
+ foreach (ParamSpec prop_spec in prop_specs) {
+ prop = doc.create_element ("Property");
+ prop.set_attribute ("ptype", prop_spec.value_type.name ());
+ prop.set_attribute ("pname", prop_spec.name);
+ value_prop = Serialization.serialize_property (object, prop_spec, doc);
+ prop.append_child (value_prop);
+ root.append_child (prop);
+ }
+
+ /* Debug output */
+ bool debug = false;
+ if (debug) {
+ Serialization.print_debug (doc, object);
+ }
+
+ return doc;
+ }
+
+ /*
+ * This handles deserializing properties individually.
+ * Because { link GLib.Value} doesn't handle transforming
+ * strings back to other types, we use our own function to do
+ * that.
+ */
+ private static void deserialize_property (ParamSpec spec, Element prop_elem,
+ out Value val)
+ throws GLib.Error
+ {
+ Type type;
+ type = spec.value_type;
+ // Get value and save this all as a parameter
+ val = Value (type);
+ if (GLib.Value.type_transformable (type, typeof (string))) {
+ Serializable.string_to_gvalue (prop_elem.content, ref val);
+ } else if (type.is_a (typeof (GLib.Object))) {
+ GXml.Node prop_elem_child;
+ Object property_object;
+ prop_elem_child = prop_elem.first_child;
+ property_object = Serialization.deserialize_object_from_node
(prop_elem_child);
+ val.set_object (property_object);
+ }
+ }
+
+ /**
+ * FIXME: DON'T USE CACHE. SERIALIZE OVER NEW OBJECTS OR OVERWRITE PROPERTIES.
+ * When serialize a set of objects, you can add Node Elements <Object>
+ * as many as objects you have serialized to the XML Document. On
+ * deserialization, you must create a new GObject, on the fly, for each
+ * <Object> tag found in the file.
+ *
+ * This table is used while deserializing objects to avoid
+ * creating duplicate objects when we encounter multiple
+ * references to a single serialized object.
+ *
+ * TODO: one problem, if you deserialize two XML structures,
+ * some differing objects might have the same OID :( Need to
+ * find make it more unique than just the memory address. SEE ABOVE!!!!*/
+ private static HashTable<string,Object> deserialize_cache = null;
+ private static HashTable<string,GXml.Node> serialize_cache = null;
+ // public so that tests can call it
+ public static void clear_cache () { // TODO: rename to clear_caches, just changed back
temporarily to avoid API break for 0.3.2
+ if (Serialization.deserialize_cache != null)
+ Serialization.deserialize_cache.remove_all ();
+ if (Serialization.serialize_cache != null)
+ Serialization.serialize_cache.remove_all ();
+ }
+
+ private static void init_caches () {
+ if (Serialization.deserialize_cache == null) {
+ Serialization.deserialize_cache = new HashTable<string,Object> (str_hash,
str_equal);
+ }
+ if (Serialization.serialize_cache == null) {
+ Serialization.serialize_cache = new HashTable<string,GXml.Node> (str_hash,
str_equal);
+ }
+ }
+
+ /**
+ * Deserialize a { link GXml.Document} back into a { link GLib.Object}.
+ *
+ * This deserializes a { link GXml.Document} back into a
+ * { link GLib.Object}. The { link GXml.Document}
+ * must represent a { link GLib.Object} as serialized
+ * by { link GXml.Serialization}. The types of the
+ * objects that are being deserialized must be known
+ * to the system deserializing them or a
+ * { link GXml.SerializationError} will result.
+ *
+ * @type object type to deserialize
+ * @doc a { link GXml.Document} to deseralize from
+ * @return the deserialized { link GLib.Object}
+ */
+ public static GLib.Object deserialize_object (Type type, GXml.Document doc) throws GLib.Error
+ {
+ if (type.is_a (typeof (Serializable))) {
+ Object object = Object.new (type);
+ ((Serializable) object).deserialize (doc);
+ return object;
+ }
+ return deserialize_object_from_node (doc.document_element);
+ }
+
+ /**
+ * This function must assume deserialize over non-Serializable objects
+ * because Serializable have its own method serialize/deserialize
+ */
+ internal static GLib.Object? deserialize_object_from_node (GXml.Node obj_node)
+ throws GLib.Error
+ {
+ Element obj_elem;
+ string otype;
+ string oid;
+ Type type;
+ Object obj;
+ unowned ObjectClass obj_class;
+ ParamSpec[] specs;
+
+ obj_elem = (Element)obj_node;
+
+ // FIXME: Remove cache.
+ // If the object has been deserialised before, get it from cache
+ oid = obj_elem.get_attribute ("oid");
+ Serialization.init_caches ();
+ if (oid != "" && Serialization.deserialize_cache.contains (oid)) {
+ return Serialization.deserialize_cache.get (oid);
+ }
+
+ // Get the object's type
+ // TODO: wish there was a g_object_class_from_name () method
+ otype = obj_elem.get_attribute ("otype");
+ type = Type.from_name (otype);
+ if (type == 0) {
+ throw new SerializationError.UNKNOWN_TYPE ("Deserializing unknown GType '%s'
objects is unsupported", otype);
+ }
+
+ if (type.is_a (typeof (Serializable))) {
+ obj = Object.new (type);
+ ((Serializable) obj).deserialize (obj_node);
+ return obj;
+ }
+
+ // Get the list of properties as ParamSpecs
+ obj = Object.newv (type, new Parameter[] {}); // TODO: causes problems with Enums
when 0 isn't a valid enum value (e.g. starts from 2 or something)
+ obj_class = obj.get_class ();
+
+ // Set it as the last possible action, so that invalid objects won't end up getting
stored // Changed our mind, for deserializing ObjectRefs
+ Serialization.deserialize_cache.set (oid, obj);
+ specs = obj_class.list_properties ();
+
+ foreach (GXml.Node child_node in obj_elem.child_nodes) {
+ if (child_node.node_name == "Property") {
+ Element prop_elem;
+ string pname;
+ Value val;
+
+ prop_elem = (Element)child_node;
+ pname = prop_elem.get_attribute ("pname");
+ // Check name and type for property
+ ParamSpec? spec = null;
+ spec = obj_class.find_property (pname);
+
+ if (spec == null) {
+ throw new SerializationError.UNKNOWN_PROPERTY ("Unknown
property '%s' found, for object type '%s'-->XML: [%s]", pname, otype, obj_elem.to_string ());
+ return null;
+ }
+ Serialization.deserialize_property (spec, prop_elem, out val);
+ obj.set_property (pname, val);
+ }
+ }
+ return obj;
+ }
+ }
+}
diff --git a/test/SerializableTest.vala b/test/SerializableTest.vala
index 7b914d7..e5a9b0a 100644
--- a/test/SerializableTest.vala
+++ b/test/SerializableTest.vala
@@ -51,7 +51,7 @@ using Gee;
Test overriding {set,get}_property
*/
-public class SerializableTomato : GXml.SerializableJson {
+public class SerializableTomato : Xom.SerializableJson {
public int weight;
private int age { get; set; }
public int height { get; set; }
@@ -77,7 +77,7 @@ public class SerializableTomato : GXml.SerializableJson {
}
}
-public class SerializableCapsicum : GXml.SerializableJson {
+public class SerializableCapsicum : Xom.SerializableJson {
public int weight;
private int age { get; set; }
public int height { get; set; }
@@ -97,8 +97,8 @@ public class SerializableCapsicum : GXml.SerializableJson {
this.age = age;
this.height = height;
this.ratings = ratings;
- ((GXml.Serializable)this).serialize_unknown_property_type.connect
(serialize_unknown_property_type);
- ((GXml.Serializable)this).deserialize_unknown_property_type.connect
(deserialize_unknown_property_type);
+ ((Xom.Serializable)this).serialize_unknown_property_type.connect
(serialize_unknown_property_type);
+ ((Xom.Serializable)this).deserialize_unknown_property_type.connect
(deserialize_unknown_property_type);
}
/* TODO: do we really need GLib.Value? or should we modify the object directly?
@@ -140,7 +140,7 @@ public class SerializableCapsicum : GXml.SerializableJson {
}
-public class SerializableBanana : GXml.SerializableJson {
+public class SerializableBanana : Xom.SerializableJson {
private int private_field;
public int public_field;
private int private_property { get; set; }
diff --git a/test/SerializationTest.vala b/test/SerializationTest.vala
index bd26691..6672780 100644
--- a/test/SerializationTest.vala
+++ b/test/SerializationTest.vala
@@ -1,5 +1,6 @@
-/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* -*- Mode: vala; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
using GXml;
+using Xom;
using Gee;
/**
@@ -323,7 +324,7 @@ class SerializationTest : GXmlTest {
Test.message ("Regular expression [%s] for test failed: %s",
expectation, e.message);
assert_not_reached ();
- } catch (GXml.SerializationError e) {
+ } catch (Xom.SerializationError e) {
Test.message ("%s", e.message);
assert_not_reached ();
} catch (GLib.Error e) {
@@ -373,7 +374,7 @@ class SerializationTest : GXmlTest {
assert_not_reached ();
} catch (GLib.Error e) {
//stdout.printf (@"Cought Error: $(e.message)");
- if (e is GXml.SerializationError.UNKNOWN_PROPERTY) {
+ if (e is Xom.SerializationError.UNKNOWN_PROPERTY) {
// pass
} else {
GLib.message (@"Error is not UNKNOWN_PROPERTY: $(e.message)");
@@ -389,7 +390,7 @@ class SerializationTest : GXmlTest {
Serialization.deserialize_object (0, doc);
assert_not_reached ();
} catch (GLib.Error e) {
- if (e is SerializationError.UNKNOWN_TYPE) {
+ if (e is Xom.SerializationError.UNKNOWN_TYPE) {
// pass
}
else {
@@ -410,7 +411,7 @@ class SerializationTest : GXmlTest {
fruit = (Fruit)Serialization.deserialize_object (typeof (Fruit), doc);
assert_not_reached ();
} catch (GLib.Error e) {
- if (e is SerializationError.UNKNOWN_PROPERTY)
+ if (e is Xom.SerializationError.UNKNOWN_PROPERTY)
{ // pass
}
else {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]