/* * Copyright (C) 2014 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.errai.forge.facet.resource; import org.jboss.errai.forge.test.base.ForgeTest; import org.jboss.errai.forge.xml.ElementFactory; import org.jboss.errai.forge.xml.XmlParserFactory; import org.jboss.forge.addon.projects.Project; import org.junit.Test; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import javax.inject.Inject; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import java.io.*; import java.util.*; import static org.junit.Assert.*; public class AbstractXmlResourceFacetTest extends ForgeTest { @Inject private XmlParserFactory xmlParserFactory; public class TestXmlResourceFacet extends AbstractXmlResourceFacet { private final String relPath; private final Map<String, Collection<Node>> nodes; private final Map<String, Node> replacements; private final Map<String, Node> replacementsRemoval; public TestXmlResourceFacet(final String relPath, final Map<String, Collection<Node>> nodes, final Map<String, Node> replacements, final Map<String, Node> replacementsRemoval) { this.relPath = relPath; this.nodes = nodes; this.replacements = replacements; this.replacementsRemoval = replacementsRemoval; this.xmlParserFactory = AbstractXmlResourceFacetTest.this.xmlParserFactory; } @Override protected Map<XPathExpression, Collection<Node>> getElementsToInsert(final XPath xPath, final ElementFactory elemFactory) throws ParserConfigurationException, XPathExpressionException { final Map<XPathExpression, Collection<Node>> retVal = new HashMap<XPathExpression, Collection<Node>>(nodes.size()); for (final String rawExpression : nodes.keySet()) { final Collection<Node> value = new ArrayList<Node>(nodes.get(rawExpression).size()); for (final Node importNode : nodes.get(rawExpression)) { value.add(elemFactory.importElement((Element) importNode, true)); } retVal.put(xPath.compile(rawExpression), value); } return retVal; } private Map<XPathExpression, Node> prepMap(final XPath xPath, final ElementFactory elemFactory, final Map<String, Node> map) throws XPathExpressionException, DOMException { final Map<XPathExpression, Node> retVal = new HashMap<XPathExpression, Node>(map.size()); for (final String rawExpression : map.keySet()) { retVal.put(xPath.compile(rawExpression), elemFactory.importElement((Element) map.get(rawExpression), true)); } return retVal; } @Override protected Map<XPathExpression, Node> getReplacements(final XPath xPath, final ElementFactory elemFactory) throws ParserConfigurationException, XPathExpressionException, DOMException { return prepMap(xPath, elemFactory, replacements); } @Override protected String getRelPath() { return relPath; } @Override protected Map<XPathExpression, Node> getRemovalMap(final XPath xPath, final ElementFactory elemFactory) throws ParserConfigurationException, XPathExpressionException { return prepMap(xPath, elemFactory, replacementsRemoval); } } @Test public void testIsInstalledRecursiveCase() throws Exception { final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final List<Node> nodes = Arrays.asList(new Node[] { doc.createElement("first"), doc.createElement("first") }); nodes.get(0).appendChild(doc.createElement("second")).appendChild(doc.createElement("third")); nodes.get(0).getFirstChild().appendChild(doc.createElement("fourth")); nodes.get(0).appendChild(doc.createElement("fifth")); ((Element) nodes.get(1).appendChild(doc.createElement("second"))).setAttribute("name", "test"); final Map<String, Collection<Node>> insertMap = new HashMap<String, Collection<Node>>(1); insertMap.put("/main", nodes); final Map<String, Node> empty = new HashMap<String, Node>(0); final Project project = initializeJavaProject(); final TestXmlResourceFacet testFacet = new TestXmlResourceFacet( writeResourceToFile("org/jboss/errai/forge/facet/resource/AbstractXmlResourceFacetTest-1.xml"), insertMap, empty, empty); testFacet.setFaceted(project); assertTrue(testFacet.isInstalled()); } @Test public void testNotInstalledRecursiveCase() throws Exception { final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final List<Node> nodes = Arrays.asList(new Node[] { doc.createElement("first"), doc.createElement("first") }); nodes.get(0).appendChild(doc.createElement("second")).appendChild(doc.createElement("third")); // This extra attribute should cause isInstalled to return false. ((Element) nodes.get(0).getFirstChild()).setAttribute("foo", "bar"); nodes.get(0).getFirstChild().appendChild(doc.createElement("fourth")); nodes.get(0).appendChild(doc.createElement("fifth")); ((Element) nodes.get(1).appendChild(doc.createElement("second"))).setAttribute("name", "test"); final Map<String, Collection<Node>> insertMap = new HashMap<String, Collection<Node>>(1); insertMap.put("/main", nodes); final Map<String, Node> empty = new HashMap<String, Node>(0); final Project project = initializeJavaProject(); final TestXmlResourceFacet testFacet = new TestXmlResourceFacet( writeResourceToFile("org/jboss/errai/forge/facet/resource/AbstractXmlResourceFacetTest-1.xml"), insertMap, empty, empty); testFacet.setFaceted(project); assertFalse(testFacet.isInstalled()); } @Test public void testSimpleReplacement() throws Exception { final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); final Map<String, Node> replacements = new HashMap<String, Node>(1); final String key = "/main/first/second[@name='test']/.."; final Element value = doc.createElement("different"); replacements.put(key, value); final Project project = initializeJavaProject(); final TestXmlResourceFacet testFacet = new TestXmlResourceFacet( writeResourceToFile("org/jboss/errai/forge/facet/resource/AbstractXmlResourceFacetTest-1.xml"), new HashMap<String, Collection<Node>>(0), replacements, new HashMap<String, Node>(0)); testFacet.setFaceted(project); assertTrue(testFacet.install()); final Document resDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder() .parse(new File(testFacet.relPath)); assertEquals(1, resDoc.getElementsByTagName("different").getLength()); assertEquals(1, resDoc.getElementsByTagName("first").getLength()); } private String writeResourceToFile(final String res) throws IOException { final File file = File.createTempFile(getClass().getSimpleName(), ".xml"); file.deleteOnExit(); final InputStream resourceAsStream = ClassLoader.getSystemClassLoader().getResourceAsStream(res); final BufferedInputStream stream = new BufferedInputStream(resourceAsStream); final BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(file)); final byte[] buf = new byte[256]; for (int read = stream.read(buf); read != -1; read = stream.read(buf)) { writer.write(buf, 0, read); } writer.close(); stream.close(); return file.getAbsolutePath(); } }