/* * JBoss, Home of Professional Open Source * Copyright 2006, JBoss Inc., and others contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2005-2006, JBoss Inc. */ package org.jboss.tools.smooks.templating.model; import java.util.HashMap; import java.util.Map; import org.milyn.xml.DomUtils; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Model Node resolver. * <p/> * Handles hiding of elements from the reserved namespace. * * @author <a href="mailto:tom.fennelly@jboss.com">tom.fennelly@jboss.com</a> */ public class ModelNodeResolver { private Map<String, Node> modelNodeMap = new HashMap<String, Node>(); private Map<String, String> prefixMap = new HashMap<String, String>(); public ModelNodeResolver(Document model) { buildModelNodeMap(model.getDocumentElement(), ""); //$NON-NLS-1$ } public Node resolveNodeMapping(Node node) { return modelNodeMap.get(buildNodePath(node)); } private Object buildNodePath(Node node) { StringBuilder pathBuilder = new StringBuilder(); while(node != null && node.getNodeType() != Node.DOCUMENT_NODE) { if(!ModelBuilder.isInReservedNamespace(node)) { if(pathBuilder.length() > 0) { pathBuilder.insert(0, '/'); //$NON-NLS-1$ } String nodeNS = node.getNamespaceURI(); if(nodeNS != null && nodeNS.length() > 0) { if(node.getNodeType() == Node.ATTRIBUTE_NODE) { pathBuilder.insert(0, "@" + getPrefix(nodeNS) + ":" + ((Attr)node).getName()); //$NON-NLS-1$ //$NON-NLS-2$ } else { pathBuilder.insert(0, getPrefix(nodeNS) + ":" + DomUtils.getName((Element) node)); //$NON-NLS-1$ } } else { if(node.getNodeType() == Node.ATTRIBUTE_NODE) { pathBuilder.insert(0, "@" + ((Attr)node).getName()); //$NON-NLS-1$ } else { pathBuilder.insert(0, DomUtils.getName((Element) node)); } } } node = ModelBuilder.getParentNode(node); } return pathBuilder.toString(); } private void buildModelNodeMap(Element element, String parentPath) { String elementPath = parentPath; if(!ModelBuilder.isInReservedNamespace(element)) { String elNS = element.getNamespaceURI(); if(parentPath.length() > 0) { parentPath += "/"; //$NON-NLS-1$ } if(elNS != null && elNS.length() > 0) { elementPath = parentPath + getPrefix(elNS) + ":" + DomUtils.getName(element); //$NON-NLS-1$ modelNodeMap.put(elementPath, element); } else { elementPath = parentPath + DomUtils.getName(element); modelNodeMap.put(elementPath, element); } NamedNodeMap attributes = element.getAttributes(); int attrCount = attributes.getLength(); for(int i = 0; i < attrCount; i++) { Attr attribute = (Attr) attributes.item(i); if(!ModelBuilder.isInReservedNamespace(attribute)) { String attrNS = attribute.getNamespaceURI(); if(attrNS != null && attrNS.length() > 0) { modelNodeMap.put(elementPath + "/@" + getPrefix(attrNS) + ":" + attribute.getName(), attribute); //$NON-NLS-1$ //$NON-NLS-2$ } else { modelNodeMap.put(elementPath + "/@" + attribute.getName(), attribute); //$NON-NLS-1$ } } } } NodeList children = element.getChildNodes(); int childCount = children.getLength(); for(int i = 0; i < childCount; i++) { Node child = children.item(i); if(child.getNodeType() == Node.ELEMENT_NODE) { buildModelNodeMap((Element) child, elementPath); } } } private String getPrefix(String nsURI) { String prefix = prefixMap.get(nsURI); if(prefix == null) { prefix = "ns" + prefixMap.size(); //$NON-NLS-1$ prefixMap.put(nsURI, prefix); } return prefix; } }