Skip to content
Snippets Groups Projects
Commit 28eb53f1 authored by Daniel Espinosa's avatar Daniel Espinosa
Browse files

Document: interface removed

parent a186066f
Branches
Tags
No related merge requests found
/* -*- Mode: vala; indent-tabs-mode: nil; c-basic-offset: 0; tab-width: 2 -*- */
/* ObjectModel.vala
*
* Copyright (C) 2015 Daniel Espinosa <esodan@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:
* Daniel Espinosa <esodan@gmail.com>
*/
using Gee;
/**
* Errors for documents handling {@link GXml.Document} reading/writing
*/
[Version (deprecated = true, deprecated_since = "0.18", replacement = "GXml.DomError")]
public errordomain GXml.DocumentError {
INVALID_DOCUMENT_ERROR,
INVALID_FILE
}
/**
* DOM1 Interface to handle XML documents.
*
* Provides basic interfaces to read and create XML documents.
*/
[Version (deprecated = true, deprecated_since = "0.18", replacement = "GXml.DomDocument")]
public interface GXml.Document : Object, GXml.Node
{
/**
* Controls if writting this documents should use indent.
*/
public abstract bool indent { get; set; }
/**
* Controls if writting this documentsshould use namespaces
* declaration at root {@link GXml.Element}.
*
* This removes full declaration at childs nodes, because they
* are just prefixed if a prefix was defined for namespace apply.
*/
public abstract bool ns_top { get; set; }
/**
* Controls if writting this document should use default namespace's prefix
* to prefix root's childs {@link GXml.Element}.
*
* This removes prefix on childs using default namespace. Default namespace
* is the first one found in {@link GXml.Node.namespaces} for this document.
*/
public abstract bool prefix_default_ns { get; set; }
/**
* Controls if writting to a {@link GLib.File} creates a backup, by default
* is true;
*/
public abstract bool backup { get; set; }
/**
* XML document root node as a {@link GXml.Element}.
*/
public abstract GXml.Node root { owned get; }
/**
* Stores a {@link GLib.File} to save/read XML documents to/from.
*/
public abstract GLib.File file { get; set; }
/**
* This method should create a new {@link GXml.Element}.
*
* Is a matter of you to add as a child to any other
* {@link GXml.Node}.
*/
public abstract GXml.Node create_element (string name) throws GLib.Error;
/**
* Creates a new {@link GXml.Text}.
*
* Is a matter of you to add as a child to any other
* {@link GXml.Node}, like a {@link GXml.Element} node.
*/
public abstract GXml.Node create_text (string text);
/**
* Creates a new {@link GXml.Comment}.
*
* Is a matter of you to add as a child to any other
* {@link GXml.Node}, like a {@link GXml.Element} node.
*/
public abstract GXml.Node create_comment (string text);
/**
* Creates a new {@link GXml.ProcessingInstruction}.
*
* Is a matter of you to add as a child to any other
* {@link GXml.Node}, like a {@link GXml.Element} node.
*/
public abstract GXml.Node create_pi (string target, string data);
/**
* Save this {@link GXml.Document} to {@link GXml.Document.file}
*
* If {@link GXml.Document.file} doesn't exists, it creates a new file to save to.
*/
public abstract bool save (GLib.Cancellable? cancellable = null) throws GLib.Error;
/**
* Save this {@link GXml.Document} to given {@link GLib.File}
*/
public abstract bool save_as (GLib.File f, GLib.Cancellable? cancellable = null) throws GLib.Error;
/**
* Creates a new {@link GXml.Document} using default implementation class.
*
* As an interface you can create your own implementation of it, but if
* default one is required use this.
*/
public static GXml.Document new_default ()
{
return new GDocument ();
}
/**
* Creates a new {@link GXml.Document} from a file path using default implementation class.
*
* As an interface you can create your own implementation of it, but if
* default one is required use this.
*/
public static GXml.Document new_default_for_path (string path)
throws GLib.Error
{
File f = File.new_for_path (path);
return GXml.Document.new_default_for_file (f);
}
/**
* Creates a new {@link GXml.Document} from a {@link GLib.File} using default implementation class.
*
* As an interface you can create your own implementation of it, but if
* default one is required use this.
*/
public static GXml.Document new_default_for_file (GLib.File f)
throws GLib.Error
{
var d = new GDocument.from_path (f.get_path ());
if (!f.query_exists ())
throw new DocumentError.INVALID_FILE (_("Invalid file"));
d.file = f;
return d;
}
}
......@@ -206,7 +206,8 @@ public interface GXml.DomDocument : GLib.Object,
}
public errordomain GXml.DomDocumentError {
FILE_NOT_FOUND_ERROR
FILE_NOT_FOUND_ERROR,
INVALID_DOCUMENT_ERROR
}
public interface GXml.DomXMLDocument : GLib.Object, GXml.DomDocument {}
......@@ -219,7 +220,7 @@ public interface GXml.DomImplementation : GLib.Object {
public abstract DomXMLDocument create_document (string? nspace,
string? qualified_name,
DomDocumentType? doctype = null) throws GLib.Error;
public abstract Document create_html_document (string title);
public abstract DomDocument create_html_document (string title);
public virtual bool has_feature() { return true; } // useless; always returns true
}
......
......@@ -24,14 +24,13 @@ using Gee;
using Xml;
/**
* DOM4 class implemeting {@link GXml.Document} and {GXml.DomDocument} interface,
* DOM4 class implemeting {@link GXml.DomDocument} and {GXml.DomDocument} interface,
* powered by libxml-2.0 library.
*
* This class use {@link Xml.TextWriter} to write down XML documents using
* its contained {@link GXml.Node} children or other XML structures.
*/
public class GXml.GDocument : GXml.GNode,
GXml.Document,
GXml.DomParentNode,
GXml.DomNonElementParentNode,
GXml.DomDocument,
......@@ -55,7 +54,7 @@ public class GXml.GDocument : GXml.GNode,
public GDocument.from_file (GLib.File file, int options = 0, Cancellable? cancel = null) throws GLib.Error {
if (!file.query_exists ())
throw new DocumentError.INVALID_DOCUMENT_ERROR (_("File doesn't exist"));
throw new DomDocumentError.INVALID_DOCUMENT_ERROR (_("File doesn't exist"));
var parser = new GParser (this);
parser.cancellable = cancel;
parser.read_stream (file.read ());
......@@ -95,8 +94,8 @@ public class GXml.GDocument : GXml.GNode,
public override Gee.Map<string,GXml.Node> attrs { owned get { return new GHashMapAttr (this, (Xml.Node*) doc) as Gee.Map<string,GXml.Node>; } }
public override Gee.BidirList<GXml.Node> children_nodes { owned get { return new GListChildren (this, (Xml.Node*) doc) as Gee.BidirList<GXml.Node>; } }
public override Gee.List<GXml.Namespace> namespaces { owned get { return new GListNamespaces (this, doc->get_root_element()) as Gee.List<GXml.Namespace>; } }
public override GXml.Document document { get { return this; } }
// GXml.Document
public override GXml.DomDocument document { get { return this; } }
// GXml.DomDocument
public bool indent { get; set; default = false; }
public bool ns_top { get; set; default = false; }
public bool prefix_default_ns { get; set; default = false; }
......@@ -122,30 +121,12 @@ public class GXml.GDocument : GXml.GNode,
return new GElement (this, r);
}
}
public GXml.Node GXml.Document.create_comment (string text)
{
var c = doc->new_comment (text);
return new GComment (this, c);
}
public GXml.Node create_pi (string target, string data)
{
var pi = doc->new_pi (target, data);
return new GProcessingInstruction (this, pi);
}
public GXml.Node GXml.Document.create_element (string name) throws GLib.Error
{
Xml.reset_last_error ();
var el = doc->new_raw_node (null, name, null);
var e = Xml.get_last_error ();
if (e != null) {
var errmsg = "Parser Error for string";
string s = libxml2_error_to_string (e);
if (s != null)
errmsg = ". ";
throw new GXml.Error.PARSER (errmsg);
}
return new GElement (this, el);
}
public GXml.Node create_text (string text)
{
var t = doc->new_text (text);
......@@ -205,7 +186,17 @@ public class GXml.GDocument : GXml.GNode,
public DomElement? document_element { owned get { return (DomElement) root; } }
public DomElement GXml.DomDocument.create_element (string local_name) throws GLib.Error {
return (DomElement) (this as Document).create_element (local_name);
Xml.reset_last_error ();
var el = doc->new_raw_node (null, local_name, null);
var e = Xml.get_last_error ();
if (e != null) {
var errmsg = "Parser Error for string";
string s = libxml2_error_to_string (e);
if (s != null)
errmsg = ". ";
throw new GXml.Error.PARSER (errmsg);
}
return new GElement (this, el);
}
public DomElement GXml.DomDocument.create_element_ns (string? ns, string qualified_name) throws GLib.Error
{
......@@ -219,8 +210,8 @@ public class GXml.GDocument : GXml.GNode,
prefix = s[0];
qname = s[1];
}
var e = (this as GXml.Document).create_element (qname);
e.set_namespace (ns, prefix);
var e = (this as GXml.DomDocument).create_element (qname);
(e as GElement).set_namespace (ns, prefix);
return e as DomElement;
}
......@@ -250,7 +241,8 @@ public class GXml.GDocument : GXml.GNode,
return (DomText) create_text (data);
}
public DomComment GXml.DomDocument.create_comment (string data) throws GLib.Error {
return (DomComment) create_comment (data);
var c = doc->new_comment (data);
return new GComment (this, c);
}
public DomProcessingInstruction create_processing_instruction (string target, string data) throws GLib.Error {
return (DomProcessingInstruction) create_pi (target, data);
......@@ -287,7 +279,7 @@ public class GXml.GDocument : GXml.GNode,
throw new GXml.DomError.NOT_SUPPORTED_ERROR (_("Can't adopt a Document"));
if (this == node.owner_document) return node;
var dst = this.create_element (node.node_name);
GXml.Node.copy (this, dst, (GXml.Node) node, true);
GXml.Node.copy (this, dst as GXml.Node, (GXml.Node) node, true);
if (node.parent_node != null)
node.parent_node.child_nodes.remove_at (node.parent_node.child_nodes.index_of (node));
if (this.document_element == null)
......@@ -338,12 +330,12 @@ public class GXml.GDocument : GXml.GNode,
}
}
public DomElement? first_element_child {
owned get { return (DomElement) (this as Document).children_nodes.first (); }
owned get { return (DomElement) (this as DomDocument).child_nodes.first (); }
}
public DomElement? last_element_child {
owned get { return (DomElement) (this as Document).children_nodes.last (); }
owned get { return (DomElement) (this as DomDocument).child_nodes.last (); }
}
public int child_element_count { get { return children_nodes.size; } }
public int child_element_count { get { return child_nodes.size; } }
public DomNodeList query_selector_all (string selectors) throws GLib.Error {
var cs = new CssSelectorParser ();
......@@ -390,7 +382,7 @@ public class GXml.GImplementation : GLib.Object, GXml.DomImplementation {
DomDocumentType? doctype = null)
throws GLib.Error
{ return new GDocument (); } // FIXME
public Document create_html_document (string title) {
public DomDocument create_html_document (string title) {
return new GHtmlDocument (); // FIXME:
}
}
......
......@@ -142,6 +142,9 @@ public class GXml.GElement : GXml.GNonDocumentChildNode,
}
}
public override string to_string () {
return write_string ();
}
public string write_string (GLib.Cancellable? cancellable = null) {
var buf = new Xml.Buffer ();
buf.node_dump (_node->doc, _node, 1, 0);
return buf.content ().dup ();
......
......@@ -60,7 +60,7 @@ public abstract class GXml.GNode : Object,
public virtual Gee.Map<string,GXml.Node> attrs { owned get { return new GHashMapAttr (_doc, _node) as Gee.Map<string,GXml.Node>; } }
public virtual Gee.BidirList<GXml.Node> children_nodes { owned get { return new GListChildren (_doc, _node) as Gee.BidirList<GXml.Node>; } }
public virtual Gee.List<GXml.Namespace> namespaces { owned get { return new GListNamespaces (_doc, _node) as Gee.List<GXml.Namespace>; } }
public virtual GXml.Document document { get { return _doc; } }
public virtual GXml.DomDocument document { get { return _doc; } }
public virtual GXml.Node parent {
owned get {
GXml.Node nullnode = null;
......@@ -198,7 +198,7 @@ public abstract class GXml.GNode : Object,
if (this is GXml.DomText) return (this as DomText).data;
if (this is GXml.DomProcessingInstruction) return this.@value;
if (this is GXml.DomComment) return this.@value;
if (this is GXml.Document || this is GXml.DomElement) {
if (this is GXml.DomDocument || this is GXml.DomElement) {
message ("Is Element");
foreach (GXml.Node n in children_nodes) {
if (n is GXml.DomText) {
......@@ -210,9 +210,9 @@ public abstract class GXml.GNode : Object,
return t;
}
set {
if (this is GXml.Document || this is GXml.DomElement) {
var t = this.document.create_text (value);
this.document.children_nodes.add (t);
if (this is GXml.DomDocument || this is GXml.DomElement) {
var t = this.document.create_text_node (value);
(this.document as Node).children_nodes.add (t as Node);
}
if (!(this is GXml.DomText || this is GXml.DomComment || this is GXml.DomProcessingInstruction)) return;
this.@value = value;
......
......@@ -54,7 +54,7 @@ private class GXml.GParser : Object, Parser {
var b = new MemoryOutputStream.resizable ();
b.splice (stream, 0);
if (b.data == null)
throw new DocumentError.INVALID_DOCUMENT_ERROR (_("stream doesn't provide data"));
throw new ParserError.INVALID_STREAM_ERROR (_("stream doesn't provide data"));
read_string ((string) b.data);
}
public async void read_stream_async (GLib.InputStream stream) throws GLib.Error
......
......@@ -359,7 +359,7 @@ public class GXml.GomImplementation : GLib.Object, GXml.DomImplementation {
d.append_child (d.create_element_ns (namespace, qualified_name));
return d as DomXMLDocument;
} // FIXME
public Document create_html_document (string title) {
public DomDocument create_html_document (string title) {
return new GHtmlDocument (); // FIXME:
}
}
......
......@@ -58,7 +58,7 @@ public interface GXml.Node : Object
/**
* Node's XML document holding this node.
*/
public abstract GXml.Document document { get; }
public abstract GXml.DomDocument document { get; }
/**
* Node's XML document holding this node.
*/
......@@ -101,7 +101,7 @@ public interface GXml.Node : Object
get_elements_by_name (string name)
{
var list = new GXml.DomElementList ();
if (!(this is GXml.DomElement || this is GXml.Document)) return list;
if (!(this is GXml.DomElement || this is GXml.DomDocument)) return list;
foreach (var child in children_nodes) {
if (child is GXml.DomElement) {
(list as Gee.Collection<GXml.DomElement>).add_all (child.get_elements_by_name (name) as Gee.Collection<GXml.DomElement>);
......@@ -118,7 +118,7 @@ public interface GXml.Node : Object
get_elements_by_name_ns (string name, string? ns)
{
var list = new GXml.DomElementList ();
if (!(this is GXml.DomElement || this is GXml.Document)) return list;
if (!(this is GXml.DomElement || this is GXml.DomDocument)) return list;
foreach (var child in children_nodes) {
if (child is GXml.DomElement) {
(list as Gee.Collection<GXml.DomElement>).add_all (child.get_elements_by_name (name) as Gee.Collection<GXml.DomElement>);
......@@ -156,24 +156,24 @@ public interface GXml.Node : Object
*/
public virtual string ns_uri () { return namespaces.first ().uri; }
/**
* Copy a {@link GXml.Node} relaying on {@link GXml.Document} to other {@link GXml.Node}.
* Copy a {@link GXml.Node} relaying on {@link GXml.DomDocument} to other {@link GXml.Node}.
*
* {@link node} could belongs from different {@link GXml.Document}, while source is a node
* {@link node} could belongs from different {@link GXml.DomDocument}, while source is a node
* belonging to given document.
*
* Only {@link GXml.DomElement} objects are supported. For attributes, use
* {@link GXml.DomElement.set_attr} method, passing source's name and value as arguments.
*
* @param doc a {@link GXml.Document} owning destiny node
* @param doc a {@link GXml.DomDocument} owning destiny node
* @param node a {@link GXml.DomElement} to copy nodes to
* @param source a {@link GXml.DomElement} to copy nodes from, it could be holded by different {@link GXml.Document}
* @param source a {@link GXml.DomElement} to copy nodes from, it could be holded by different {@link GXml.DomDocument}
*/
public static bool copy (GXml.Document doc, GXml.Node node, GXml.Node source, bool deep)
public static bool copy (GXml.DomDocument doc, GXml.Node node, GXml.Node source, bool deep)
{
#if DEBUG
GLib.message ("Copying GXml.Node");
#endif
if (node is GXml.Document) return false;
if (node is GXml.DomDocument) return false;
if (source is GXml.DomElement && node is GXml.DomElement) {
#if DEBUG
GLib.message ("Copying source and destiny nodes are GXml.Elements... copying...");
......@@ -194,8 +194,8 @@ public interface GXml.Node : Object
#endif
try {
var e = doc.create_element (c.name); // TODO: Namespace
node.children_nodes.add (e);
copy (doc, e, c, deep);
node.children_nodes.add (e as GXml.Node);
copy (doc, e as GXml.Node, c, deep);
} catch {}
}
if (c is DomText) {
......@@ -203,8 +203,8 @@ public interface GXml.Node : Object
GLib.warning (_("Text node with NULL string"));
continue;
}
var t = doc.create_text (c.value);
node.children_nodes.add (t);
var t = doc.create_text_node (c.value);
node.children_nodes.add (t as GXml.Node);
#if DEBUG
GLib.message (@"Copying source's Text node '$(source.name)' to destiny node with text: $(c.value) : Size= $(node.children_nodes.size)");
GLib.message (@"Added Text: $(node.children_nodes.get (node.children_nodes.size - 1))");
......
......@@ -38,7 +38,6 @@ configure_file(output : 'config.h',
valasources = files ([
'Collections.vala',
'CssSelectorParser.vala',
'Document.vala',
'DocumentType.vala',
'DomAttr.vala',
'DomCharacter.vala',
......
......@@ -26,18 +26,18 @@ class GElementTest : GXmlTest {
public static void add_tests () {
Test.add_func ("/gxml/gelement/to_string", () =>{
try {
GDocument doc = new GDocument.from_string ("<root />");
DomDocument doc = new GDocument.from_string ("<root />");
var elem = doc.create_element ("country");
var t = doc.create_text ("New Zealand");
var t = doc.create_text_node ("New Zealand");
assert (t != null);
elem.children_nodes.add (t);
Test.message ("Elem1:"+elem.to_string ());
assert (elem.to_string () == "<country>New Zealand</country>");
elem.append_child (t);
message ("Elem1:"+elem.write_string ());
assert (elem.write_string () == "<country>New Zealand</country>");
var elem2 = doc.create_element ("messy");
var t2 = doc.create_text ("&lt;<>&gt;");
elem2.children_nodes.add (t2);
Test.message ("Elem2:"+elem2.to_string ());
assert (elem2.to_string () == "<messy>&amp;lt;&lt;&gt;&amp;gt;</messy>");
var t2 = doc.create_text_node ("&lt;<>&gt;");
elem2.append_child (t2);
message ("Elem2:"+elem2.write_string ());
assert (elem2.write_string () == "<messy>&amp;lt;&lt;&gt;&amp;gt;</messy>");
} catch (GLib.Error e) {
Test.message (e.message);
assert_not_reached ();
......
......@@ -30,7 +30,7 @@ class XPathTest : GXmlTest {
public static void add_tests () {
Test.add_func ("/gxml/gelement/xpath", () => {
try {
Document document = null;
DomDocument document = null;
var rf = GLib.File.new_for_uri ("http://www.w3schools.com/xsl/books.xml");
if (rf.query_exists ()) {
document = new GDocument.from_uri ("http://www.w3schools.com/xsl/books.xml");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment