/*
* Created on 20.11.2003
*
* (c) Stabsstelle IKT-Strategie des Bundes
*/
package at.gv.egovernment.moa.spss.slinterface.transformers;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.xerces.dom.DocumentImpl;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import at.gv.egovernment.moa.spss.slinterface.Constants;
/**
* @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at)
*/
public class Utils
{
/**
*
* @param elem
* @param prefixes
* @param namespaces
* @param names
*
* @pre elem
is backed by a org.apache.xerces.dom.DocumentImpl
.
*/
public static Element transformDeep(Element elem, Map prefixes, Map namespaces, Map names)
{
// Get node iterator for element
DocumentTraversal docTraversal = (DocumentImpl) elem.getOwnerDocument();
NodeIterator elemsIt = docTraversal.createNodeIterator(elem, NodeFilter.SHOW_ELEMENT, null, true);
// Make iterator immutable
List elemsList = new LinkedList();
while (true)
{
Node currNode = elemsIt.nextNode();
if (currNode == null) break;
elemsList.add(currNode);
}
Iterator elemsImmIt = elemsList.iterator();
Element returnValue = null;
while (elemsImmIt.hasNext())
{
Element currElem = (Element) elemsImmIt.next();
String nsUri = currElem.getNamespaceURI();
String localName = currElem.getLocalName();
QName qName = new QName(nsUri, localName);
// Check if element is in "names"
QName newQName = (QName)names.get(qName);
if (newQName != null)
{
Element transformedElem = transformElem(currElem, newQName, prefixes);
if (returnValue == null) returnValue = transformedElem;
}
else
{
String newNamespace = (String)namespaces.get(nsUri);
if (newNamespace != null)
{
newQName = new QName(newNamespace, localName);
Element transformedElem = transformElem(currElem, newQName, prefixes);
if (returnValue == null) returnValue = transformedElem;
}
}
}
return returnValue;
}
/* ---------------------------------------------------------------------------------------------------- */
private static Element transformElem(Element currElem, QName newQName, Map prefixes)
{
Element newElem = currElem.getOwnerDocument().createElementNS(newQName.nsUrl_,
(String) prefixes.get(newQName.nsUrl_) + ":" + newQName.localName_);
currElem.getParentNode().replaceChild(newElem, currElem);
// Treat attributes of currElem
NamedNodeMap currAttrs = currElem.getAttributes();
ArrayList currAttrsList = new ArrayList(currAttrs.getLength());
for (int i = 0; i < currAttrs.getLength(); i++) currAttrsList.add(currAttrs.item(i));
for (int i = 0; i < currAttrsList.size(); i++)
{
Attr currAttr = (Attr)currAttrsList.get(i);
currAttr.getOwnerElement().removeAttributeNode(currAttr);
// Workaround for bad Xerces behaviour: default attributes in the xml namespace are created without
// the xml prefix
if (Constants.NSURI_XML_.equals(currAttr.getNamespaceURI()) && "space".equals(currAttr.getLocalName()))
{
newElem.setAttributeNS(Constants.NSURI_XML_, "xml:space", currAttr.getValue());
}
else
{
newElem.setAttributeNode(currAttr);
}
}
// Treat child nodes of currElem
NodeList currChildren = currElem.getChildNodes();
ArrayList currChildrenList = new ArrayList(currChildren.getLength());
for (int i = 0; i < currChildren.getLength(); i++) currChildrenList.add(currChildren.item(i));
for (int i = 0; i < currChildrenList.size(); i++)
{
Node currChild = (Node)currChildrenList.get(i);
currElem.removeChild(currChild);
newElem.appendChild(currChild);
}
return newElem;
}
}