uk.ac.starlink.hdx
Class AbstractHdxFacade

java.lang.Object
  extended by uk.ac.starlink.hdx.AbstractHdxFacade
All Implemented Interfaces:
Cloneable, HdxFacade
Direct Known Subclasses:
BridgeNDArray.BridgeNDArrayHdxFacade, BridgeNdx.BridgeNdxHdxFacade

public abstract class AbstractHdxFacade
extends Object
implements HdxFacade

Skeletal implementation of the HdxFacade interface.

This includes trivial implementations of addChildBefore, replaceChild and setAttribute, which act as a read-only DOM. It also implements the getSource method in terms of the corresponding getDOM method, which is in turn implemented using synchronizeElement.

XXX getDOM method is almost certainly disappearing! Thus these class comments need a rewrite.

As noted here, this abstract class implements getSource in terms of getDOM, because this is more often useful than the other way around. Recall, however, that the base interface HdxFacade asserts that these two methods are complementary, and an extending class may perfectly reasonably implement the latter in terms of the former.

Thus, the only methods which an implementing class must itself implement are getHdxResourceType(), synchronizeElement() and getObject().

The clone() method which this class implements is a simple one, which will be generally appropriate, since the facade has no instance variables.

Version:
$Id$
Author:
Norman Gray

Constructor Summary
AbstractHdxFacade()
           
 
Method Summary
 boolean addChildBefore(Element parent, Element newChild, Element refChild)
          Adds a new child to an element.
 Object clone()
          Creates and returns a copy of this element
abstract  HdxResourceType getHdxResourceType()
          Obtains the HdxResourceType which this is a facade for.
abstract  Object getObject(Element el)
          Obtains the object which the given Element is a facade for.
 Source getSource(URI base)
          Produces a Source representing this object.
 boolean replaceChild(Element parent, Element newChild, Element oldChild)
          Replaces or removes a child.
 boolean setAttribute(Element el, String name, String value)
          Sets an attribute on an element.
abstract  Object synchronizeElement(Element el, Object memento)
          Adds attributes and children to the given element, to represent the current state of the object as a DOM.
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AbstractHdxFacade

public AbstractHdxFacade()
Method Detail

synchronizeElement

public abstract Object synchronizeElement(Element el,
                                          Object memento)
                                   throws HdxException
Description copied from interface: HdxFacade
Adds attributes and children to the given element, to represent the current state of the object as a DOM. The implementing object should add or update elements and attributes on the given element using the Document obtained by invoking Node.getOwnerDocument() on the element. This Document will in fact be an instance of HdxDocument, which implements the standard Document interface with the addition of HdxDocument.createElement(HdxFacade), which the implementing code is therefore free to use (this is an understatement -- the entire point of this interface is to give an implementing class the opportunity of using this method).

The element will have the type this.getHdxResourceType().xmlname().

