/******************************************************************************* * Copyright (c) 2008, 2012 Obeo. * All rights reserved. This program and the accompanying materials * are 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: * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.emf.eef.codegen.core.util; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Path; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * @author <a href="mailto:goulwen.lefur@obeo.fr">Goulwen Le Fur</a> * */ public class ExtensionHelper { private static final String POINT_ATTRIBUTE_NAME = "point"; private static final String EXTENSION_TAG = "extension"; private static final String PLUGIN_TAG_NAME = "plugin"; private static final String PLUGIN_XML_FILE_PATH = "plugin.xml"; private IProject bundleProject; private Document document; private IFile pluginXML; /** * @param pluginProject * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ public ExtensionHelper(IProject pluginProject) throws ParserConfigurationException, SAXException, IOException { this.bundleProject = pluginProject; this.pluginXML = pluginXML(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(false); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(pluginXML.getLocation().toFile()); } public ExtensionHelper(IFile pluginXML) throws ParserConfigurationException, SAXException, IOException { this.bundleProject = pluginXML.getProject(); this.pluginXML = pluginXML; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(pluginXML.getLocation().toFile()); } /** * @return */ public List<Node> extensions() { List<Node> result = new ArrayList<Node>(); Node pluginTag = pluginTag(); if (pluginTag != null && pluginTag.hasChildNodes()) { NodeList elementsByTagName = document.getElementsByTagName(EXTENSION_TAG); int i = 0; Node next = elementsByTagName.item(i); while (next != null) { result.add(next); i++; next = elementsByTagName.item(i); } } return result; } /** * @param id * @return */ public List<Node> extensionsWithID(String id) { List<Node> result = new ArrayList<Node>(); for (Node node : extensions()) { NamedNodeMap attributes = node.getAttributes(); Node namedItem = attributes.getNamedItem(POINT_ATTRIBUTE_NAME); if (namedItem != null && namedItem.getNodeValue().equals(id)) { result.add(node); } } return result; } /** * @param n1 * @return */ public boolean hasExtension(Node n1) { for (Node node : extensions()) { if (extensionsEqual(n1, node)) { return true; } } return false; } /** * @return the "plugin.xml" file of the plugin */ public IFile pluginXML() { if (pluginXML == null) { return bundleProject.getFile(new Path(PLUGIN_XML_FILE_PATH)); } else { return pluginXML; } } /** * @param helper * @return */ public List<Node> diff(ExtensionHelper helper) { List<Node> extensions = helper.extensions(); List<Node> res = new ArrayList<Node>(extensions.size()); for (Node ext : extensions) { if (!hasExtension(ext)) { res.add(ext); } } return res; } /** * @param extensions * @throws TransformerException * @throws TransformerFactoryConfigurationError * @throws TransformerConfigurationException */ public void append(List<Node> extensions) throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException { for (Node node : extensions) { Node importNode = document.importNode(node, true); pluginTag().appendChild(importNode); } save(); } public void save() throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException { Transformer transformer = TransformerFactory.newInstance().newTransformer(); StreamResult result = new StreamResult(pluginXML.getLocation().toFile()); DOMSource source = new DOMSource(document); transformer.transform(source, result); } /** * @param n1 * @param n2 * @return */ private boolean extensionsEqual(Node n1, Node n2) { boolean res = extensionAttributesEquals(n1, n2); if (res) { // All attributes are equals, comparing sub-nodes NodeList childNodes = n1.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node childNode = childNodes.item(i); if (!hasAMatchingSubNode(childNode, n2)) { return false; } } } return res; } private boolean extensionAttributesEquals(Node n1, Node n2) { NamedNodeMap n1Attributes = n1.getAttributes(); NamedNodeMap n2Attributes = n2.getAttributes(); if (n1Attributes == null) { if (n2Attributes == null) { return true; } else { return false; } } else if (n2Attributes == null) { return false; } else { for (int i = 0; i < n1Attributes.getLength(); i++) { Node item = n1Attributes.item(i); String nodeName = item.getNodeName(); Node matchingItem = n2Attributes.getNamedItem(nodeName); if (!item.getNodeValue().equals(matchingItem.getNodeValue())) { return false; } } return true; } } /** * @param subNode * @param processingNode * @return */ private boolean hasAMatchingSubNode(Node subNode, Node processingNode) { NodeList childNodes = processingNode.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node childNode = childNodes.item(i); if (extensionsEqual(subNode, childNode)) { return true; } } return false; } /** * @return */ private Node pluginTag() { NodeList pluginTags = document.getElementsByTagName(PLUGIN_TAG_NAME); if (pluginTags.item(0) != null) return pluginTags.item(0); return null; } }