/******************************************************************************* * Copyright (c) 2008 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.smooks.configuration.editors.xml; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.ParserConfigurationException; import org.jboss.tools.smooks.templating.model.xml.XMLSampleModelBuilder; 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; import org.xml.sax.SAXException; /** * @author Dart Peng * @Date Jul 25, 2008 */ public class XMLObjectAnalyzer { public TagList analyze(String xmlFilePath, String[] ignoreNodeNames, Class<? extends AbstractXMLObject> tagObjectClass) throws ParserConfigurationException, SAXException, IOException { FileInputStream stream = new FileInputStream(xmlFilePath); TagList list = this.analyze(stream, ignoreNodeNames, tagObjectClass); try { stream.close(); } catch (IOException e) { } return list; } public TagList analyze(Document doc, String[] ignoreNodeNames, Class<? extends AbstractXMLObject> tagObjectClass) { if (doc == null) return null; Element rootElement = doc.getDocumentElement(); TagList dco = new TagList(); dco.setName("Docuement"); //$NON-NLS-1$ dco.addRootTag(parseElement(rootElement, null, ignoreNodeNames, tagObjectClass)); return dco; } public TagList analyze(InputStream stream, String[] ignoreNodeNames, Class<? extends AbstractXMLObject> tagObjectClass) throws ParserConfigurationException, SAXException, IOException { DocumentBuilder builder = createDocumentBuildingFactory(); Document doc = builder.parse(stream); XMLSampleModelBuilder.trimNonModelNodes(doc.getDocumentElement()); return analyze(doc, ignoreNodeNames, tagObjectClass); } public DocumentBuilder createDocumentBuildingFactory() throws ParserConfigurationException { return XMLUtils.getDOMBuilder(); } public TagObject analyzeFregment(InputStream stream, String[] ignoreNodeNames, Class<? extends AbstractXMLObject> tagObjectClass) throws ParserConfigurationException, SAXException, IOException { DocumentBuilder builder = createDocumentBuildingFactory(); org.w3c.dom.Document doc = builder.parse(stream); Element rootElement = doc.getDocumentElement(); return parseElement(rootElement, null, ignoreNodeNames, tagObjectClass); } protected TagObject getChildTagByName(String name, TagObject tag, String[] ignoreNodeNames) { if (isIgnoreNode(name, ignoreNodeNames)) return null; if (tag == null) return null; List<?> list = tag.getXMLNodeChildren(); for (Iterator<?> iterator = list.iterator(); iterator.hasNext();) { TagObject tagc = (TagObject) iterator.next(); if (tagc.getName().equals(name)) return tagc; } return null; } private boolean isIgnoreNode(Element element, String[] ignoreNodeNames) { return isIgnoreNode(element.getNodeName(), ignoreNodeNames); } // private boolean isIgnoreNode(TagObject element , String[] // ignoreNodeNames){ // return isIgnoreNode(element.getName(), ignoreNodeNames); // } private boolean isIgnoreNode(String name, String[] ignoreNodeNames) { if (ignoreNodeNames == null) return false; for (int i = 0; i < ignoreNodeNames.length; i++) { String ignore = ignoreNodeNames[i]; if (ignore.trim().equalsIgnoreCase(name)) return true; } return false; } protected TagObject parseElement(Element element, TagObject parentTag, String[] ignoreNodeNames, Class<? extends AbstractXMLObject> tagObjectClass) { if (isIgnoreNode(element, ignoreNodeNames)) return null; boolean canAdd = false; TagObject tag = getChildTagByName(element.getNodeName(), parentTag, ignoreNodeNames); if (tag == null) { if (tagObjectClass != null) { try { tag = (TagObject) tagObjectClass.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } else { tag = new TagObject(); } canAdd = true; } if (tag == null) return null; tag.setReferenceElement(element); String localName = element.getLocalName(); String nodeName = element.getNodeName(); if (localName == null) { localName = nodeName; } tag.setName(localName); fillProperties(element, tag, ignoreNodeNames); tag.setNamespaceURI(element.getNamespaceURI()); NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node instanceof Element) { Element childElement = (Element) node; TagObject t = parseElement(childElement, tag, ignoreNodeNames, tagObjectClass); if (t != null) { tag.addChildTag(t); t.setReferenceElement(childElement); } } } if (canAdd) return tag; else return null; } protected boolean hasSameNameProperty(String proName, TagObject tag) { List<TagPropertyObject> pros = tag.getProperties(); for (Iterator<TagPropertyObject> iterator = pros.iterator(); iterator.hasNext();) { TagPropertyObject tp = (TagPropertyObject) iterator.next(); if (tp.getName().equals(proName)) return true; } return false; } protected void fillProperties(Element element, TagObject tag, String[] ignoreNodeNames) { NamedNodeMap attrMap = element.getAttributes(); for (int i = 0; i < attrMap.getLength(); i++) { Node node = attrMap.item(i); if (node instanceof Attr) { Attr attr = (Attr) node; String attrName = attr.getName(); String value = attr.getValue(); if (isIgnoreNode(attrName, ignoreNodeNames)) continue; if (hasSameNameProperty(attrName, tag)) { continue; } TagPropertyObject pro = new TagPropertyObject(); String localName = attr.getLocalName(); String name = attr.getNodeName(); if (localName == null) { localName = name; } pro.setReferenceAttibute(attr); pro.setName(localName); pro.setValue(value); pro.setNamespaceURI(attr.getNamespaceURI()); tag.addProperty(pro); } } } }