Newer
Older
KeeperJerry_Launcher / Launcher / source / hasher / FileNameMatcher.java
@KeeperJerry KeeperJerry on 27 Jun 2020 2 KB Рефактор кода
package launcher.hasher;

import launcher.LauncherAPI;
import launcher.helper.IOHelper;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Pattern;

public final class FileNameMatcher
{
    private static final Entry[] NO_ENTRIES = new Entry[0];

    // Instance
    private final Entry[] update;
    private final Entry[] verify;
    private final Entry[] exclusions;

    @LauncherAPI
    public FileNameMatcher(String[] update, String[] verify, String[] exclusions)
    {
        this.update = toEntries(update);
        this.verify = toEntries(verify);
        this.exclusions = toEntries(exclusions);
    }

    private FileNameMatcher(Entry[] update, Entry[] verify, Entry[] exclusions)
    {
        this.update = update;
        this.verify = verify;
        this.exclusions = exclusions;
    }

    private static boolean anyMatch(Entry[] entries, Collection<String> path)
    {
        return Arrays.stream(entries).anyMatch(e -> e.matches(path));
    }

    private static Entry[] toEntries(String... entries)
    {
        return Arrays.stream(entries).map(Entry::new).toArray(Entry[]::new);
    }

    @LauncherAPI
    public boolean shouldUpdate(Collection<String> path)
    {
        return (anyMatch(update, path) || anyMatch(verify, path)) && !anyMatch(exclusions, path);
    }

    @LauncherAPI
    public boolean shouldVerify(Collection<String> path)
    {
        return anyMatch(verify, path) && !anyMatch(exclusions, path);
    }

    @LauncherAPI
    public FileNameMatcher verifyOnly()
    {
        return new FileNameMatcher(NO_ENTRIES, verify, exclusions);
    }

    private static final class Entry
    {
        private static final Pattern SPLITTER = Pattern.compile(Pattern.quote(IOHelper.CROSS_SEPARATOR) + '+');
        private final Pattern[] parts;

        private Entry(CharSequence exclusion)
        {
            parts = SPLITTER.splitAsStream(exclusion).map(Pattern::compile).toArray(Pattern[]::new);
        }

        private boolean matches(Collection<String> path)
        {
            if (parts.length > path.size())
            {
                return false;
            }

            // Verify path parts
            Iterator<String> iterator = path.iterator();
            for (Pattern patternPart : parts)
            {
                String pathPart = iterator.next();
                if (!patternPart.matcher(pathPart).matches())
                {
                    return false;
                }
            }

            // All matches
            return true;
        }
    }
}