sk.baka.ikslibs.ids
Class IDManager

java.lang.Object
  extended by sk.baka.ikslibs.ids.IDManager
All Implemented Interfaces:
EventListener, INodeObserver

public final class IDManager
extends Object
implements EventListener, INodeObserver

Provides support for mapping between ID and nodes. The class relies mainly on the value of the ID attribute (its name is specified in the constructor), its internal list is used only for fast execution of getNode. Non-element nodes, such as text, cdata etc, are addressed by their parent element's id, thus they don't have ID themselves.

Every element has an ID: an integer number. Every non-element non-atribute node has two-part ID, split by a ;: first part is ID of their parent element, and second part is their position in this element (the numbering starts from 0). Warning: this numbering is consistent with the 'normalized document' (the document that is source for the transformation process) rather than the original document. Use the getID() function rather than computing the ID yourself. Every attribute has an ID split by @: first part is the ID of their owner element and second part is the prefixed name of the attribute.

If the node is a root node (the parent is the document) and it is not an element then the ID is in format ";[number]" - it does not have an ID of parent element.

Prior to each transformation the document is normalized: entity references are resolved and all adjacent text and cdata nodes are merged into one text node. Hence one text node can be backwards-identified as a set of 'adjacent' nodes (adjacent when the entity references are resolved). No ID may reference an entity reference node.

FOP requires that each ID is unique. However we may want to identify same element from different places. We must ensure that two different ID strings denote the same element. Hence, we define the ID structure as follows:

[parent-id]{; or @} position or attribute-name [,any_string]

where [] denotes the optional part and {} represents choice between two or more strings. No whitespaces are allowed. Two IDs are equal if and only if their parent-id are equal or both are missing and position or attribute-name are equal.

To automatically manage nodes simply register the manager as a listener to the container node with EventTypesEnum.MNodeInserted and EventTypesEnum.MNodeRemoved event types.

Author:
Martin Vysny

Field Summary
 QName idAttribute
          QNames of ID attributes.
 
Constructor Summary
IDManager(Node rootContainer, QName idAttribute, FailEnum fail)
          Constructs an IDManager instance bound to specified document.
 
Method Summary
 String addElement(Element element, FailEnum fail)
          Links given element with unique ID.
 void addTree(Node node, FailEnum fail)
          Adds all element nodes in the descendant-or-self axis of given node to the id list.
 boolean areIdsEqual(String id1, String id2)
          Tests if the two IDs denote the same nodeset.
static boolean canHaveId(Node node)
          Checks if the node can have an id.
static boolean canHaveId(short nodeType)
          Checks if the node can have an id.
 void checkWellFormedness(String id)
          If given ID is not well formed the DOMException is thrown.
 int compareIds(String id1, String id2)
          Compares two IDs by their document order and returns result similar to Comparable.compareTo(Object) method.
 boolean containsElements(String id)
          Checks, whether given element contains some elements also, or it contains text/comments/pi only.
 Attr getAttrNode(String id)
          Gets attribute node, identified by ID.
 Comment getCommentNode(String id)
          Gets comment node, identified by ID.
 String getContainerText(String id)
          Computes text value of element or entity reference by concatenating all textual values of descendant text/cdata nodes.
 String getData(String id)
          Returns data, associated with given node.
 Element getElement(String id)
          Returns regular element, identified by given id.
static Node getFirstDescendantOrSelfIdentifiableNode(Node node)
          Returns first identifiable node encountered on descendant-or-self axis of given node.
 String getID(Node node)
          Gets ID value from the node.
 String getIDNull(Node node)
          Gets ID value from the node.
static String getIDNull(Node node, QName idAttr)
          Gets ID value from the node.
 NodeListID getNode(String id)
          Gets node identified by ID.
 NodeListID getNodeNull(String id)
          Gets node identified by ID.
 short getNodeType(String id)
          Returns the type of node, denoted by given ID.
 ProcessingInstruction getPINode(String id)
          Gets processing instruction node, identified by ID.
 NodeListID getTextNode(String id)
          Gets text (or CData) nodes, containing text identified by ID.
 void handleEvent(Event evt)
           
 boolean hasID(Element element)
          Examines if the node has the ID attribute.
 boolean inEntity(String id)
          Checks if node with given ID is in an entity, therefore unmodifiable.
 boolean isIdAttribute(Node node)
          Checks if given node is the ID attribute.
 boolean isValid(String id)
          Checks whether given ID is valid.
static boolean isWellFormed(String id)
          Checks whether given ID is well-formed (but the presence of the node with this id in the document is not checked).
 void observe(Node node)
          Starts to observe given node and its descendants.
 void remove(Element element)
          Removes element from list.
 void removeTree(Node node)
          Removes all element nodes in the descendant-or-self axis of given node from the id list.
 void sortByDocumentOrder(List<String> list)
          Sorts list of IDs: node denoted by first ID precedes node denoted by second ID etc.
 void stopObservation(Node node)
           Finishes observation of given node and its descendants.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