This method is called frequently, and the implementing object should therefore take care to do no more work than is necessary. To assist in this, the caller will preserve a memento on behalf of the implementor. This memento is the object returned by this method, which is re-presented when the synchronizeElement method is next called (this is an example of `memento' pattern, although that is more commonly associated with undo actions than the cache-like operation described here). If the implementing object needs to preserve some state, to remind it of its own state when it last synchronised the element, then it should wrap that state in some object or other and return it from this method. This might be as simple as a hash-code.

The first time this method is called, the memento will be null.

The returned memento may be null if, for example, the implementor can extract all its relevant state information from the DOM it receives in the Element; or if the object is immutable, so that the Element attributes and children are correct if they are there at all. This null memento will be duly returned to the implementor on any future invocation. In such a case, the implementor might need to be careful to distinguish this returned null memento from the null memento provided when the method is called the first time.

It is perfectly feasible for the implementor to return itself as the memento.

Specified by:
synchronizeElement in interface HdxFacade
Parameters:
el - an element which is to be made consistent with the current state of the object
memento - either null, if this is the first time this method has been called, or the object which was returned by this method last time it was called (which may be null if that is what the method chose to return)
Returns:
an object or null, which is to be returned to the method next time it is called
Throws:
HdxException - if it is for some reason impossible to update the DOM. The method should regard this as something akin to a `can't happen' error: this thrown exception will be converted to a DOMException if that is reasonable for the caller, but if not, may be converted to a PluginException.

getObject

public abstract Object getObject(Element el)
                          throws HdxException
Description copied from interface: HdxFacade
Obtains the object which the given Element is a facade for. The caller should know what (Java) type of object this will be (that is, Ndx, HdxContainer, or the like), and will therefore be able to cast the result appropriately.

The returned element must match the class appropriate for the Hdx type this element corresponds to. That is the return value obj must be such that the following are true

for any instance facade of this interface, and if el is the Element which this facade is linked to.

Specified by:
getObject in interface HdxFacade
Parameters:
el - an Element which is to be transformed into an object
Returns:
the Java object which this element is a facade for. The object must not be null.
Throws:
HdxException - if the facade does not know how to recover the object type it has been asked for. This will also happen if the element el does not correspond to a known HdxResourceType.

getHdxResourceType

public abstract HdxResourceType getHdxResourceType()
Description copied from interface: HdxFacade
Obtains the HdxResourceType which this is a facade for.

This is not (just) a convenience method. Although the same information is retrievable by calling HdxFacade.getSource(java.net.URI), and calling HdxResourceType.match(Element) on the top element obtained from it,

  1. calling getSource may involve significant processing, and
  2. it is not trivial to retrieve the top element from a Source, since the root of the resulting document (matched by the XPath /) is not guaranteed to be the `top' node of the DOM (see DOMSource.DOMSource(Node))

Specified by:
getHdxResourceType in interface HdxFacade
Returns:
the HdxResourceType this facade represents

getSource

public Source getSource(URI base)
                 throws HdxException
Produces a Source representing this object.

Specified by:
getSource in interface HdxFacade
Parameters:
base - the base URI against which URIs written within the XML are considered relative. If null, all are written absolute.
Returns:
a Source representing the object
Throws:
HdxException - if the Source cannot be generated for some reason
See Also:
SourceReader

addChildBefore

public boolean addChildBefore(Element parent,
                              Element newChild,
                              Element refChild)
Adds a new child to an element. Trivial implementation, which does not allow DOM modification

Specified by:
addChildBefore in interface HdxFacade
Parameters:
parent - the element which is to receive the new child
newChild - The child to be added
refChild - if non-null, the new child is to be inserted before refChild. If refChild is null, the new child is to be appended to the end of the list of children.
Returns:
false, indicating that the DOM cannot be modified

replaceChild

public boolean replaceChild(Element parent,
                            Element newChild,
                            Element oldChild)
Replaces or removes a child. Trivial implementation, which does not allow DOM modification

Specified by:
replaceChild in interface HdxFacade
Parameters:
parent - the element which is to have its children changed
newChild - the replacement element. If this is null, then oldChild is deleted.
oldChild - the element which is to be replaced.
Returns:
false, indicating that the DOM cannot be modified

setAttribute

public boolean setAttribute(Element el,
                            String name,
                            String value)
Sets an attribute on an element. Trivial implementation, which does not allow DOM modification

Specified by:
setAttribute in interface HdxFacade
Parameters:
el - the element which is to have the attribute set
name - the attribute which is to be set
value - the new value of the attribute. If the value is null, the attribute is removed. Setting the value to the empty string is allowed, and is not the same as setting it to null.
Returns:
false, indicating that the DOM cannot be modified

clone

public Object clone()
Creates and returns a copy of this element

Specified by:
clone in interface HdxFacade
Overrides:
clone in class Object
Returns:
a copy of this element


Copyright © 2015 Central Laboratory of the Research Councils. All Rights Reserved.