/******************************************************************************* * 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.graphical.editors.model.freemarker; 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.configuration.editors.xml.AbstractXMLObject; import org.jboss.tools.smooks.configuration.editors.xml.TagList; import org.jboss.tools.smooks.configuration.editors.xml.TagObject; import org.jboss.tools.smooks.configuration.editors.xml.TagPropertyObject; import org.jboss.tools.smooks.configuration.editors.xml.XMLUtils; import org.jboss.tools.smooks.templating.model.ModelBuilder; 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 * */ public class FreemarkerModelAnalyzer { 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); 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; } public static boolean isChoiceElement(Element element) { if (element != null) { Node parentNode = element.getParentNode(); if (parentNode instanceof Element) { if (ModelBuilder.isCompositor(parentNode)) { 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 = null; if (ModelBuilder.isCompositor(element)) { tag = parentTag; } else { 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 localName = attr.getLocalName(); String name = attr.getNodeName(); if (localName == null) { localName = name; } if(ModelBuilder.isInReservedNamespace(attr)) { continue; } String value = attr.getValue(); if (isIgnoreNode(localName, ignoreNodeNames)) continue; if (hasSameNameProperty(localName, tag)) { continue; } TagPropertyObject pro = new FreemarkerAttrModel(); tag.addProperty(pro); pro.setName(localName); pro.setValue(value); pro.setNamespaceURI(attr.getNamespaceURI()); pro.setReferenceAttibute(attr); } } } }