95 lines
3.9 KiB
Java
95 lines
3.9 KiB
Java
package io.gitlab.jfronny.respackopts.filters.util;
|
|
|
|
import io.gitlab.jfronny.commons.LazySupplier;
|
|
import io.gitlab.jfronny.muscript.data.additional.context.Scope;
|
|
import io.gitlab.jfronny.muscript.data.additional.impl.ObjectGraphPrinter;
|
|
import io.gitlab.jfronny.respackopts.Respackopts;
|
|
import io.gitlab.jfronny.respackopts.model.Condition;
|
|
import io.gitlab.jfronny.respackopts.model.DirRpo;
|
|
import io.gitlab.jfronny.respackopts.model.cache.CacheKey;
|
|
import io.gitlab.jfronny.respackopts.muscript.RespackoptsFS;
|
|
import io.gitlab.jfronny.respackopts.util.MetaCache;
|
|
|
|
import java.util.List;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
public sealed interface DirRpoResult {
|
|
FixedState IGNORE = FixedState.IGNORE;
|
|
FixedState ORIGINAL = FixedState.ORIGINAL;
|
|
static Replacement replacement(String originalPrefix, String fallbackPrefix, int version) {
|
|
return new Replacement(originalPrefix, fallbackPrefix, version);
|
|
}
|
|
|
|
static DirRpoResult compute(String file, List<DirRpo> rpos, CacheKey key, RespackoptsFS fs) {
|
|
int version = MetaCache.getMeta(key).version;
|
|
if (version < 11) rpos = rpos.isEmpty() ? rpos : List.of(rpos.getLast());
|
|
LazySupplier<Scope> scope = new LazySupplier<>(() -> MetaCache.getScope(key, fs));
|
|
for (DirRpo rpo : rpos) {
|
|
if (rpo.condition == null) continue;
|
|
try {
|
|
if (rpo.condition.get(scope.get())) continue;
|
|
// Condition does not apply, find fallback
|
|
if (rpo.fallback == null) return IGNORE;
|
|
return replacement(rpo.path + "/", rpo.fallback, version);
|
|
} catch (Condition.ConditionException e) {
|
|
String res = "Could not evaluate condition for " + file + " (pack: " + key.packName() + ")";
|
|
try {
|
|
Respackopts.LOGGER.error(res + " with condition:\n" + ObjectGraphPrinter.printGraph(rpo.condition) + ")", e);
|
|
} catch (Throwable ex) {
|
|
Respackopts.LOGGER.error(res, e);
|
|
}
|
|
}
|
|
}
|
|
return ORIGINAL;
|
|
}
|
|
|
|
enum FixedState implements DirRpoResult {IGNORE, ORIGINAL}
|
|
|
|
final class Replacement implements DirRpoResult {
|
|
public final Prefix original;
|
|
public final Prefix fallback;
|
|
private final int version;
|
|
|
|
public record Prefix(String prefix, String quoted, Pattern pattern) {
|
|
public Prefix(String prefix) {
|
|
this(
|
|
prefix,
|
|
Matcher.quoteReplacement(prefix),
|
|
Pattern.compile(Pattern.quote(prefix))
|
|
);
|
|
}
|
|
}
|
|
|
|
public Replacement(String originalPrefix, String fallbackPrefix, int version) {
|
|
this.original = new Prefix(originalPrefix);
|
|
this.fallback = new Prefix(fallbackPrefix);
|
|
this.version = version;
|
|
}
|
|
|
|
public String toFallback(String original) {
|
|
Matcher m = this.original.pattern.matcher(original);
|
|
if (version < 11) {
|
|
return m.replaceAll(this.fallback.quoted);
|
|
}
|
|
if (!m.find()) {
|
|
Respackopts.LOGGER.error("Attempted conversion to fallback path, but could not find original prefix for: " + original);
|
|
return original;
|
|
}
|
|
return m.replaceFirst(this.fallback.quoted);
|
|
}
|
|
|
|
public String toOriginal(String fallback) {
|
|
Matcher m = this.fallback.pattern.matcher(fallback);
|
|
if (version < 11) {
|
|
return m.replaceAll(this.original.quoted);
|
|
}
|
|
if (!m.find()) {
|
|
Respackopts.LOGGER.error("Attempted conversion to original path, but could not find fallback prefix for: " + fallback);
|
|
return fallback;
|
|
}
|
|
return m.replaceFirst(this.original.quoted);
|
|
}
|
|
}
|
|
}
|