diff --git a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java index 3fd8c857d..145c168d4 100644 --- a/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java +++ b/src/main/java/org/apache/xmlbeans/impl/tool/MavenPlugin.java @@ -24,6 +24,7 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.xmlbeans.XmlError; +import org.apache.xmlbeans.impl.util.FileUtil; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -59,6 +60,10 @@ public class MavenPlugin extends AbstractMojo { @Parameter( defaultValue = "*.xsd,*.wsdl,*.java" ) private String sourceSchemas; + /** sourceSubdirs determines if subdirectories of sourceDir are checked for schemas */ + @Parameter( defaultValue = "false" ) + private boolean sourceSubdirs; + /** xmlConfigs points to your xmlconfig.xml file */ @Parameter( defaultValue = "${project.basedir}/src/schema/xmlconfig.xml" ) private String xmlConfigs; @@ -216,9 +221,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { .replace(".", "\\.") .replace("*",".*") + ")"); - - File[] schemaFiles = Objects.requireNonNull(base.listFiles((dir, name) -> - !name.endsWith(".xsdconfig") && pat.matcher(name).matches())); + Collection schemaFiles = FileUtil.find(base, pat, sourceSubdirs); for (File sf : schemaFiles) { String name = sf.getName(); switch (name.replaceAll(".*\\.", "")) { diff --git a/src/main/java/org/apache/xmlbeans/impl/util/FileUtil.java b/src/main/java/org/apache/xmlbeans/impl/util/FileUtil.java new file mode 100644 index 000000000..8637d1a05 --- /dev/null +++ b/src/main/java/org/apache/xmlbeans/impl/util/FileUtil.java @@ -0,0 +1,33 @@ +package org.apache.xmlbeans.impl.util; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class FileUtil { + + private FileUtil() {} + + /** + * @param base Directory where to look for files + * @param pattern Regex pattern the files must match to be included + * @param searchSubdirectories If true, search all subdirectories. Otherwise, only search base + * @return Collection of files in base and possibly subdirectories that match pattern + */ + public static Collection find(File base, Pattern pattern, boolean searchSubdirectories) { + try (Stream pathStream = Files.find(base.toPath(), searchSubdirectories ? Integer.MAX_VALUE : 1, (path, atts) -> { + String name = path.getFileName().toString(); + return !name.endsWith(".xsdconfig") && pattern.matcher(name).matches(); + })) { + return pathStream.map(Path::toFile).collect(Collectors.toList()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/src/main/maven/plugin.xml b/src/main/maven/plugin.xml index ef2d7fce2..c1002c38c 100644 --- a/src/main/maven/plugin.xml +++ b/src/main/maven/plugin.xml @@ -167,6 +167,13 @@ true sourceSchemas is a comma-delimited list of all the schemas you want to compile + + sourceSubdirs + boolean + false + true + sourceSubdirs determines if subdirectories of sourceDir are checked for schemas + xmlConfigs java.lang.String @@ -363,6 +370,7 @@ + diff --git a/src/test/java/org/apache/xmlbeans/impl/util/FileUtilTest.java b/src/test/java/org/apache/xmlbeans/impl/util/FileUtilTest.java new file mode 100644 index 000000000..23e80a2c5 --- /dev/null +++ b/src/test/java/org/apache/xmlbeans/impl/util/FileUtilTest.java @@ -0,0 +1,69 @@ +package org.apache.xmlbeans.impl.util; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.Comparator; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class FileUtilTest { + + private Path root; + + @BeforeEach + public void setup() throws IOException { + root = Files.createTempDirectory("test"); + } + + @AfterEach + public void cleanup() throws IOException { + try (Stream walk = Files.walk(root)) { + walk.sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + } + + @Test + public void testFindNoSubdirs() throws IOException { + Files.createFile(root.resolve("test1.xsdconfig")); + Files.createFile(root.resolve("test1.xsd")); + Files.createFile(root.resolve("test1.txt")); + Path dir = Files.createDirectory(root.resolve("test")); + Files.createFile(dir.resolve("test2.xsdconfig")); + Files.createFile(dir.resolve("test2.xsd")); + Files.createFile(dir.resolve("test2.txt")); + + Collection files = FileUtil.find(root.toFile(), Pattern.compile(".*\\.xsd"), false); + + assertEquals(1, files.size()); + assertEquals("test1.xsd", files.iterator().next().getName()); + } + + @Test + public void testFindSubdirs() throws IOException { + Files.createFile(root.resolve("test1.xsdconfig")); + Files.createFile(root.resolve("test1.xsd")); + Files.createFile(root.resolve("test1.txt")); + Path dir = Files.createDirectory(root.resolve("test")); + Files.createFile(dir.resolve("test2.xsdconfig")); + Files.createFile(dir.resolve("test2.xsd")); + Files.createFile(dir.resolve("test2.txt")); + + Collection files = FileUtil.find(root.toFile(), Pattern.compile(".*\\.xsd"), true); + + assertEquals(2, files.size()); + assertEquals(Set.of("test1.xsd", "test2.xsd"), files.stream().map(File::getName).collect(Collectors.toSet())); + } +} \ No newline at end of file