Difference between revisions of "The Tree Library"

From Gcube Wiki
Jump to: navigation, search
(Building Trees)
Line 73: Line 73:
  
 
Tree tree = new Tree("rootId");
 
Tree tree = new Tree("rootId");
tree.setAttribute(new QName("x"),"1");
+
tree.setAttribute(new QName("x"),"...");
tree.setAttribute(new QName("http://foo.org","y"), new Date().toString());
+
tree.setAttribute(new QName("http://foo.org","y"), "...");
 
tree.setSourceID("sourceId");
 
tree.setSourceID("sourceId");
 
Leaf leaf1 = new Leaf("id1");
 
Leaf leaf1 = new Leaf("id1");
leaf1.value("1");  
+
leaf1.value("...");  
Leaf leaf2 = new Leaf("id2");
+
Leaf leaf2 = new Leaf("...");
 
leaf2.value("true");
 
leaf2.value("true");
 
Edge e1 = new Edge(new QName("a"),leaf1);  //unqualified
 
Edge e1 = new Edge(new QName("a"),leaf1);  //unqualified
Line 89: Line 89:
 
<source lang="java5">
 
<source lang="java5">
 
Tree tree = new Tree("rootId",
 
Tree tree = new Tree("rootId",
new Edge("a", new Leaf("id1","2")),
+
new Edge("a", new Leaf("id1","...")),
new Edge("http://bar.org","b", new Leaf("id2","true")));
+
new Edge("http://bar.org","b", new Leaf("id2","...")));
 
   
 
   
tree.setAttribute("x","1");
+
tree.setAttribute("x","...");
tree.setAttribute("http://foo.org","y", new Date().toString());
+
tree.setAttribute("http://foo.org","y","...");
 
tree.setSourceID("sourceId");
 
tree.setSourceID("sourceId");
  
 
</source>
 
</source>
  
We find details on individual constructor and mutators in the in Javadoc documentation.
+
We find details on individual constructors and mutators in the in Javadoc documentation.
  
Alternatively, we can adopt a more functional style importing the static builder methods of the <code>Nodes</code> class and composing them in tree expressions, e.g:
+
Alternatively, we can adopt a more functional style, importing the static builder methods of the <code>Nodes</code> class and composing them in inlined tree expressions, e.g:
  
 
<source lang="java5">
 
<source lang="java5">
Line 107: Line 107:
 
 
 
Tree tree = attr(t("sourceId","rootId",
 
Tree tree = attr(t("sourceId","rootId",
e("a",1),  
+
e("a","..."),  
e("http://bar.org","b",true)),
+
e("http://bar.org","b","...")),
                   a("x",1),a("http://foo.org","y",new Date()));
+
                   a("x",1),a("http://foo.org","y","..."));
  
 
</source>
 
</source>
  
The functional style is far less verbose, and is particularly suited for testing. <code>t()</code>, <code>attr()</code>, <code>e()</code>, and <code>a()</code> are examples of root, attribute, and edge builders, respectively. We use them to inline tree expressions, i.e. avoid the <code>new</code> operator for <code>Node</code>s, <code>Edge</code>s and <code>QName</code>s. They also perform object-to-string conversion (cf. <code>int</code>, <code>boolean</code>, and <code>Date</code> above).  
+
The functional style is far less verbose, and is particularly suited for testing. <code>t()</code>, <code>attr()</code>, <code>e()</code>, and <code>a()</code> are examples of root, attribute, and edge builders, respectively. We use them to inline tree expressions, i.e. avoid the <code>new</code> operator for <code>Node</code>s, <code>Edge</code>s and <code>QName</code>s. They also perform object-to-string conversion.  
  
We find details on all the available builders in the Javadoc documentation of the Nodes class. See also these additional examples:
+
We show some additional examples below, and details on all the available builders in the Javadoc documentation of the <code>Nodes</code> class:
  
 
<source lang="java5">
 
<source lang="java5">
  
// n() is an inner node generator
+
//child-less root: t() is a tree builder
Tree tree = t("rootId",
+
Tree tree = t();
                    e("a", n("2",           
+
                              e("b",3))));
+
+
  
tree = t(   
+
//with identifier
e("a", attr(
+
tree = t("id1");
                            n("2",
+
 
                                e("b",l("3",0)),            //l()= explicit leaf generator for identity assignment
+
//with identifier and provenance
                                e("a",l("4",0))),
+
tree = t("source","id1");
                          a("foo","0"))));
+
 
+
//with a simple child: e() is an edge builder
+
tree = t(e("a",1));
tree = attr(t("1",
+
 
e("a",l("2",5)),
+
//with a second, identified simple child: l() is a leaf builder
e("b",attr(
+
tree = t(e("a",1),e("b",l("id2","foo")));
                            n("3",e("c",4)),
+
 
  a("foo",0))),
+
//with a complex child: n() is an inner node builder
e("c",5)),
+
tree = t(e("a",n(e("b",1))));
      a("x",0));
+
 
