Respackopts/src/main/java/io/gitlab/jfronny/respackopts/filters/util/DirRpoResult.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);
}
}
}