diff --git a/modules/lang-painless/spi/src/main/java/org/opensearch/painless/spi/AllowlistLoader.java b/modules/lang-painless/spi/src/main/java/org/opensearch/painless/spi/AllowlistLoader.java index c2ba64d3fc169..daaf0909716bf 100644 --- a/modules/lang-painless/spi/src/main/java/org/opensearch/painless/spi/AllowlistLoader.java +++ b/modules/lang-painless/spi/src/main/java/org/opensearch/painless/spi/AllowlistLoader.java @@ -47,10 +47,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; /** Loads and creates a {@link Allowlist} from one to many text files. */ public final class AllowlistLoader { + private static final Pattern WHITESPACE = Pattern.compile("\\s+"); + /** * Loads and creates a {@link Allowlist} from one to many text files using only the base annotation parsers. * See {@link #loadFromResourceFiles(Class, Map, String...)} for information on how to structure an allowlist @@ -312,9 +315,9 @@ public static Allowlist loadFromResourceFiles(Class resource, Map resource, Map resource, Map parseAllowlistAnnotations(Map annotations; - if ("".equals(line.replaceAll("\\s+", ""))) { + if (line.isBlank()) { annotations = Collections.emptyList(); } else { line = line.trim(); diff --git a/modules/lang-painless/src/main/java/org/opensearch/painless/PainlessScriptEngine.java b/modules/lang-painless/src/main/java/org/opensearch/painless/PainlessScriptEngine.java index 5067df7063437..2ab1caf52c754 100644 --- a/modules/lang-painless/src/main/java/org/opensearch/painless/PainlessScriptEngine.java +++ b/modules/lang-painless/src/main/java/org/opensearch/painless/PainlessScriptEngine.java @@ -90,10 +90,12 @@ public PainlessScriptEngine(Settings settings, Map, List, Compiler> contextsToCompilers = new HashMap<>(); Map, PainlessLookup> contextsToLookups = new HashMap<>(); + Map, PainlessLookup> allowlistsToLookups = new HashMap<>(); for (Map.Entry, List> entry : contexts.entrySet()) { ScriptContext context = entry.getKey(); - PainlessLookup lookup = PainlessLookupBuilder.buildFromAllowlists(entry.getValue()); + List allowlists = List.copyOf(entry.getValue()); + PainlessLookup lookup = allowlistsToLookups.computeIfAbsent(allowlists, PainlessLookupBuilder::buildFromAllowlists); contextsToCompilers.put( context, new Compiler(context.instanceClazz, context.factoryClazz, context.statefulFactoryClazz, lookup) diff --git a/modules/lang-painless/src/main/java/org/opensearch/painless/lookup/PainlessLookupBuilder.java b/modules/lang-painless/src/main/java/org/opensearch/painless/lookup/PainlessLookupBuilder.java index 4c6910d16f8e6..e4a118528b999 100644 --- a/modules/lang-painless/src/main/java/org/opensearch/painless/lookup/PainlessLookupBuilder.java +++ b/modules/lang-painless/src/main/java/org/opensearch/painless/lookup/PainlessLookupBuilder.java @@ -65,9 +65,11 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.regex.Pattern; import static org.opensearch.painless.WriterConstants.DEF_TO_B_BYTE_IMPLICIT; @@ -1925,20 +1927,23 @@ public PainlessLookup build() { classesToPainlessClasses.put(painlessClassBuilderEntry.getKey(), painlessClassBuilderEntry.getValue().build()); } - if (javaClassNamesToClasses.values().containsAll(canonicalClassNamesToClasses.values()) == false) { + Set> javaClasses = new HashSet<>(javaClassNamesToClasses.values()); + Set> canonicalClasses = new HashSet<>(canonicalClassNamesToClasses.values()); + Set> painlessClasses = classesToPainlessClasses.keySet(); + + if (javaClasses.containsAll(canonicalClasses) == false) { throw new IllegalArgumentException( "the values of java class names to classes " + "must be a superset of the values of canonical class names to classes" ); } - if (javaClassNamesToClasses.values().containsAll(classesToPainlessClasses.keySet()) == false) { + if (javaClasses.containsAll(painlessClasses) == false) { throw new IllegalArgumentException( "the values of java class names to classes " + "must be a superset of the keys of classes to painless classes" ); } - if (canonicalClassNamesToClasses.values().containsAll(classesToPainlessClasses.keySet()) == false - || classesToPainlessClasses.keySet().containsAll(canonicalClassNamesToClasses.values()) == false) { + if (canonicalClasses.equals(painlessClasses) == false) { throw new IllegalArgumentException( "the values of canonical class names to classes " + "must have the same classes as the keys of classes to painless classes" );