[jdom-interest] Code submision: JDOM2 the dual tree implement ation...

James Strachan james at metastuff.com
Wed Nov 29 02:33:11 PST 2000


----- Original Message -----
From: "Jason Hunter" <jhunter at collab.net>


> James Strachan wrote:
> > I'd say that validation is a complex area. Some may want to
> > validate as they build; never allowing an incorrect data structure
> > to ever be built.
>
> That'd be pretty hard to enforce.  To build a correct document structure
> you have to build the document in pieces, and those pieces won't be
> valid.  Consider adding elements to an element that requires three
> children.  You're not valid until you've added the third.  Do you want
> it to raise an exception after you've added just one?  Of course not.
> Do you want to require all three elts be added at once?  Of course not
> -- to do so would make JDOM extremely unfriendly to use.

Yes - some validation can only occur once the tree is built. I'm not sure
how useful 'incremental' validation is. Should we just focus on validation
of whole documents for now? Something along the lines...

public interface Validator {
    public void validate(Document document) throws InvalidDocumentException;
}

> > Validator interface or abstract base class which is a property
> > of Document (for use in doubly linked trees)
>
> If validation is a property of Document, then elements are tied to
> document (bad)

They already are. Doubly linked Element has getDocument() and getParent()
methods so an Element is currently tied to its parent elements and the
document.

> or elements have to be imported to a document (bad)

They already do don't they? Right now you have to deep clone to get an
Element from one document to another.

> or
> element have to be background-checked when added to a document (bad for
> efficiency, plus impossible with a singly linked tree).

Agreed. Let's quitely ignore incremental validation for now shall we? ;-)

> > 1) singly linked trees - have no reference to the owning document
>
> Thinking more about singly linked trees, with such a design I think that
> while it's possible to make the attribs/pis/comments/etc immutable, it's
> not possible to make Element immutable.  Assuming Element doesn't know
> about its parent (because it's singly linked) that means you'll open up
> the possibility of having the same Element on the same tree at two
> different points.

This is a possibility. Though you can mix and match - you could use singly
linked immutable leaves with mutable doubly linked Element you wish.

> That's extremely undesirable, because it allows the
> document to have loops and that makes output, validation, and any other
> action on the document much more difficult.

I think we should leave this configuraiton possible as its another possible
performance optimisation. For example, if the same Element (branch) is
required to exist in several documents or at several points in a document,
it would be nice to be able to share the same instance. Though I agree, it
would be nice to make it immutable. How about we use a similar design
pattern to the one in the Collections API to solve exactly this problem -
the Collections.unmodifiableCollection() method

http://java.sun.com/j2se/1.3/docs/api/java/util/Collections.html#unmodifiabl
eCollection(java.util.Collection)

So we could have an ImmutableElement implementation which proxies the
mutable Element implementation and throws an UnsupportedOperationException
on all methods which attempt to modify its state. So in your code you could
do something like

public class Foo {
    private Element blueBallImage = null;

    public Element getBulletImage() {
        if ( blueBallImage == null ) {
            Element image = new Element( "img" );    // singly linked
element
            image.setAttributeValue( "href",
"http://www.somewhere.com/images/blueball.gif" );
            ...
            image = blueBallImage.createUnmodifiable();
        }
        return image;
    }

So we can have a mutable Element but share it in JDOM trees in an immutable
way.
In JDOM we can have cake and eat it too ;-)

I'm now starting to think that, although it adds some complexity, an Element
interface (or abstract base class with no instance data) might be a good
idea. Then we could implement a proxy Element...

public abstract class ProxyElement implements Element {
    private Element proxy;

    // delegate all methods to the proxy...
    public List getChildren() {
        proxy.getChildren();
    }
}

Then we can have...

public class ImmutableElement extends ElementProxy {
    ...
    public addAttribute(Attribute attribute) {
        throw new UnsupportedOperationException
    }
}

and maybe

public class DoublyLinkedImmutableElement extends ImmutableElement {
    private Element parent;

    public Element getParent() {
        return parent;
    }

    protected void setParent(Element parent) {
        this.parent = parent;
    }
    ...
    public addAttribute(Attribute attribute) {
        throw new UnsupportedOperationException( "This Element cannot be
modified" );
    }
}

The only downside of the interace / abstract base class route is that if
people want to do their own custom building, they need to use specific class
names....

    Element element1 = new SingleElement("foo");
    Element element2 = new DoubleElement("bar");

or to use a tree builder (a kind of composite factory object) ...

    TreeBuilder treeBuilder = new TreeBuilder(); // or new
SinglelTreeBuilder() for singly linked trees
    Element element1 = builder.createElement( "foo" );
    Element element2 = builder.createElement( "bar" );

I think the more we discuss issues of immutability, instance sharing, singly
/ doubly linked trees and possibly efficient caching of XPath / getChild() /
getAttribute() methods I'm increasingly coming to the conclusion that we
need good interface / abstract base classes for Element / Attribute et al
and a library of various implementations for different use cases with a
couple of tree builders. I think the Java 2 Collections are an excellent
example of how to leave things flexible yet easy to extend and still simple
to use.

> I think elements need to be mutable and mutable elements need to keep
> track of parentage.  So a singly linked tree would be only somewhat
> singly linked.

Not necessarily but in most cases yes.

<James/>


James Strachan
=============
email: james at metastuff.com
web: http://www.metastuff.com



If you are not the addressee of this confidential e-mail and any
attachments, please delete it and inform the sender; unauthorised
redistribution or publication is prohibited. Views expressed are those of
the author and do not necessarily represent those of Citria Limited.



More information about the jdom-interest mailing list