DOOM's OMFactory implementation should be stateless
---------------------------------------------------

                 Key: AXIOM-412
                 URL: https://issues.apache.org/jira/browse/AXIOM-412
             Project: Axiom
          Issue Type: Improvement
          Components: DOOM
    Affects Versions: 1.2.12
            Reporter: Andreas Veithen


There is a sort of "impedance mismatch" between the Axiom API and DOM because
* the Axiom API is designed such that nodes are created using a factory 
(OMFactory or SOAPFactory) that is expected to be a singleton and stateless;
* in the DOM API, the Document instance plays the role of node factory, and 
each node (explicitly or implicitly) keeps a reference to the Document instance 
from which it was created (the "owner document").

The approach currently used by DOOM to solve that issue is to have a stateful 
OMFactory implementation which has a reference to a (OM)Document instance. That 
(OM)Document instance is then used as the owner document for nodes created 
using the Axiom API [Well, actually it is a bit more complicated and obscure 
than that...]. For this to work, the application code is required to request an 
OMFactory once and only once for each document created. This is one of the 
reasons why in general code written for the standard Axiom implementation 
(LLOM) doesn't work well when switching to DOOM. In addition, although the 
implementation of that design is relatively simple, it makes DOOM quite obscure 
from the user's perspective.

There is an alternative approach to solve the Axiom/DOM impedance mismatch 
which doesn't require a stateful OMFactory implementation. It is based on the 
following set of rules that determine how the DOM owner document is handled 
when nodes are created and manipulated using the Axiom API:

(1) Nodes created using the Axiom API and for which a parent node is specified 
will have as their owner document the owner document of the parent. This is 
simply a consequence of the fact that DOM is designed such that two nodes that 
are part of the same tree must have the same owner document.

(2) Nodes created using the Axiom API and for which no parent node is specified 
will get a new owner document. That is unavoidable if one wants a 
stateless/singleton OMFactory.

(3) When the Axiom API is used to add a node A as a child of another node B, 
then the owner document of B becomes the new owner document of A and all its 
descendants. In DOM parlance, this means that node A is automatically adopted 
by the owner document of B. This rule ensures that any operation that is valid 
with the LLOM implementation will also work with DOOM (without triggering a 
WRONG_DOCUMENT_ERR exception and without violating the rule that all nodes in a 
tree must have the same owner document).

(4) When a node is detached from its parent using the Axiom API (i.e. using 
OMNode#detach), it will get a new owner document. This rule is not strictly 
required to make the approach work; it merely exists for consistency because 
together with the other rules it implies that every tree has a distinct owner 
document (as long as only the Axiom API is used to manipulate the nodes).

If implemented literally, these rules would obviously have a performance impact 
because (depending on the usage pattern) a large number of temporary Document 
instances may be needed. In addition, rules (3) and (4) require an efficient 
way to change the owner document of an entire tree (more efficient than to 
traverse the entire tree). Therefore these rules would be supplemented by the 
following design choices:

(5) Owner documents are created lazily, namely when explicitly requested using 
DOM's Node#getOwnerDocument() API (or when DOOM needs to access data that it 
choses to store in the owner document).

(6) Only the root node of a tree stores a reference to the owner document. As 
noted above, all nodes in a tree must have the same owner document. Therefore 
it is not necessary for a node to have references to both its parent and its 
owner document. Instead, a node should have a single attribute that stores the 
reference either to the parent (if it has a parent) or to the owner document 
(if it has no parent), as well as a flag that indicates the meaning of the 
reference (this is important if the reference points to a Document instance, 
which would otherwise be ambiguous). With this design, changing the owner 
document of a tree is O(1) instead of O(N) where N is the number of nodes in 
the tree. However, requesting the owner document of a node is O(M) instead of 
O(1) with M the depth of the tree. This is a good tradeoff considering that
* Axiom methods never need to check the owner document;
* DOM methods need to check the owner document more often (basically for every 
node addition) than the owner document of a tree is changed, but M << N.

It should be noted that switching from the current design to the new design 
proposed here is not entirely transparent for application code. It implies a 
change in behavior if nodes are first created and manipulated using the Axiom 
API and then later passed to DOM APIs such as appendChild. In that situation it 
is likely that with the new design, the nodes have different owner documents, 
while this was not the case with the old design (because the same OMFactory 
instance was used). Such application code needs to be changed to use 
Document#adoptNode where appropriate. However, it is expected that in the Axis2 
universe, the impact will be limited to a few places in the SAAJ implementation 
as well as Rampart. There are quite some examples where these two components 
depended on incorrect behavior in DOOM's DOM implementation or other 
implementation details, so that in general they can only be expected to work 
with the Axiom version for which they were built. One may therefore assume that 
the impact is acceptable.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@ws.apache.org
For additional commands, e-mail: dev-h...@ws.apache.org

Reply via email to