idAttribute

public final QName idAttribute
QNames of ID attributes.

Constructor Detail

IDManager

public IDManager(Node rootContainer,
                 QName idAttribute,
                 FailEnum fail)
Constructs an IDManager instance bound to specified document. Instance created with reference to document will not accept nodes from another document. Upon creating, IDs for all elements are generated, even for elements contained in the EntityReference nodes.

Parameters:
rootContainer - the root node. All descendant elements including this node will receive an ID. Must not be null. Must be an ID-level container node.
fail - what to do when the element already contains an ID.
idAttribute - the qname of the ID attribute.
Throws:
DOMException - if the function fails to set an ID to some element.
Method Detail

addElement

public String addElement(Element element,
                         FailEnum fail)
                  throws DOMException
Links given element with unique ID. The node will be modified by inserting the idAttribute. If the node already has an id then its present id is returned instead.

Parameters:
element - Element, that has been added to the document.
fail - what to do when the element already contains an ID.
Returns:
ID-value that has been assigned to node.
Throws:
DOMException - if the function fails to set an ID to the element.

addTree

public void addTree(Node node,
                    FailEnum fail)
             throws DOMException
Adds all element nodes in the descendant-or-self axis of given node to the id list. Function returns id of given node. Function shall fail only if the argument is null.

Parameters:
node - the root of the tree to register.
fail - what to do when the ID already exists.
Throws:
DOMException - if the function fails to set an ID to some element.

remove

public void remove(Element element)
Removes element from list. If element does not have an id then nothing happens.

Parameters:
element - element, which is being removed from the manager.

removeTree

public void removeTree(Node node)
Removes all element nodes in the descendant-or-self axis of given node from the id list. Function shall fail only if the argument is null.

Parameters:
node - the root of the tree to remove from registry.

canHaveId

public static boolean canHaveId(Node node)
Checks if the node can have an id. Only elements, attributes, text, cdata, processing instruction and comments can have an id.

Parameters:
node - the node to check
Returns:
true if the node can have id, false otherwise.

canHaveId

public static boolean canHaveId(short nodeType)
Checks if the node can have an id. Only elements, attributes, text, cdata, processing instruction and comments can have an id.

Parameters:
nodeType - the node type to check
Returns:
true if the node can have id, false otherwise.

isWellFormed

public static boolean isWellFormed(String id)
Checks whether given ID is well-formed (but the presence of the node with this id in the document is not checked).

Parameters:
id - the ID to check.
Returns:
true if the ID is well-formed, false otherwise.

isValid

public boolean isValid(String id)
Checks whether given ID is valid. It must be well-formed and it must be present in the document.

Parameters:
id - the ID to check.
Returns:
true if id is valid, false otherwise.

inEntity

public boolean inEntity(String id)
Checks if node with given ID is in an entity, therefore unmodifiable.

Parameters:
id - ID of the node
Returns:
true if the node is not modifiable, false if node is not in an entity (in case of element, PI, comment, attribute) or some text parts may be modifiable (in case of textual node).
Throws:
DOMException - if id doesn't exist.

getNodeType

public short getNodeType(String id)
Returns the type of node, denoted by given ID. If the ID spans over multiple text/cdata nodes then the type of the first node is returned.

Parameters:
id - id of the node.
Returns:
one of the Node type constants.
Throws:
DOMException - if given ID does not exist.

getIDNull

public String getIDNull(Node node)
Gets ID value from the node. If the specified node has no ID, function returns null. This method works also with nodes, which doesn't belong to our document. If the ID spans over multiple nodes then given node is amongst these nodes.

Parameters:
node - Element, whose ID has to be returned.
Returns:
Id of the node, or null if the node doesn't have an ID. It will not have the trailing third (,) part.

getIDNull

public static String getIDNull(Node node,
                               QName idAttr)
Gets ID value from the node. If the specified node has no ID, function returns null. This method works also with nodes, which doesn't belong to our document. If the ID spans over multiple nodes then given node is amongst these nodes.

Parameters:
node - Element, whose ID has to be returned.
idAttr - the qname of the attribute that holds the ID.
Returns:
Id of the node, or null if the node doesn't have an ID. It will not have the trailing third (,) part.

getID

public String getID(Node node)
Gets ID value from the node. If the specified node has no ID, function fails with IllegalStateException. It works with all types of nodes, even not from our document.

Parameters:
node - node, whose ID has to be returned.
Returns:
Id of the node.

areIdsEqual

public boolean areIdsEqual(String id1,
                           String id2)
Tests if the two IDs denote the same nodeset.

Parameters:
id1 - first ID
id2 - second ID
Returns:
true if the IDs are same.

checkWellFormedness

