From 426102ff4dc612c956dad8b4b45a0d6d7962abce Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Mon, 4 Aug 2025 15:58:48 -0500 Subject: [PATCH] IVY-1658: merge `ivy-module` namespaces --- META-INF/MANIFEST.MF | 2 +- .../parser/xml/XmlModuleDescriptorParser.java | 24 ++- .../xml/XmlModuleDescriptorUpdater.java | 18 +- .../apache/ivy/core/deliver/DeliverTest.java | 189 +++++++++++------- .../org/apache/ivy/core/deliver/ivy-1111.xml | 26 --- 5 files changed, 150 insertions(+), 109 deletions(-) delete mode 100644 test/java/org/apache/ivy/core/deliver/ivy-1111.xml diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index 05111fe7..9760f4fe 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -88,7 +88,7 @@ Export-Package: org.apache.ivy;version="2.0.0", org.apache.ivy.plugins.pack;version="2.6.0", org.apache.ivy.plugins.parser;version="2.0.0", org.apache.ivy.plugins.parser.m2;version="2.6.0", - org.apache.ivy.plugins.parser.xml;version="2.0.0", + org.apache.ivy.plugins.parser.xml;version="2.6.0", org.apache.ivy.plugins.report;version="2.0.0", org.apache.ivy.plugins.repository;version="2.0.0", org.apache.ivy.plugins.repository.file;version="2.0.0", diff --git a/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java b/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java index 878fd0ae..952caf27 100644 --- a/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java +++ b/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java @@ -83,6 +83,7 @@ import org.apache.ivy.util.FileUtil; import org.apache.ivy.util.Message; import org.apache.ivy.util.XMLHelper; import org.apache.ivy.util.extendable.ExtendableItemHelper; + import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -548,37 +549,30 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser { * @param parent * a given parent module descriptor */ - protected void mergeWithOtherModuleDescriptor(List extendTypes, - ModuleDescriptor parent) { - + protected void mergeWithOtherModuleDescriptor(List extendTypes, ModuleDescriptor parent) { if (extendTypes.contains("all")) { mergeAll(parent); } else { if (extendTypes.contains("info")) { mergeInfo(parent); } - if (extendTypes.contains("configurations")) { mergeConfigurations(parent); } - if (extendTypes.contains("dependencies")) { mergeDependencies(parent.getDependencies()); } - if (extendTypes.contains("description")) { mergeDescription(parent.getDescription()); } - if (extendTypes.contains("licenses")) { mergeLicenses(parent.getLicenses()); } - if (extendTypes.contains("excludes")) { mergeExcludes(parent.getAllExcludeRules()); } } - + mergeNamespaces(parent.getExtraAttributesNamespaces()); // IVY-1658 } /** @@ -722,6 +716,17 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser { } } + private void mergeNamespaces(Map namespaces) { + if (namespaces != null && !namespaces.isEmpty()) { + for (Map.Entry entry : namespaces.entrySet()) { + Message.debug("Merging extra attribute namesapce: " + entry); + if (getMd().getExtraAttributesNamespaces().get(entry.getKey()) == null) { + getMd().addExtraAttributeNamespace(entry.getKey(), entry.getValue()); + } + } + } + } + /** * Returns the parent module using the location attribute (for dev purpose). * @@ -1455,5 +1460,4 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser { public String toString() { return "ivy parser"; } - } diff --git a/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java b/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java index 9af53fa3..25cb3deb 100644 --- a/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java +++ b/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java @@ -59,6 +59,7 @@ import org.apache.ivy.util.DateUtil; import org.apache.ivy.util.Message; import org.apache.ivy.util.XMLHelper; import org.apache.ivy.util.extendable.ExtendableItemHelper; + import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -409,13 +410,22 @@ public final class XmlModuleDescriptorUpdater { // copy write("<" + qName); - for (int i = 0; i < attributes.getLength(); i++) { - write(" " + attributes.getQName(i) + "=\"" - + substitute(settings, attributes.getValue(i)) + "\""); + if (options.isMerge() && path.equals("ivy-module")) { + for (int i = 0, n = attributes.getLength(); i < n; i += 1) { + if (attributes.getQName(i).startsWith("xmlns:")) continue; + write(" " + attributes.getQName(i) + "=\"" + substitute(settings, attributes.getValue(i)) + "\""); + } + Map namespaces = options.getMergedDescriptor().getExtraAttributesNamespaces(); + for (Map.Entry namespace : namespaces.entrySet()) { + write(" xmlns:" + namespace.getKey() + "=\"" + substitute(settings, namespace.getValue()) + "\""); + } + } else { + for (int i = 0, n = attributes.getLength(); i < n; i += 1) { + write(" " + attributes.getQName(i) + "=\"" + substitute(settings, attributes.getValue(i)) + "\""); + } } } justOpen = qName; - // indent.append("\t"); } private void startExtends(Attributes attributes) { diff --git a/test/java/org/apache/ivy/core/deliver/DeliverTest.java b/test/java/org/apache/ivy/core/deliver/DeliverTest.java index aa303ef7..1ae6e9d9 100644 --- a/test/java/org/apache/ivy/core/deliver/DeliverTest.java +++ b/test/java/org/apache/ivy/core/deliver/DeliverTest.java @@ -17,79 +17,35 @@ */ package org.apache.ivy.core.deliver; -import org.apache.ivy.TestHelper; -import org.apache.ivy.ant.IvyDeliver; -import org.apache.ivy.ant.IvyResolve; -import org.apache.ivy.util.FileUtil; -import org.apache.tools.ant.Project; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.net.URI; -import static org.junit.Assert.assertFalse; +import org.apache.ivy.TestHelper; +import org.apache.ivy.ant.IvyDeliver; +import org.apache.ivy.ant.IvyResolve; +import org.apache.ivy.util.FileUtil; + +import org.apache.commons.io.FileUtils; +import org.apache.tools.ant.Project; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + import static org.junit.Assert.assertTrue; public class DeliverTest { - private File cache; + + private File cacheDir; private File deliverDir; private IvyDeliver ivyDeliver; - @Before - public void setUp() { - cache = new File("build/cache"); - System.setProperty("ivy.cache.dir", cache.getAbsolutePath()); - createCache(); - - deliverDir = new File("build/test/deliver"); - deliverDir.mkdirs(); - - Project project = TestHelper.newProject(); - project.init(); - - ivyDeliver = new IvyDeliver(); - ivyDeliver.setProject(project); - ivyDeliver.setDeliverpattern(deliverDir.getAbsolutePath() - + "/[type]s/[artifact]-[revision](-[classifier]).[ext]"); - } - - @After - public void tearDown() { - FileUtil.forceDelete(cache); - FileUtil.forceDelete(deliverDir); - } - private void createCache() { - cache.mkdirs(); - } - - /** - * Test case for IVY-1111. - * - * @throws Exception if something goes wrong - * @see IVY-1111 - */ - @Test - public void testIVY1111() throws Exception { - Project project = ivyDeliver.getProject(); - project.setProperty("ivy.settings.file", "test/repositories/IVY-1111/ivysettings.xml"); - File ivyFile = new File(new URI(DeliverTest.class.getResource("ivy-1111.xml").toString())); - - resolve(ivyFile); - - ivyDeliver.setReplacedynamicrev(true); - ivyDeliver.doExecute(); - - String deliverContent = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml"); - assertFalse(deliverContent.contains("rev=\"latest.integration\"")); - assertTrue(deliverContent.contains("name=\"b\" rev=\"1.5\"")); + cacheDir.mkdirs(); } /** @@ -120,16 +76,113 @@ public class DeliverTest { private String readFile(String fileName) throws IOException { StringBuilder retval = new StringBuilder(); - - File ivyFile = new File(fileName); - BufferedReader reader = new BufferedReader(new FileReader(ivyFile)); - - String line = null; - while ((line = reader.readLine()) != null) { - retval.append(line).append("\n"); + File file = new File(fileName); + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line = null; + while ((line = reader.readLine()) != null) { + retval.append(line).append("\n"); + } } - - reader.close(); return retval.toString(); } + + private File writeFile(String fileText) throws IOException { + File file = File.createTempFile("ivy", ".xml"); + file.deleteOnExit(); + FileUtils.write(file, fileText, "UTF-8"); + return file; + } + + @Before + public void setUp() { + cacheDir = new File("build/cache"); + System.setProperty("ivy.cache.dir", cacheDir.getAbsolutePath()); + createCache(); + + deliverDir = new File("build/test/deliver"); + deliverDir.mkdirs(); + + Project project = TestHelper.newProject(); + project.init(); + + ivyDeliver = new IvyDeliver(); + ivyDeliver.setProject(project); + ivyDeliver.setDeliverpattern(deliverDir.getAbsolutePath() + "/[type]s/[artifact]-[revision](-[classifier]).[ext]"); + } + + @After + public void tearDown() { + FileUtil.forceDelete(cacheDir); + FileUtil.forceDelete(deliverDir); + } + + /** + * Test case for IVY-1111. + */ + @Test + public void testDeliver1111() throws Exception { + ivyDeliver.getProject().setProperty("ivy.settings.file", "test/repositories/IVY-1111/ivysettings.xml"); + + String ivyFile + = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + + resolve(writeFile(ivyFile)); + + ivyDeliver.setReplacedynamicrev(true); + ivyDeliver.doExecute(); + + ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml"); + assertTrue(ivyFile.contains("org=\"test\" name=\"a\" rev=\"1\" revConstraint=\"latest.integration\"")); + assertTrue(ivyFile.contains("org=\"test\" name=\"b\" rev=\"1.5\" revConstraint=\"latest.integration\" e:att=\"att\"")); + assertTrue(ivyFile.contains("org=\"junit\" name=\"junit\" rev=\"4.4\" revConstraint=\"latest.integration\"")); + } + + /** + * Test case for IVY-1658. + */ + @Test + public void testDeliver1658() throws Exception { + String ivyFile + = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + + ivyFile + = "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n"; + + resolve(writeFile(ivyFile)); + + ivyDeliver.doExecute(); + + ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml"); + + assertTrue(ivyFile.contains(" version=\"2.0\"")); + assertTrue(ivyFile.contains(" xmlns:m=\"http://ant.apache.org/ivy/maven\"")); + assertTrue(ivyFile.contains(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")); + assertTrue(ivyFile.contains(" xsi:noNamespaceSchemaLocation=\"http://ant.apache.org/ivy/schemas/ivy.xsd\"")); + } } diff --git a/test/java/org/apache/ivy/core/deliver/ivy-1111.xml b/test/java/org/apache/ivy/core/deliver/ivy-1111.xml deleted file mode 100644 index 3e806260..00000000 --- a/test/java/org/apache/ivy/core/deliver/ivy-1111.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - -