Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing JT-173 (backport of modified version of PR made by phax) #287

Merged
merged 1 commit into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.MatchPatterns;
import org.codehaus.plexus.util.Scanner;
import org.codehaus.plexus.util.SelectorUtils;
import org.jvnet.jaxb.maven.util.CollectionUtils.Function;
import org.sonatype.plexus.build.incremental.BuildContext;
import org.xml.sax.InputSource;
Expand Down Expand Up @@ -95,11 +98,93 @@ public static List<File> scanDirectoryForFiles(BuildContext buildContext, final

scanner.scan();

final List<File> files = new ArrayList<File>();
for (final String name : scanner.getIncludedFiles()) {
// Reorder files according to includes specific file ordering
List<String> orderedIncludedFiles = reorderFiles(scanner.getIncludedFiles(), includes);

final List<File> files = new ArrayList<>();
for (final String name : orderedIncludedFiles) {
files.add(new File(directory, name).getCanonicalFile());
}

return files;
}

private static boolean isWildcard (final String s) {
return s.indexOf ('*') >= 0 || s.indexOf ('?') >= 0;
}

/**
* Reorder the result of "scanner.getIncludedFile" so that the order of the
* source includes is maintained as good as possible.
* Examples:<br>
* If the includes contain [a, b, c] and the resulting list should be in that order.<br>
* If the includes contain [a, b*, c] the resulting list should be [a, matches-of(b*), c]
*
* @param resolvedFiles
* resolved files from scanner.getIncludedFiles. May not be <code>null</code>.
* @param includes
* The source includes in the correct order. May be <code>null</code> or empty.
* @return The ordered list of files, that tries to take the source order as good as possible
*/
protected static List<String> reorderFiles(final String[] resolvedFiles, final String[] includes) {
if (includes == null || includes.length == 0) {
// return "as is"
return Arrays.asList(resolvedFiles);
}

// copy of the initial list in order to avoid changes in resolvedFiles var
List<String> resolvedFilesList = new ArrayList<>(Arrays.asList(resolvedFiles));
final List<String> ret = new ArrayList<>(resolvedFilesList.size());

// For each include
for (final String include : includes) {
// Create MatchPatterns from normalizePattern of the include (like it was done in DirectoryScanner)
MatchPatterns inc = MatchPatterns.from(normalizePattern(include));

// Find all matches in the resolved files list
final List<String> matches = new ArrayList<>();
for (final String resFile : resolvedFilesList) {
if (inc.matches(resFile, false)) {
matches.add(resFile);
}
}

// Add all matches to the result list
ret.addAll(matches);
// Remove from the main list
resolvedFilesList.removeAll(matches);
}

// Add all remaining resolved files in the order "as is"
ret.addAll(resolvedFilesList);

return ret;
}

/**
* Copy of Plexus-utils function (private) to normalize pattern of include.<br>
* Normalizes the pattern, e.g. converts forward and backward slashes to the platform-specific file separator.
*
* @param pattern The pattern to normalize, must not be <code>null</code>.
* @return The normalized pattern, never <code>null</code>.
*/
private static String normalizePattern(String pattern) {
pattern = pattern.trim();

if (pattern.startsWith(SelectorUtils.REGEX_HANDLER_PREFIX)) {
if (File.separatorChar == '\\') {
pattern = org.codehaus.plexus.util.StringUtils.replace(pattern, "/", "\\\\");
} else {
pattern = org.codehaus.plexus.util.StringUtils.replace(pattern, "\\\\", "/");
}
} else {
pattern = pattern.replace(File.separatorChar == '/' ? '\\' : '/', File.separatorChar);

if (pattern.endsWith(File.separator)) {
pattern += "**";
}
}

return pattern;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package org.jvnet.jaxb.maven.util;

import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class IOUtilsTests {

@Test
public void reorderFilesIncludesNull() {
String[] files = {"a.xsd", "c.xsd", "b.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, null);

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());
Assert.assertEquals(files[0], orderedFiles.get(0));
Assert.assertEquals(files[1], orderedFiles.get(1));
Assert.assertEquals(files[2], orderedFiles.get(2));
}

@Test
public void reorderFilesIncludesEmpty() {
String[] files = {"a.xsd", "c.xsd", "b.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, new String[] {});

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());
Assert.assertEquals(files[0], orderedFiles.get(0));
Assert.assertEquals(files[1], orderedFiles.get(1));
Assert.assertEquals(files[2], orderedFiles.get(2));
}

@Test
public void reorderFilesIncludesNoWildcard() {
String[] files = {"a.xsd", "c.xsd", "b.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, new String[] { "b.xsd", "c.xsd", "a.xsd" });

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());
Assert.assertEquals(files[2], orderedFiles.get(0));
Assert.assertEquals(files[1], orderedFiles.get(1));
Assert.assertEquals(files[0], orderedFiles.get(2));
}

@Test
public void reorderFilesIncludesNoWildcardWithCommonSuffix() {
String[] files = {"a.xsd", "b.xsd", "service-ab.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, new String[] { "b.xsd", "a.xsd", "service-ab.xsd" });

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());
Assert.assertEquals(files[1], orderedFiles.get(0));
Assert.assertEquals(files[0], orderedFiles.get(1));
Assert.assertEquals(files[2], orderedFiles.get(2));
}

@Test
public void reorderFilesIncludesWithWildcardFirst() {
String[] files = {"a.xsd", "common/c1.xsd", "b.xsd", "common/c2.xsd", "common/a.xsd", "common/b.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, new String[] { "common/*.xsd", "a.xsd", "b.xsd" });

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());
// we have all common/*.xsd files in same order
Assert.assertEquals(files[1], orderedFiles.get(0));
Assert.assertEquals(files[3], orderedFiles.get(1));
Assert.assertEquals(files[4], orderedFiles.get(2));
Assert.assertEquals(files[5], orderedFiles.get(3));
// and then a.xsd
Assert.assertEquals(files[0], orderedFiles.get(4));
// and finally b.xsd
Assert.assertEquals(files[2], orderedFiles.get(5));
}

@Test
public void reorderFilesIncludesWithWildcardMiddle() {
String[] files = {"a.xsd", "common/c1.xsd", "b.xsd", "common/c2.xsd", "common/a.xsd", "common/b.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, new String[] { "a.xsd", "common/*.xsd", "b.xsd" });

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());

// we have a.xsd
Assert.assertEquals(files[0], orderedFiles.get(0));
// and then all common/*.xsd files in same order
Assert.assertEquals(files[1], orderedFiles.get(1));
Assert.assertEquals(files[3], orderedFiles.get(2));
Assert.assertEquals(files[4], orderedFiles.get(3));
Assert.assertEquals(files[5], orderedFiles.get(4));
// and finally b.xsd
Assert.assertEquals(files[2], orderedFiles.get(5));
}

@Test
public void reorderFilesIncludesWithWildcardLast() {
String[] files = {"a.xsd", "common/c1.xsd", "b.xsd", "common/c2.xsd", "common/a.xsd", "common/b.xsd" };
List<String> orderedFiles = IOUtils.reorderFiles(files, new String[] { "a.xsd", "b.xsd", "common/*.xsd" });

Assert.assertNotNull("Ordered files list should not be null",
orderedFiles);
Assert.assertEquals("Ordered files list should contains all elements of initial list",
files.length, orderedFiles.size());

// we have a.xsd
Assert.assertEquals(files[0], orderedFiles.get(0));
// and then b.xsd
Assert.assertEquals(files[2], orderedFiles.get(1));
// and finally all common/*.xsd files in same order
Assert.assertEquals(files[1], orderedFiles.get(2));
Assert.assertEquals(files[3], orderedFiles.get(3));
Assert.assertEquals(files[4], orderedFiles.get(4));
Assert.assertEquals(files[5], orderedFiles.get(5));
}
}
Loading