public void checkWellFormedness(String id)
If given ID is not well formed the DOMException is thrown.

Parameters:
id - ID to check.

getNode

public NodeListID getNode(String id)
                   throws DOMException
Gets node identified by ID.

Parameters:
id - id of the desired node.
Returns:
nodelist, never null nor empty.
Throws:
DOMException - if id doesn't exist.

getNodeNull

public NodeListID getNodeNull(String id)
Gets node identified by ID.

Parameters:
id - id of the desired node.
Returns:
non-null non-empty list of node, or null if the id is not valid.

hasID

public boolean hasID(Element element)
Examines if the node has the ID attribute.

Parameters:
element - the element to be examined.
Returns:
true if node has an ID.

isIdAttribute

public boolean isIdAttribute(Node node)
Checks if given node is the ID attribute.

Parameters:
node - node to check.
Returns:
true if node is the id attribute, false otherwise.

compareIds

public int compareIds(String id1,
                      String id2)
               throws DOMException
Compares two IDs by their document order and returns result similar to Comparable.compareTo(Object) method.

Parameters:
id1 - first ID
id2 - second ID
Returns:
-1 if node denoted by first id precedes node denoted by second id (as stated by the document ordering), 0 if two ids are equal as determined by the areIdsEqual(String, String) method, or 1 if node denoted by first id follows node denoted by second id.
Throws:
DOMException - if at least one id doesn't exist.

sortByDocumentOrder

public void sortByDocumentOrder(List<String> list)
Sorts list of IDs: node denoted by first ID precedes node denoted by second ID etc.

Parameters:
list - list to sort.

getFirstDescendantOrSelfIdentifiableNode

public static Node getFirstDescendantOrSelfIdentifiableNode(Node node)
Returns first identifiable node encountered on descendant-or-self axis of given node. It may return given node itself. Checks all descendants of given node.

Parameters:
node - the node to check.
Returns:
first descendant-or-self of node in the document order. If node itself is identifiable then it is returned.

getElement

public Element getElement(String id)
                   throws DOMException
Returns regular element, identified by given id.

Parameters:
id - id of node.
Returns:
Element, denoted by given id.
Throws:
DOMException - if id doesn't exist or it doesn't denote regular element.

getTextNode

public NodeListID getTextNode(String id)
                       throws DOMException
Gets text (or CData) nodes, containing text identified by ID.

Parameters:
id - id of the desired node.
Returns:
text nodes denoted by given id.
Throws:
DOMException - if id doesn't exist or it doesn't denote text or CData node.

getPINode

public ProcessingInstruction getPINode(String id)
                                throws DOMException
Gets processing instruction node, identified by ID.

Parameters:
id - id of the desired node.
Returns:
the node
Throws:
DOMException - if id doesn't exist or it doesn't denote ProcessingInstruction node.

getCommentNode

public Comment getCommentNode(String id)
                       throws DOMException
Gets comment node, identified by ID.

Parameters:
id - id of the desired node.
Returns:
the node
Throws:
DOMException - if id doesn't exist or it doesn't denote Comment node.

getAttrNode

public Attr getAttrNode(String id)
                 throws DOMException
Gets attribute node, identified by ID.

Parameters:
id - id of the desired node.
Returns:
the node
Throws:
DOMException - if id doesn't exist or it doesn't denote Attr node.

getData

public String getData(String id)
               throws DOMException
Returns data, associated with given node. Returns a text value.

Parameters:
id - id of node.
Returns:
character data, that the node contains. Never null.
Throws:
DOMException - if node doesn't exist or it denotes an element.

containsElements

public boolean containsElements(String id)
                         throws DOMException
Checks, whether given element contains some elements also, or it contains text/comments/pi only.

Parameters:
id - id of element.
Returns:
true if element contains at least one regular element, false otherwise.
Throws:
DOMException - if id doesn't exist or it doesn't denote regular element.

getContainerText

public String getContainerText(String id)
                        throws DOMException
Computes text value of element or entity reference by concatenating all textual values of descendant text/cdata nodes.

Parameters:
id - id of element.
Returns:
textual value of element, never null.
Throws:
DOMException - if id doesn't exist or it doesn't denote regular element.

handleEvent

public void handleEvent(Event evt)
Specified by:
handleEvent in interface EventListener

observe

public void observe(Node node)
Description copied from interface: INodeObserver
Starts to observe given node and its descendants.

Specified by:
observe in interface INodeObserver
Parameters:
node - node to observe

stopObservation

public void stopObservation(Node node)
Description copied from interface: INodeObserver

Finishes observation of given node and its descendants.

Warning: the method simply deregisters from given node. It does NOT deregister from any descendants of given node hence the observation of some descendants may continue.

Specified by:
stopObservation in interface INodeObserver
Parameters:
node - stops observing this node.


Copyright © 2006 Martin Vysny - baka. All Rights Reserved.