com.adobe.xfa.dom.DOM Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
/*
* ADOBE CONFIDENTIAL
*
* Copyright 2009 Adobe Systems Incorporated All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual and
* technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or copyright
* law. Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe Systems Incorporated.
*/
package com.adobe.xfa.dom;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.adobe.xfa.Element.DualDomNode;
/**
* W3C DOM wrapper access.
*
* The W3C DOM wrapper allows part or all of an XFA DOM (certain
* com.adobe.xfa classes) to be wrapped in a standard W3C DOM interface.
* This is handy if some portion of an XFA DOM needs to be passed to a
* package that expects W3C DOM objects.
*
*
* The general mode of operation is to create a wrapper node or
* document, pass it to the package that processes the W3C DOM
* interface, and then (implicitly) discard any wrapper objects created.
* This package does not currently support DOM update operations, nor
* does it respond to events generated by the underlying XFA DOM.
*
*
* This package is faithful in its mirroring of the XFA DOM structure.
* In particular, if an XDP is loaded into an XFA DOM and then wrapped,
* the document element in the wrapping W3C DOM corresponds to the root
* XDP element of the loaded document. However, if a non-XFA XML file
* is loaded into an XFA DOM and then wrapped, the document element is
* the XDP implicitly created by the XFA DOM, and the root element of
* the document is a child.
*
*
* Because this package wraps XFA DOM object instances with objects that
* implement the W3C DOM interface, there is the potential for a large
* number of wrapper objects to be created. Note, however, that wrapper
* object instances are created dynamically as the caller walks the DOM.
* In other words, it the caller inspects only a small part of the DOM,
* only a small number of wrapper instances will be created.
*
*
* Depending on how this package is used, it is possible to create
* multiple separate wrapper sets (documents) on a single XFA DOM, or
* have a single wrapper set (document) on the underlying XFA DOM. Both
* might be desirable, though the latter is likely more common.
*
*
* To create a single wrapper set, first use attach (com.adobe.xfa.Node)
* with any node from the XFA DOM. This returns a W3C DOM node. For
* subsequent nodes, call attach (Document, com.adobe.xfa.Node) passing
* in the document returned by Node.getOwnerDocument() for any node
* returned by either attach() overload. To create multiple wrapper
* sets, repeat the single wrapper set steps for each wrapper set
* required.
*
*
* Note that this is the only public class in the DOM wrapper package.
* There is no access to wrapper internals.
*
* @exclude from published api.
*/
public class DOM {
/**
* Create a W3C DOM wrapper node instance associated with the given XFA
* DOM node.
*
* Given an XFA DOM node, this method returns an object implementing the
* W3C DOM node interface, corresponding to the XFA node. The result
* can be passed to any package expecting a W3C DOM node as input.
*
*
* Note that a new wrapper instance is always created, even if the
* application has previously called this method on the given XFA node.
* The new instance will have a new document, and navigation from the
* result will yield new wrapper instances for those nodes.
*
* @param xfaNode XFA DOM node to be wrapped.
* @return Corresponding W3C DOM node wrapper.
*/
public static Node attach (com.adobe.xfa.Node xfaNode) {
// if (NodeImpl.DO_DEBUG) {
// System.out.println ("Attach node only");
// }
return attachNode (xfaNode, false);
}
/**
* Find or create a W3C DOM wrapper node instance associated with the
* given XFA DOM node.
*
* Given a W3C DOM document instance and an XFA DOM node, this method
* returns an object implementing the W3C DOM node interface,
* corresponding to the XFA node. The result can be passed to any
* package expecting a W3C DOM node as input.
*
*
* If the given XFA node has already been wrapped for this document
* (either explicitly or implicitly through navigation), the existing
* wrapper instance is returned. Otherwise, a new instance is created,
* and that instance will be associated with the given document.
*
* @param document W3C DOM document in which to wrap the XFA node.
* @param xfaNode XFA DOM node to be wrapped.
* @return Corresponding W3C DOM node wrapper.
*/
public static Node attach (Document document, com.adobe.xfa.Node xfaNode) {
// if (NodeImpl.DO_DEBUG) {
// System.out.println ("Attach node to document");
// }
assert (document instanceof DocumentImpl);
DocumentImpl documentImpl = (DocumentImpl) document;
return documentImpl.attach (xfaNode);
}
/**
* Find the XFA node wrapped by a given node object.
* Given a reference to an org.w3c.dom.Node instance, this method
* returns the corresponding com.adobe.xfa.Node instance if there is
* one.
* @param node Instance of org.w3c.dom.Node to map.
* @return Corresponding com.adobe.xfa.Node instance or null if the
* mapping failed. The mapping will fail if the given node was not
* created by this implementation, or if it refers to an attribute,
* since XFA attributes are not instances of XFA nodes.
*
* Commented out since the intended use has now been deemed illegal.
*/
// public static com.adobe.xfa.Node mapToXFANode (Node node) {
// if (! (node instanceof XFANodeHolder)) {
// return null;
// }
// XFANodeHolder holder = (XFANodeHolder) node;
// return holder.getXFANode();
// }
/*
* Recursively attach the node, working up the XFA hierarchy until the
* document is encountered. This is used by the first attach() overload
* to create a minimum hierarchy from the document down to the requested
* node. In order to create a node wrapper, both the document and its
* parent wrapper must already exist. So the general algorithm is to
* first call attachNode() with the XFA parent, and then create the
* desired wrapper.
*/
private static XFANodeHolder attachNode (com.adobe.xfa.Node xfaNode, boolean recursive) {
XFANodeHolder result = null;
// Ensure that we are on the XML DOM side
if (xfaNode instanceof DualDomNode)
xfaNode = ((DualDomNode)xfaNode).getXmlPeer();
/*
* If the given XFA node is the document, create a document. This is
* complicated by the fact that the XFA DOM has an AppModel element at
* the top of its element hierarchy, so the code needs to handle a
* recursive call differently from an external one.
*/
if (xfaNode instanceof com.adobe.xfa.Document) {
com.adobe.xfa.Document xfaDoc = (com.adobe.xfa.Document) xfaNode;
if (recursive) {
result = new DocumentImpl (xfaDoc);
} else {
// Ensure that the document element gets a chance to initialize
com.adobe.xfa.Node xfaDocChild = xfaDoc.getFirstXMLChild();
while (xfaDocChild != null) {
if (xfaDocChild instanceof com.adobe.xfa.Element) {
break;
}
xfaDocChild = xfaDocChild.getNextXMLSibling();
}
if (xfaDocChild == null) {
return null;
}
XFANodeHolder docElement = attachNode (xfaDocChild, true);
result = docElement.getDocument();
}
/*
* Otherwise, it's a "normal" element. Try to attach its parent first
* and then create an appropriate wrapper for the given node.
*/
} else {
com.adobe.xfa.Element xfaParent = XFANodeHolder.getXFAParent (xfaNode);
if (xfaParent == null) {
return null;
}
XFANodeHolder parent = attachNode (xfaParent, true);
if (parent == null) {
return null;
}
assert (parent instanceof ParentNode);
ParentNode parentNode = (ParentNode) parent;
result = XFANodeHolder.createNode (parentNode, xfaNode);
parentNode.setOnlyChild (result);
}
return result;
}
}