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

Painless: Add Bindings #33042

Merged
merged 127 commits into from
Aug 29, 2018
Merged
Show file tree
Hide file tree
Changes from 123 commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
1419751
Parially added constructor.
jdconrad Jul 26, 2018
6469598
Add method type to method.
jdconrad Jul 27, 2018
54b8992
Merge branch 'master' into clean18
jdconrad Jul 27, 2018
8581deb
Merge branch 'clean16' into clean19
jdconrad Jul 27, 2018
641c383
Add PainlessConstructor.
jdconrad Jul 27, 2018
5b449d8
Clean up method.
jdconrad Jul 27, 2018
3c5db32
Merge branch 'master' into clean19
jdconrad Jul 27, 2018
c19b95d
Merge branch 'clean19' into clean20
jdconrad Jul 27, 2018
266a92d
Fixes.
jdconrad Jul 27, 2018
2875c48
Clean up fields.
jdconrad Jul 27, 2018
3f17455
Merge branch 'master' into clean19
jdconrad Jul 30, 2018
b9299d6
Merge branch 'clean19' into clean20
jdconrad Jul 30, 2018
aa833d9
Merge branch 'clean20' into clean21
jdconrad Jul 30, 2018
0c9c174
Reponse to PR comments.
jdconrad Jul 30, 2018
683361a
Merge branch 'clean19' into clean20
jdconrad Jul 30, 2018
6757987
Merge branch 'clean20' into clean21
jdconrad Jul 30, 2018
ccabb90
Merge branch 'master' into clean19
jdconrad Jul 30, 2018
55004f1
Merge branch 'clean19' into clean20
jdconrad Jul 30, 2018
9ca9381
Merge branch 'master' into clean20
jdconrad Jul 31, 2018
f379f2d
Merge branch 'clean20' into clean21
jdconrad Jul 31, 2018
98995f2
Start to clean up PainlessLookup.
jdconrad Jul 31, 2018
8bd9a28
Complete method lookup.
jdconrad Jul 31, 2018
6eaca81
Add lookup constructor.
jdconrad Jul 31, 2018
aab122a
Add field lookup.
jdconrad Jul 31, 2018
509e607
Merge branch 'master' into clean20
jdconrad Jul 31, 2018
aff5c3e
Reponse to PR comments.
jdconrad Jul 31, 2018
dbc3e27
Merge branch 'clean20' into clean21
jdconrad Jul 31, 2018
43d5e49
Merge branch 'clean21' into clean22
jdconrad Jul 31, 2018
dfa6de1
Merge branch 'master' into clean20
jdconrad Jul 31, 2018
36f41af
Merge branch 'clean20' into clean21
jdconrad Jul 31, 2018
2265836
Merge branch 'clean21' into clean22
jdconrad Jul 31, 2018
57e2a46
Add local methods to def bootstrap for consistency in look ups.
jdconrad Aug 1, 2018
bd2d854
Merge branch 'master' into clean21
jdconrad Aug 1, 2018
7187e4f
Merge branch 'master' into clean21
jdconrad Aug 1, 2018
69da907
Merge branch 'clean21' into clean22
jdconrad Aug 1, 2018
eb3bb9f
Merge branch 'clean22' into clean24
jdconrad Aug 1, 2018
4da7113
Add FunctionReference.
jdconrad Aug 1, 2018
1d8b547
Progress.
jdconrad Aug 1, 2018
e51f3df
Progress.
jdconrad Aug 1, 2018
a082624
Progress.
jdconrad Aug 1, 2018
89e936e
Fix.
jdconrad Aug 1, 2018
cf430a9
Progress.
jdconrad Aug 1, 2018
c4e8357
Large clean up of function reference.
jdconrad Aug 1, 2018
bde26b4
A bit more clean up.
jdconrad Aug 1, 2018
b3ed1b7
Merge branch 'master' into clean22
jdconrad Aug 1, 2018
264f6a4
Merge branch 'clean22' into clean24
jdconrad Aug 1, 2018
2cf04ec
Merge branch 'clean24' into clean25
jdconrad Aug 1, 2018
02ab981
Move runtime method lookup to PainlessLookup.
jdconrad Aug 1, 2018
551dc4e
Add getter/setter lookup methods to PainlessLookup.
jdconrad Aug 1, 2018
c1d9d25
Rename.
jdconrad Aug 1, 2018
73bfbdf
Mechanical change to rename variables in PainlessCast.
jdconrad Aug 2, 2018
581f359
Clean up whitelist names.
jdconrad Aug 2, 2018
87820b9
Rename only_fqn to no_import.
jdconrad Aug 2, 2018
4255c3c
Merge branch 'master' into clean22
jdconrad Aug 2, 2018
9d5f02f
Remove unnecessary sorted classes list.
jdconrad Aug 2, 2018
a255273
Merge branch 'clean22' into clean24
jdconrad Aug 2, 2018
4dbb100
Merge branch 'clean24' into clean25
jdconrad Aug 2, 2018
9609b45
Merge branch 'clean25' into clean26
jdconrad Aug 2, 2018
f27f954
Merge branch 'clean26' into clean27
jdconrad Aug 2, 2018
172df36
Merge branch 'clean27' into clean28
jdconrad Aug 2, 2018
8d8cce4
Merge branch 'clean28' into clean29
jdconrad Aug 2, 2018
12b66d8
Special case def.
jdconrad Aug 2, 2018
64933d1
Merge branch 'master' into clean22
jdconrad Aug 2, 2018
61737be
Merge branch 'clean22' into clean24
jdconrad Aug 2, 2018
67f4140
Merge branch 'clean24' into clean25
jdconrad Aug 2, 2018
8471f6b
Merge branch 'clean25' into clean26
jdconrad Aug 2, 2018
61946df
Merge branch 'clean26' into clean27
jdconrad Aug 2, 2018
ef3356a
Merge branch 'clean27' into clean28
jdconrad Aug 2, 2018
eb20b67
Merge branch 'clean28' into clean29
jdconrad Aug 2, 2018
03f68e6
Merge branch 'clean29' into clean30
jdconrad Aug 2, 2018
d7d0292
Remove extraneous line.
jdconrad Aug 2, 2018
aac6d88
Change Object to Map.
jdconrad Aug 2, 2018
4051638
Fix import.
jdconrad Aug 2, 2018
b65f459
Merge branch 'master' into clean24
jdconrad Aug 6, 2018
f071c78
Merge branch 'clean24' into clean25
jdconrad Aug 6, 2018
8e2a6af
Merge branch 'master' into clean25
jdconrad Aug 6, 2018
9921693
Merge branch 'clean25' into clean26
jdconrad Aug 6, 2018
c42e64e
Merge branch 'clean26' into clean27
jdconrad Aug 6, 2018
6e5e7ad
Merge branch 'clean27' into clean28
jdconrad Aug 6, 2018
78f70b6
Merge branch 'clean28' into clean29
jdconrad Aug 6, 2018
6b17a51
Merge branch 'clean29' into clean30
jdconrad Aug 6, 2018
af80f8e
Merge branch 'master' into clean25
jdconrad Aug 7, 2018
0b8ebdf
Fix formatting.
jdconrad Aug 7, 2018
b7812d6
Add FunctionRef back.
jdconrad Aug 7, 2018
c7ebe54
Remove extraneous character.
jdconrad Aug 7, 2018
28f6e60
Merge branch 'master' into clean25
jdconrad Aug 7, 2018
b98030a
Merge branch 'clean25' into clean26
jdconrad Aug 7, 2018
fc578ed
Merge branch 'master' into clean26
jdconrad Aug 7, 2018
ab9a805
Merge branch 'clean26' into clean27
jdconrad Aug 7, 2018
058c988
Merge branch 'clean27' into clean28
jdconrad Aug 7, 2018
4ebb939
Merge branch 'clean28' into clean29
jdconrad Aug 7, 2018
128f668
Merge branch 'clean29' into clean30
jdconrad Aug 7, 2018
1d3d2fc
Merge branch 'master' into clean26
jdconrad Aug 8, 2018
804f529
Return null instead of throwing exceptions for all methods in
jdconrad Aug 8, 2018
973c1b2
Merge branch 'master' into clean26
jdconrad Aug 8, 2018
f05f3d9
Merge branch 'clean26' into clean27
jdconrad Aug 8, 2018
a1a166b
Merge branch 'clean27' into clean28
jdconrad Aug 8, 2018
a5a0070
Merge branch 'clean28' into clean29
jdconrad Aug 8, 2018
ce8de87
Merge branch 'clean29' into clean30
jdconrad Aug 9, 2018
4240f75
Merge branch 'master' into clean27
jdconrad Aug 9, 2018
1939f16
Merge branch 'clean27' into clean28
jdconrad Aug 9, 2018
3f2cda7
Merge branch 'clean28' into clean29
jdconrad Aug 9, 2018
6077300
Merge branch 'clean29' into clean30
jdconrad Aug 9, 2018
e617201
Merge branch 'master' into clean27
jdconrad Aug 10, 2018
0cbe7c5
Merge branch 'clean27' into clean28
jdconrad Aug 10, 2018
8886264
Merge branch 'master' into clean28
jdconrad Aug 10, 2018
b6c6bd5
Merge branch 'clean28' into clean29
jdconrad Aug 10, 2018
1e25bc5
Merge branch 'clean29' into clean30
jdconrad Aug 10, 2018
b535937
Merge branch 'master' into clean29
jdconrad Aug 13, 2018
21d09f0
Merge branch 'master' into clean29
jdconrad Aug 14, 2018
68637a1
Merge branch 'clean29' into clean30
jdconrad Aug 14, 2018
fde19b3
Merge branch 'master' into clean30
jdconrad Aug 15, 2018
8836c20
Merge branch 'master' into clean30
jdconrad Aug 15, 2018
b5498e9
Some progress.
jdconrad Aug 15, 2018
87bc424
Merge branch 'master' into clean30
jdconrad Aug 16, 2018
9e57635
Merge branch 'clean30' into bindings
jdconrad Aug 16, 2018
5536cdb
Merge branch 'master' into bindings
jdconrad Aug 21, 2018
7fbea29
Completion of adding bindings to lookup.
jdconrad Aug 21, 2018
059cf4c
Added bindings.
jdconrad Aug 21, 2018
d04deb0
Merge branch 'master' into bindings
jdconrad Aug 23, 2018
352c897
Binding updated.
jdconrad Aug 23, 2018
ff26f71
Update bindings in whitelist to new format.
jdconrad Aug 23, 2018
869a23a
Merge branch 'master' into bindings
jdconrad Aug 23, 2018
a1298e2
Merge branch 'master' into bindings
jdconrad Aug 28, 2018
1fa435e
Response to PR comments.
jdconrad Aug 28, 2018
ee49cc8
Merge branch 'master' into bindings
jdconrad Aug 28, 2018
b4e2655
Merge branch 'master' into bindings
jdconrad Aug 29, 2018
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 @@ -61,9 +61,12 @@ public final class Whitelist {
/** The {@link List} of all the whitelisted Painless classes. */
public final List<WhitelistClass> whitelistClasses;

public final List<WhitelistBinding> whitelistBindings;

/** Standard constructor. All values must be not {@code null}. */
public Whitelist(ClassLoader classLoader, List<WhitelistClass> whitelistClasses) {
public Whitelist(ClassLoader classLoader, List<WhitelistClass> whitelistClasses, List<WhitelistBinding> whitelistBindings) {
this.classLoader = Objects.requireNonNull(classLoader);
this.whitelistClasses = Collections.unmodifiableList(Objects.requireNonNull(whitelistClasses));
this.whitelistBindings = Collections.unmodifiableList(Objects.requireNonNull(whitelistBindings));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.painless.spi;

import java.util.List;
import java.util.Objects;

/**
* A binding represents a static method call that stores state. Each binding must have exactly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to distinguish the binding here (whitelist binding) from a binding class? The latter is what most of your description is referring to (except for the first sentence?), but it is confusing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaned this up a bit.

* one public constructor and one public method excluding those inherited directly from {@link Object}.
* The canonical type name parameters provided must match those of the constructor and method combined.
* The constructor for a binding will be called when the binding is called for the first time at which
* point state may be stored for the arguments passed into the constructor. The method for a binding
* will be called each time the binding is called and may use the previously stored state.
*/
public class WhitelistBinding {

/** Information about where this constructor was whitelisted from. */
public final String origin;

/** The Java class name this binding represents. */
public final String targetJavaClassName;

/** The method name for this binding. */
public final String methodName;

/**
* The canonical type name for the return type.
*/
public final String returnCanonicalTypeName;

/**
* A {@link List} of {@link String}s that are the Painless type names for the parameters of the
* constructor which can be used to look up the Java constructor through reflection.
*/
public final List<String> canonicalTypeNameParameters;

/** Standard constructor. All values must be not {@code null}. */
public WhitelistBinding(String origin, String targetJavaClassName,
String methodName, String returnCanonicalTypeName, List<String> canonicalTypeNameParameters) {

this.origin = Objects.requireNonNull(origin);
this.targetJavaClassName = Objects.requireNonNull(targetJavaClassName);

this.methodName = Objects.requireNonNull(methodName);
this.returnCanonicalTypeName = Objects.requireNonNull(returnCanonicalTypeName);
this.canonicalTypeNameParameters = Objects.requireNonNull(canonicalTypeNameParameters);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ public final class WhitelistClass {

/** Standard constructor. All values must be not {@code null}. */
public WhitelistClass(String origin, String javaClassName, boolean noImport,
List<WhitelistConstructor> whitelistConstructors,
List<WhitelistMethod> whitelistMethods,
List<WhitelistField> whitelistFields) {
List<WhitelistConstructor> whitelistConstructors, List<WhitelistMethod> whitelistMethods, List<WhitelistField> whitelistFields)
{

this.origin = Objects.requireNonNull(origin);
this.javaClassName = Objects.requireNonNull(javaClassName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public final class WhitelistLoader {
*/
public static Whitelist loadFromResourceFiles(Class<?> resource, String... filepaths) {
List<WhitelistClass> whitelistClasses = new ArrayList<>();
List<WhitelistBinding> whitelistBindings = new ArrayList<>();

// Execute a single pass through the whitelist text files. This will gather all the
// constructors, methods, augmented methods, and fields for each whitelisted class.
Expand All @@ -141,8 +142,9 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep
int number = -1;

try (LineNumberReader reader = new LineNumberReader(
new InputStreamReader(resource.getResourceAsStream(filepath), StandardCharsets.UTF_8))) {
new InputStreamReader(resource.getResourceAsStream(filepath), StandardCharsets.UTF_8))) {

String parseType = null;
String whitelistClassOrigin = null;
String javaClassName = null;
boolean noImport = false;
Expand All @@ -165,7 +167,11 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep
// Ensure the final token of the line is '{'.
if (line.endsWith("{") == false) {
throw new IllegalArgumentException(
"invalid class definition: failed to parse class opening bracket [" + line + "]");
"invalid class definition: failed to parse class opening bracket [" + line + "]");
}

if (parseType != null) {
throw new IllegalArgumentException("invalid definition: cannot embed class definition [" + line + "]");
}

// Parse the Java class name.
Expand All @@ -178,41 +184,125 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep
throw new IllegalArgumentException("invalid class definition: failed to parse class name [" + line + "]");
}

parseType = "class";
whitelistClassOrigin = "[" + filepath + "]:[" + number + "]";
javaClassName = tokens[0];

// Reset all the constructors, methods, and fields to support a new class.
whitelistConstructors = new ArrayList<>();
whitelistMethods = new ArrayList<>();
whitelistFields = new ArrayList<>();
} else if (line.startsWith("static ")) {
// Ensure the final token of the line is '{'.
if (line.endsWith("{") == false) {
throw new IllegalArgumentException(
"invalid class definition: failed to parse class opening bracket [" + line + "]");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the message here indicate "static" opening bracket, not class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}

// Handle the end of a class, by creating a new WhitelistClass with all the previously gathered
// constructors, methods, augmented methods, and fields, and adding it to the list of whitelisted classes.
if (parseType != null) {
throw new IllegalArgumentException("invalid definition: cannot embed static definition [" + line + "]");
}

parseType = "static";

// Handle the end of a definition and reset all previously gathered values.
// Expects the following format: '}' '\n'
} else if (line.equals("}")) {
if (javaClassName == null) {
throw new IllegalArgumentException("invalid class definition: extraneous closing bracket");
if (parseType == null) {
throw new IllegalArgumentException("invalid definition: extraneous closing bracket");
}

whitelistClasses.add(new WhitelistClass(whitelistClassOrigin, javaClassName, noImport,
whitelistConstructors, whitelistMethods, whitelistFields));
// Create a new WhitelistClass with all the previously gathered constructors, methods,
// augmented methods, and fields, and add it to the list of whitelisted classes.
if ("class".equals(parseType)) {
whitelistClasses.add(new WhitelistClass(whitelistClassOrigin, javaClassName, noImport,
whitelistConstructors, whitelistMethods, whitelistFields));

whitelistClassOrigin = null;
javaClassName = null;
noImport = false;
whitelistConstructors = null;
whitelistMethods = null;
whitelistFields = null;
}

// Set all the variables to null to ensure a new class definition is found before other parsable values.
whitelistClassOrigin = null;
javaClassName = null;
noImport = false;
whitelistConstructors = null;
whitelistMethods = null;
whitelistFields = null;
// Reset the parseType.
parseType = null;

// Handle all other valid cases.
} else {
// Handle static definition types.
// Expects the following format: ID ID '(' ( ID ( ',' ID )* )? ')' 'bound_to' ID '\n'
} else if ("static".equals(parseType)) {
// Mark the origin of this parsable object.
String origin = "[" + filepath + "]:[" + number + "]";

// Parse the tokens prior to the method parameters.
int parameterStartIndex = line.indexOf('(');

if (parameterStartIndex == -1) {
throw new IllegalArgumentException(
"illegal static definition: start of method parameters not found [" + line + "]");
}

String[] tokens = line.substring(0, parameterStartIndex).trim().split("\\s+");

String methodName;

// Based on the number of tokens, look up the Java method name.
if (tokens.length == 2) {
methodName = tokens[1];
} else {
throw new IllegalArgumentException("invalid method definition: unexpected format [" + line + "]");
}

String returnCanonicalTypeName = tokens[0];

// Parse the method parameters.
int parameterEndIndex = line.indexOf(')');

if (parameterEndIndex == -1) {
throw new IllegalArgumentException(
"illegal static definition: end of method parameters not found [" + line + "]");
}

String[] canonicalTypeNameParameters =
line.substring(parameterStartIndex + 1, parameterEndIndex).replaceAll("\\s+", "").split(",");

// Handle the case for a method with no parameters.
if ("".equals(canonicalTypeNameParameters[0])) {
canonicalTypeNameParameters = new String[0];
}

// Parse the static type and class.
tokens = line.substring(parameterEndIndex + 1).trim().split("\\s+");

String staticType;
String targetJavaClassName;

// Based on the number of tokens, look up the type and class.
if (tokens.length == 2) {
staticType = tokens[0];
targetJavaClassName = tokens[1];
} else {
throw new IllegalArgumentException("invalid static definition: unexpected format [" + line + "]");
}

// Check the static type is valid.
if ("bound_to".equals(staticType) == false) {
throw new IllegalArgumentException(
"invalid static definition: unexpected static type [" + staticType + "] [" + line + "]");
}

whitelistBindings.add(new WhitelistBinding(origin, targetJavaClassName,
methodName, returnCanonicalTypeName, Arrays.asList(canonicalTypeNameParameters)));

// Handle class definition types.
} else if ("class".equals(parseType)) {
// Mark the origin of this parsable object.
String origin = "[" + filepath + "]:[" + number + "]";

// Ensure we have a defined class before adding any constructors, methods, augmented methods, or fields.
if (javaClassName == null) {
throw new IllegalArgumentException("invalid object definition: expected a class name [" + line + "]");
if (parseType == null) {
throw new IllegalArgumentException("invalid definition: expected one of ['class', 'static'] [" + line + "]");
}

// Handle the case for a constructor definition.
Expand All @@ -221,7 +311,7 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep
// Ensure the final token of the line is ')'.
if (line.endsWith(")") == false) {
throw new IllegalArgumentException(
"invalid constructor definition: expected a closing parenthesis [" + line + "]");
"invalid constructor definition: expected a closing parenthesis [" + line + "]");
}

// Parse the constructor parameters.
Expand All @@ -234,34 +324,34 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep

whitelistConstructors.add(new WhitelistConstructor(origin, Arrays.asList(tokens)));

// Handle the case for a method or augmented method definition.
// Expects the following format: ID ID? ID '(' ( ID ( ',' ID )* )? ')' '\n'
// Handle the case for a method or augmented method definition.
// Expects the following format: ID ID? ID '(' ( ID ( ',' ID )* )? ')' '\n'
} else if (line.contains("(")) {
// Ensure the final token of the line is ')'.
if (line.endsWith(")") == false) {
throw new IllegalArgumentException(
"invalid method definition: expected a closing parenthesis [" + line + "]");
"invalid method definition: expected a closing parenthesis [" + line + "]");
}

// Parse the tokens prior to the method parameters.
int parameterIndex = line.indexOf('(');
String[] tokens = line.trim().substring(0, parameterIndex).split("\\s+");
String[] tokens = line.substring(0, parameterIndex).trim().split("\\s+");

String javaMethodName;
String methodName;
String javaAugmentedClassName;

// Based on the number of tokens, look up the Java method name and if provided the Java augmented class.
if (tokens.length == 2) {
javaMethodName = tokens[1];
methodName = tokens[1];
javaAugmentedClassName = null;
} else if (tokens.length == 3) {
javaMethodName = tokens[2];
methodName = tokens[2];
javaAugmentedClassName = tokens[1];
} else {
throw new IllegalArgumentException("invalid method definition: unexpected format [" + line + "]");
}

String painlessReturnTypeName = tokens[0];
String returnCanonicalTypeName = tokens[0];

// Parse the method parameters.
tokens = line.substring(parameterIndex + 1, line.length() - 1).replaceAll("\\s+", "").split(",");
Expand All @@ -271,11 +361,11 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep
tokens = new String[0];
}

whitelistMethods.add(new WhitelistMethod(origin, javaAugmentedClassName, javaMethodName,
painlessReturnTypeName, Arrays.asList(tokens)));
whitelistMethods.add(new WhitelistMethod(origin, javaAugmentedClassName, methodName,
returnCanonicalTypeName, Arrays.asList(tokens)));

// Handle the case for a field definition.
// Expects the following format: ID ID '\n'
// Handle the case for a field definition.
// Expects the following format: ID ID '\n'
} else {
// Parse the field tokens.
String[] tokens = line.split("\\s+");
Expand All @@ -287,20 +377,23 @@ public static Whitelist loadFromResourceFiles(Class<?> resource, String... filep

whitelistFields.add(new WhitelistField(origin, tokens[1], tokens[0]));
}
} else {
throw new IllegalArgumentException("invalid definition: unable to parse line [" + line + "]");
}
}

// Ensure all classes end with a '}' token before the end of the file.
if (javaClassName != null) {
throw new IllegalArgumentException("invalid class definition: expected closing bracket");
throw new IllegalArgumentException("invalid definition: expected closing bracket");
}
} catch (Exception exception) {
throw new RuntimeException("error in [" + filepath + "] at line [" + number + "]", exception);
}
}

ClassLoader loader = AccessController.doPrivileged((PrivilegedAction<ClassLoader>)resource::getClassLoader);

return new Whitelist(loader, whitelistClasses);
return new Whitelist(loader, whitelistClasses, whitelistBindings);
}

private WhitelistLoader() {}
Expand Down
Loading