+
//with attributes: a() is an attribute builder, attr() is attribute-decorator for nodes
+
tree = attr(t(....),a("a1","3"),a("a2","foo"));
tree = attr(t("1",
+
 
              e("a", n("2",
+
//with an attributed child
              e("b",n("$2")))),
+
tree = t(e("a", attr(l("foo"),a("b1","3"),a("b2","bar"))));
                  e("a",n("a1",
+
                              e("c",n(
+
                                          e("d","..."),
+
                                          e("d",attr(                                      //l()= explicit leaf generator for attribute assignments
+
                                                        l("<xml>..</xml>"),
+
                                                    a("w",".."))))))),
+
              e("b",attr(
+
                            n("1:/2"),
+
                      a("w","...")))),
+
        a("x","http://org.acme:8080"),a("y","<a>...</a>"));
+
  
 
</source>
 
</source>

Revision as of 15:44, 18 December 2012

The Tree Library implements a model of edge-labelled trees, and related tools. It is a shared dependency for the components of a subsystem that provides data access under this model, including the Tree Manager services, the Tree Manager Framework, the Tree Manager Library and its clients.

The library is available in our Maven repositories with the following coordinates:

<groupId>org.gcube.data.access</groupId>
<artifactId>trees</artifactId>
<version>...</version>

Source code and documentation are also available in the repositories as secondary artefacts with classifiers sources and javadoc, respectively:

<groupId>org.gcube.data.access</groupId>
<artifactId>trees</artifactId>
<classifier>sources</code>
<version>...</version>
 
<groupId>org.gcube.data.access</groupId>
<artifactId>trees</artifactId>
<classifier>javadoc</code>
<version>...</version>


Trees

The library implements a model of node-attributed, leaf-valued , edge-labelled, and directed trees. In particular:

  • nodes may have an identifier and a number of uniquely named attributes;
  • edges have a label;
  • leaves may have a value;
  • roots may identify the source of origin.

Moreover:

  • identifiers, attributes, and leaves have text values;
  • attribute names and labels may be namespaced.


Tree-model.png


The model is implemented in code by the following classes:

Tree-class-hierarchy.png

Nodes are either InnerNodes or Leafs. InnerNodes have zero or more Edges, each of which has a label and target Node. Attributes and identifiers are common to all Nodes, while only Leafs have values. Trees are InnerNodes with source identifiers, and serve as tree roots.

Instances of model classes are mutable, in that we can:

  • add and remove attributes and edges;
  • change the value of attributes and leaves;
  • change source identifiers;

Note however that node identifiers and edge labels are assigned at creation time and cannot be changed thereafter.

We can also:

  • compare instances for equivalence (instances override equals());
  • use them as keys in hash-based structures (instances override hashcode());
  • publish their state for debugging purposes (instances override toString()).

Building Trees

We can construct trees in a standard object-oriented fashion, using any of the overloaded constructors common to all model classes (including copy constructors), e.g:

Tree tree = new Tree("rootId");
tree.setAttribute(new QName("x"),"...");
tree.setAttribute(new QName("http://foo.org","y"), "...");
tree.setSourceID("sourceId");
Leaf leaf1 = new Leaf("id1");
leaf1.value("..."); 
Leaf leaf2 = new Leaf("...");
leaf2.value("true");
Edge e1 = new Edge(new QName("a"),leaf1);  //unqualified
Edge e2 = new Edge(new QName("http://bar.org","b"),leaf2);
tree.add(e1,e2)

Overloaded constructors simplify object creation, e.g.:

Tree tree = new Tree("rootId",
		new Edge("a", new Leaf("id1","...")),
		new Edge("http://bar.org","b", new Leaf("id2","...")));
 
tree.setAttribute("x","...");
tree.setAttribute("http://foo.org","y","...");
tree.setSourceID("sourceId");

We find details on individual constructors and mutators in the in Javadoc documentation.

Alternatively, we can adopt a more functional style, importing the static builder methods of the Nodes class and composing them in inlined tree expressions, e.g:

import static org.gcube.data.trees.data.Nodes.*;
…
Tree tree = attr(t("sourceId","rootId",
			e("a","..."), 
			e("http://bar.org","b","...")),
                   a("x",1),a("http://foo.org","y","..."));

The functional style is far less verbose, and is particularly suited for testing. t(), attr(), e(), and a() are examples of root, attribute, and edge builders, respectively. We use them to inline tree expressions, i.e. avoid the new operator for Nodes, Edges and QNames. They also perform object-to-string conversion.

We show some additional examples below, and details on all the available builders in the Javadoc documentation of the Nodes class:

//child-less root: t() is a tree builder
Tree tree = t();
 
//with identifier
tree = t("id1");
 
//with identifier and provenance
tree = t("source","id1");
 
//with a simple child: e() is an edge builder
tree = t(e("a",1));
 
//with a second, identified simple child: l() is a leaf builder
tree = t(e("a",1),e("b",l("id2","foo")));
 
//with a complex child: n() is an inner node builder
tree = t(e("a",n(e("b",1))));
 
//with attributes: a() is an attribute builder, attr() is attribute-decorator for nodes
tree = attr(t(....),a("a1","3"),a("a2","foo"));
 
//with an attributed child
tree = t(e("a", attr(l("foo"),a("b1","3"),a("b2","bar"))));

We can of course mix object-oriented and functional style.

Traversing Trees

XML Bindings

Patterns