Merge branch 'master' into index-lifecycle
This commit is contained in:
commit
573a9e6443
|
@ -25,8 +25,8 @@ plugins {
|
|||
|
||||
group = 'org.elasticsearch.gradle'
|
||||
|
||||
if (GradleVersion.current() < GradleVersion.version('3.3')) {
|
||||
throw new GradleException('Gradle 3.3+ is required to build elasticsearch')
|
||||
if (GradleVersion.current() < GradleVersion.version('4.9')) {
|
||||
throw new GradleException('Gradle 4.9+ is required to build elasticsearch')
|
||||
}
|
||||
|
||||
if (JavaVersion.current() < JavaVersion.VERSION_1_8) {
|
||||
|
|
|
@ -67,6 +67,9 @@ class BuildPlugin implements Plugin<Project> {
|
|||
+ 'elasticearch.standalone-rest-test, and elasticsearch.build '
|
||||
+ 'are mutually exclusive')
|
||||
}
|
||||
if (GradleVersion.current() < GradleVersion.version('4.9')) {
|
||||
throw new GradleException('Gradle 4.9+ is required to use elasticsearch.build plugin')
|
||||
}
|
||||
project.pluginManager.apply('java')
|
||||
project.pluginManager.apply('carrotsearch.randomized-testing')
|
||||
// these plugins add lots of info to our jars
|
||||
|
@ -750,7 +753,6 @@ class BuildPlugin implements Plugin<Project> {
|
|||
systemProperty 'tests.task', path
|
||||
systemProperty 'tests.security.manager', 'true'
|
||||
systemProperty 'jna.nosys', 'true'
|
||||
systemProperty 'es.scripting.exception_for_missing_value', 'true'
|
||||
// TODO: remove setting logging level via system property
|
||||
systemProperty 'tests.logger.level', 'WARN'
|
||||
for (Map.Entry<String, String> property : System.properties.entrySet()) {
|
||||
|
|
|
@ -123,21 +123,8 @@ GET hockey/_search
|
|||
[float]
|
||||
===== Missing values
|
||||
|
||||
If you request the value from a field `field` that isn’t in
|
||||
the document, `doc['field'].value` for this document returns:
|
||||
|
||||
- `0` if a `field` has a numeric datatype (long, double etc.)
|
||||
- `false` is a `field` has a boolean datatype
|
||||
- epoch date if a `field` has a date datatype
|
||||
- `null` if a `field` has a string datatype
|
||||
- `null` if a `field` has a geo datatype
|
||||
- `""` if a `field` has a binary datatype
|
||||
|
||||
IMPORTANT: Starting in 7.0, `doc['field'].value` throws an exception if
|
||||
the field is missing in a document. To enable this behavior now,
|
||||
set a {ref}/jvm-options.html[`jvm.option`]
|
||||
`-Des.scripting.exception_for_missing_value=true` on a node. If you do not enable
|
||||
this behavior, a deprecation warning is logged on start up.
|
||||
`doc['field'].value` throws an exception if
|
||||
the field is missing in a document.
|
||||
|
||||
To check if a document is missing a value, you can call
|
||||
`doc['field'].size() == 0`.
|
||||
|
|
|
@ -466,8 +466,8 @@ public final class AnalyzerCaster {
|
|||
return PainlessCast.standard(actual, expected, explicit);
|
||||
} else {
|
||||
throw location.createError(new ClassCastException("Cannot cast from " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(actual) + "] to " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(actual) + "] to " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "]."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ public final class Def {
|
|||
nestedType,
|
||||
0,
|
||||
DefBootstrap.REFERENCE,
|
||||
PainlessLookupUtility.anyTypeToPainlessTypeName(interfaceType));
|
||||
PainlessLookupUtility.typeToCanonicalTypeName(interfaceType));
|
||||
filter = nested.dynamicInvoker();
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
|
@ -334,7 +334,7 @@ public final class Def {
|
|||
int arity = interfaceMethod.arguments.size();
|
||||
PainlessMethod implMethod = lookupMethodInternal(painlessLookup, receiverClass, name, arity);
|
||||
return lookupReferenceInternal(painlessLookup, methodHandlesLookup, interfaceType,
|
||||
PainlessLookupUtility.anyTypeToPainlessTypeName(implMethod.target), implMethod.name, receiverClass);
|
||||
PainlessLookupUtility.typeToCanonicalTypeName(implMethod.target), implMethod.name, receiverClass);
|
||||
}
|
||||
|
||||
/** Returns a method handle to an implementation of clazz, given method reference signature. */
|
||||
|
@ -347,7 +347,7 @@ public final class Def {
|
|||
PainlessMethod interfaceMethod = painlessLookup.getPainlessStructFromJavaClass(clazz).functionalMethod;
|
||||
if (interfaceMethod == null) {
|
||||
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
|
||||
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(clazz) + "], not a functional interface");
|
||||
"to [" + PainlessLookupUtility.typeToCanonicalTypeName(clazz) + "], not a functional interface");
|
||||
}
|
||||
int arity = interfaceMethod.arguments.size() + captures.length;
|
||||
final MethodHandle handle;
|
||||
|
|
|
@ -168,7 +168,7 @@ public class FunctionRef {
|
|||
PainlessMethod method = painlessLookup.getPainlessStructFromJavaClass(expected).functionalMethod;
|
||||
if (method == null) {
|
||||
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
|
||||
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface");
|
||||
"to [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface");
|
||||
}
|
||||
|
||||
// lookup requested method
|
||||
|
|
|
@ -292,7 +292,7 @@ public final class Locals {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("Variable[type=").append(PainlessLookupUtility.anyTypeToPainlessTypeName(clazz));
|
||||
b.append("Variable[type=").append(PainlessLookupUtility.typeToCanonicalTypeName(clazz));
|
||||
b.append(",name=").append(name);
|
||||
b.append(",slot=").append(slot);
|
||||
if (readonly) {
|
||||
|
|
|
@ -183,7 +183,7 @@ public class ScriptClassInfo {
|
|||
|
||||
private static Class<?> definitionTypeForClass(PainlessLookup painlessLookup, Class<?> type,
|
||||
Function<Class<?>, String> unknownErrorMessageSource) {
|
||||
type = PainlessLookupUtility.javaObjectTypeToPainlessDefType(type);
|
||||
type = PainlessLookupUtility.javaTypeToType(type);
|
||||
Class<?> componentType = type;
|
||||
|
||||
while (componentType.isArray()) {
|
||||
|
|
|
@ -54,6 +54,6 @@ public final class PainlessLookup {
|
|||
}
|
||||
|
||||
public Class<?> getJavaClassFromPainlessType(String painlessType) {
|
||||
return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessType, painlessTypesToJavaClasses);
|
||||
return PainlessLookupUtility.canonicalTypeNameToType(painlessType, painlessTypesToJavaClasses);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.lang.invoke.MethodHandle;
|
|||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -39,22 +38,21 @@ import java.util.Objects;
|
|||
import java.util.Stack;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.elasticsearch.painless.lookup.PainlessLookupUtility.DEF_PAINLESS_CLASS_NAME;
|
||||
import static org.elasticsearch.painless.lookup.PainlessLookupUtility.anyTypeNameToPainlessTypeName;
|
||||
import static org.elasticsearch.painless.lookup.PainlessLookupUtility.DEF_TYPE_NAME;
|
||||
import static org.elasticsearch.painless.lookup.PainlessLookupUtility.buildPainlessMethodKey;
|
||||
|
||||
public class PainlessLookupBuilder {
|
||||
|
||||
private static class PainlessMethodCacheKey {
|
||||
|
||||
private final Class<?> javaClass;
|
||||
private final Class<?> targetType;
|
||||
private final String methodName;
|
||||
private final List<Class<?>> painlessTypeParameters;
|
||||
private final List<Class<?>> typeParameters;
|
||||
|
||||
private PainlessMethodCacheKey(Class<?> javaClass, String methodName, List<Class<?>> painlessTypeParameters) {
|
||||
this.javaClass = javaClass;
|
||||
private PainlessMethodCacheKey(Class<?> targetType, String methodName, List<Class<?>> typeParameters) {
|
||||
this.targetType = targetType;
|
||||
this.methodName = methodName;
|
||||
this.painlessTypeParameters = Collections.unmodifiableList(painlessTypeParameters);
|
||||
this.typeParameters = Collections.unmodifiableList(typeParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,27 +67,27 @@ public class PainlessLookupBuilder {
|
|||
|
||||
PainlessMethodCacheKey that = (PainlessMethodCacheKey)object;
|
||||
|
||||
return Objects.equals(javaClass, that.javaClass) &&
|
||||
return Objects.equals(targetType, that.targetType) &&
|
||||
Objects.equals(methodName, that.methodName) &&
|
||||
Objects.equals(painlessTypeParameters, that.painlessTypeParameters);
|
||||
Objects.equals(typeParameters, that.typeParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(javaClass, methodName, painlessTypeParameters);
|
||||
return Objects.hash(targetType, methodName, typeParameters);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PainlessFieldCacheKey {
|
||||
|
||||
private final Class<?> javaClass;
|
||||
private final Class<?> targetType;
|
||||
private final String fieldName;
|
||||
private final Class<?> painlessType;
|
||||
private final Class<?> typeParameter;
|
||||
|
||||
private PainlessFieldCacheKey(Class<?> javaClass, String fieldName, Class<?> painlessType) {
|
||||
this.javaClass = javaClass;
|
||||
private PainlessFieldCacheKey(Class<?> targetType, String fieldName, Class<?> typeParameter) {
|
||||
this.targetType = targetType;
|
||||
this.fieldName = fieldName;
|
||||
this.painlessType = painlessType;
|
||||
this.typeParameter = typeParameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,14 +102,14 @@ public class PainlessLookupBuilder {
|
|||
|
||||
PainlessFieldCacheKey that = (PainlessFieldCacheKey) object;
|
||||
|
||||
return Objects.equals(javaClass, that.javaClass) &&
|
||||
Objects.equals(fieldName, that.fieldName) &&
|
||||
Objects.equals(painlessType, that.painlessType);
|
||||
return Objects.equals(targetType, that.targetType) &&
|
||||
Objects.equals(fieldName, that.fieldName) &&
|
||||
Objects.equals(typeParameter, that.typeParameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(javaClass, fieldName, painlessType);
|
||||
return Objects.hash(targetType, fieldName, typeParameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,157 +120,115 @@ public class PainlessLookupBuilder {
|
|||
private static final Pattern METHOD_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][_a-zA-Z0-9]*$");
|
||||
private static final Pattern FIELD_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][_a-zA-Z0-9]*$");
|
||||
|
||||
private static String anyTypesArrayToCanonicalString(Class<?>[] anyTypesArray, boolean toPainlessTypes) {
|
||||
return anyTypesListToCanonicalString(Arrays.asList(anyTypesArray), toPainlessTypes);
|
||||
}
|
||||
|
||||
private static String anyTypesListToCanonicalString(List<Class<?>> anyTypesList, boolean toPainlessTypes) {
|
||||
StringBuilder anyTypesCanonicalStringBuilder = new StringBuilder("[");
|
||||
|
||||
int anyTypesSize = anyTypesList.size();
|
||||
int anyTypesIndex = 0;
|
||||
|
||||
for (Class<?> anyType : anyTypesList) {
|
||||
String anyTypeCanonicalName = anyType.getCanonicalName();
|
||||
|
||||
if (toPainlessTypes) {
|
||||
anyTypeCanonicalName = anyTypeNameToPainlessTypeName(anyTypeCanonicalName);
|
||||
}
|
||||
|
||||
anyTypesCanonicalStringBuilder.append(anyTypeCanonicalName);
|
||||
|
||||
if (++anyTypesIndex < anyTypesSize) {
|
||||
anyTypesCanonicalStringBuilder.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
anyTypesCanonicalStringBuilder.append("]");
|
||||
|
||||
return anyTypesCanonicalStringBuilder.toString();
|
||||
}
|
||||
|
||||
private final List<Whitelist> whitelists;
|
||||
|
||||
private final Map<String, Class<?>> painlessClassNamesToJavaClasses;
|
||||
private final Map<Class<?>, PainlessClassBuilder> javaClassesToPainlessClassBuilders;
|
||||
private final Map<String, Class<?>> canonicalClassNamesToClasses;
|
||||
private final Map<Class<?>, PainlessClassBuilder> classesToPainlessClasses;
|
||||
|
||||
public PainlessLookupBuilder(List<Whitelist> whitelists) {
|
||||
this.whitelists = whitelists;
|
||||
|
||||
painlessClassNamesToJavaClasses = new HashMap<>();
|
||||
javaClassesToPainlessClassBuilders = new HashMap<>();
|
||||
canonicalClassNamesToClasses = new HashMap<>();
|
||||
classesToPainlessClasses = new HashMap<>();
|
||||
|
||||
painlessClassNamesToJavaClasses.put(DEF_PAINLESS_CLASS_NAME, def.class);
|
||||
javaClassesToPainlessClassBuilders.put(def.class,
|
||||
new PainlessClassBuilder(DEF_PAINLESS_CLASS_NAME, Object.class, Type.getType(Object.class)));
|
||||
canonicalClassNamesToClasses.put(DEF_TYPE_NAME, def.class);
|
||||
classesToPainlessClasses.put(def.class,
|
||||
new PainlessClassBuilder(DEF_TYPE_NAME, Object.class, Type.getType(Object.class)));
|
||||
}
|
||||
|
||||
private Class<?> painlessTypeNameToPainlessType(String painlessTypeName) {
|
||||
return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessTypeName, painlessClassNamesToJavaClasses);
|
||||
private Class<?> canonicalTypeNameToType(String canonicalTypeName) {
|
||||
return PainlessLookupUtility.canonicalTypeNameToType(canonicalTypeName, canonicalClassNamesToClasses);
|
||||
}
|
||||
|
||||
private void validatePainlessType(Class<?> painlessType) {
|
||||
PainlessLookupUtility.validatePainlessType(painlessType, javaClassesToPainlessClassBuilders.keySet());
|
||||
private void validateType(Class<?> type) {
|
||||
PainlessLookupUtility.validateType(type, classesToPainlessClasses.keySet());
|
||||
}
|
||||
|
||||
public void addPainlessClass(ClassLoader classLoader, String javaClassName, boolean importPainlessClassName) {
|
||||
public void addPainlessClass(ClassLoader classLoader, String javaClassName, boolean importClassName) {
|
||||
Objects.requireNonNull(classLoader);
|
||||
Objects.requireNonNull(javaClassName);
|
||||
|
||||
String painlessClassName = anyTypeNameToPainlessTypeName(javaClassName);
|
||||
Class<?> clazz;
|
||||
|
||||
if (CLASS_NAME_PATTERN.matcher(painlessClassName).matches() == false) {
|
||||
throw new IllegalArgumentException("invalid painless class name [" + painlessClassName + "]");
|
||||
}
|
||||
|
||||
String importedPainlessClassName = anyTypeNameToPainlessTypeName(javaClassName.substring(javaClassName.lastIndexOf('.') + 1));
|
||||
|
||||
Class<?> javaClass;
|
||||
|
||||
if ("void".equals(javaClassName)) javaClass = void.class;
|
||||
else if ("boolean".equals(javaClassName)) javaClass = boolean.class;
|
||||
else if ("byte".equals(javaClassName)) javaClass = byte.class;
|
||||
else if ("short".equals(javaClassName)) javaClass = short.class;
|
||||
else if ("char".equals(javaClassName)) javaClass = char.class;
|
||||
else if ("int".equals(javaClassName)) javaClass = int.class;
|
||||
else if ("long".equals(javaClassName)) javaClass = long.class;
|
||||
else if ("float".equals(javaClassName)) javaClass = float.class;
|
||||
else if ("double".equals(javaClassName)) javaClass = double.class;
|
||||
if ("void".equals(javaClassName)) clazz = void.class;
|
||||
else if ("boolean".equals(javaClassName)) clazz = boolean.class;
|
||||
else if ("byte".equals(javaClassName)) clazz = byte.class;
|
||||
else if ("short".equals(javaClassName)) clazz = short.class;
|
||||
else if ("char".equals(javaClassName)) clazz = char.class;
|
||||
else if ("int".equals(javaClassName)) clazz = int.class;
|
||||
else if ("long".equals(javaClassName)) clazz = long.class;
|
||||
else if ("float".equals(javaClassName)) clazz = float.class;
|
||||
else if ("double".equals(javaClassName)) clazz = double.class;
|
||||
else {
|
||||
try {
|
||||
javaClass = Class.forName(javaClassName, true, classLoader);
|
||||
|
||||
if (javaClass == def.class) {
|
||||
throw new IllegalArgumentException("cannot add reserved painless class [" + DEF_PAINLESS_CLASS_NAME + "]");
|
||||
}
|
||||
|
||||
if (javaClass.isArray()) {
|
||||
throw new IllegalArgumentException("cannot add an array type java class [" + javaClassName + "] as a painless class");
|
||||
}
|
||||
clazz = Class.forName(javaClassName, true, classLoader);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalArgumentException("java class [" + javaClassName + "] not found", cnfe);
|
||||
throw new IllegalArgumentException("class [" + javaClassName + "] not found", cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
addPainlessClass(painlessClassName, importedPainlessClassName, javaClass, importPainlessClassName);
|
||||
addPainlessClass(clazz, importClassName);
|
||||
}
|
||||
|
||||
public void addPainlessClass(Class<?> javaClass, boolean importPainlessClassName) {
|
||||
Objects.requireNonNull(javaClass);
|
||||
public void addPainlessClass(Class<?> clazz, boolean importClassName) {
|
||||
Objects.requireNonNull(clazz);
|
||||
|
||||
if (javaClass == def.class) {
|
||||
throw new IllegalArgumentException("cannot specify reserved painless class [" + DEF_PAINLESS_CLASS_NAME + "]");
|
||||
if (clazz == def.class) {
|
||||
throw new IllegalArgumentException("cannot add reserved class [" + DEF_TYPE_NAME + "]");
|
||||
}
|
||||
|
||||
String javaClassName = javaClass.getCanonicalName();
|
||||
String painlessClassName = anyTypeNameToPainlessTypeName(javaClassName);
|
||||
String importedPainlessClassName = anyTypeNameToPainlessTypeName(javaClassName.substring(javaClassName.lastIndexOf('.') + 1));
|
||||
String canonicalClassName = clazz.getCanonicalName();
|
||||
|
||||
addPainlessClass(painlessClassName, importedPainlessClassName, javaClass, importPainlessClassName);
|
||||
}
|
||||
if (clazz.isArray()) {
|
||||
throw new IllegalArgumentException("cannot add array type [" + canonicalClassName + "] as a class");
|
||||
}
|
||||
|
||||
private void addPainlessClass(
|
||||
String painlessClassName, String importedPainlessClassName, Class<?> javaClass, boolean importPainlessClassName) {
|
||||
PainlessClassBuilder existingPainlessClassBuilder = javaClassesToPainlessClassBuilders.get(javaClass);
|
||||
if (CLASS_NAME_PATTERN.matcher(canonicalClassName).matches() == false) {
|
||||
throw new IllegalArgumentException("invalid class name [" + canonicalClassName + "]");
|
||||
}
|
||||
|
||||
PainlessClassBuilder existingPainlessClassBuilder = classesToPainlessClasses.get(clazz);
|
||||
|
||||
if (existingPainlessClassBuilder == null) {
|
||||
PainlessClassBuilder painlessClassBuilder = new PainlessClassBuilder(painlessClassName, javaClass, Type.getType(javaClass));
|
||||
painlessClassNamesToJavaClasses.put(painlessClassName, javaClass);
|
||||
javaClassesToPainlessClassBuilders.put(javaClass, painlessClassBuilder);
|
||||
} else if (existingPainlessClassBuilder.clazz.equals(javaClass) == false) {
|
||||
throw new IllegalArgumentException("painless class [" + painlessClassName + "] illegally represents multiple java classes " +
|
||||
"[" + javaClass.getCanonicalName() + "] and [" + existingPainlessClassBuilder.clazz.getCanonicalName() + "]");
|
||||
PainlessClassBuilder painlessClassBuilder = new PainlessClassBuilder(canonicalClassName, clazz, Type.getType(clazz));
|
||||
|
||||
canonicalClassNamesToClasses.put(canonicalClassName, clazz);
|
||||
classesToPainlessClasses.put(clazz, painlessClassBuilder);
|
||||
} else if (existingPainlessClassBuilder.clazz.equals(clazz) == false) {
|
||||
throw new IllegalArgumentException("class [" + canonicalClassName + "] " +
|
||||
"cannot represent multiple java classes with the same name from different class loaders");
|
||||
}
|
||||
|
||||
if (painlessClassName.equals(importedPainlessClassName)) {
|
||||
if (importPainlessClassName == true) {
|
||||
throw new IllegalArgumentException(
|
||||
"must use only_fqn parameter on painless class [" + painlessClassName + "] with no package");
|
||||
String javaClassName = clazz.getName();
|
||||
String importedCanonicalClassName = javaClassName.substring(javaClassName.lastIndexOf('.') + 1).replace('$', '.');
|
||||
|
||||
if (canonicalClassName.equals(importedCanonicalClassName)) {
|
||||
if (importClassName == true) {
|
||||
throw new IllegalArgumentException("must use only_fqn parameter on class [" + canonicalClassName + "] with no package");
|
||||
}
|
||||
} else {
|
||||
Class<?> importedJavaClass = painlessClassNamesToJavaClasses.get(importedPainlessClassName);
|
||||
Class<?> importedPainlessType = canonicalClassNamesToClasses.get(importedCanonicalClassName);
|
||||
|
||||
if (importedJavaClass == null) {
|
||||
if (importPainlessClassName) {
|
||||
if (importedPainlessType == null) {
|
||||
if (importClassName) {
|
||||
if (existingPainlessClassBuilder != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"inconsistent only_fqn parameters found for painless class [" + painlessClassName + "]");
|
||||
"inconsistent only_fqn parameters found for painless type [" + canonicalClassName + "]");
|
||||
}
|
||||
|
||||
painlessClassNamesToJavaClasses.put(importedPainlessClassName, javaClass);
|
||||
canonicalClassNamesToClasses.put(importedCanonicalClassName, clazz);
|
||||
}
|
||||
} else if (importedJavaClass.equals(javaClass) == false) {
|
||||
throw new IllegalArgumentException("painless class [" + importedPainlessClassName + "] illegally represents multiple " +
|
||||
"java classes [" + javaClass.getCanonicalName() + "] and [" + importedJavaClass.getCanonicalName() + "]");
|
||||
} else if (importPainlessClassName == false) {
|
||||
throw new IllegalArgumentException(
|
||||
"inconsistent only_fqn parameters found for painless class [" + painlessClassName + "]");
|
||||
} else if (importedPainlessType.equals(clazz) == false) {
|
||||
throw new IllegalArgumentException("painless type [" + importedCanonicalClassName + "] illegally represents multiple " +
|
||||
"java types [" + clazz.getCanonicalName() + "] and [" + importedPainlessType.getCanonicalName() + "]");
|
||||
} else if (importClassName == false) {
|
||||
throw new IllegalArgumentException("inconsistent only_fqn parameters found for painless type [" + canonicalClassName + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addConstructor(String ownerStructName, WhitelistConstructor whitelistConstructor) {
|
||||
PainlessClassBuilder ownerStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(ownerStructName));
|
||||
PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(ownerStructName));
|
||||
|
||||
if (ownerStruct == null) {
|
||||
throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for constructor with " +
|
||||
|
@ -286,10 +242,10 @@ public class PainlessLookupBuilder {
|
|||
String painlessParameterTypeName = whitelistConstructor.painlessParameterTypeNames.get(parameterCount);
|
||||
|
||||
try {
|
||||
Class<?> painlessParameterClass = painlessTypeNameToPainlessType(painlessParameterTypeName);
|
||||
Class<?> painlessParameterClass = canonicalTypeNameToType(painlessParameterTypeName);
|
||||
|
||||
painlessParametersTypes.add(painlessParameterClass);
|
||||
javaClassParameters[parameterCount] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessParameterClass);
|
||||
javaClassParameters[parameterCount] = PainlessLookupUtility.typeToJavaType(painlessParameterClass);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new IllegalArgumentException("struct not defined for constructor parameter [" + painlessParameterTypeName + "] " +
|
||||
"with owner struct [" + ownerStructName + "] and constructor parameters " +
|
||||
|
@ -333,7 +289,7 @@ public class PainlessLookupBuilder {
|
|||
}
|
||||
|
||||
private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, WhitelistMethod whitelistMethod) {
|
||||
PainlessClassBuilder ownerStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(ownerStructName));
|
||||
PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(ownerStructName));
|
||||
|
||||
if (ownerStruct == null) {
|
||||
throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " +
|
||||
|
@ -372,11 +328,11 @@ public class PainlessLookupBuilder {
|
|||
String painlessParameterTypeName = whitelistMethod.painlessParameterTypeNames.get(parameterCount);
|
||||
|
||||
try {
|
||||
Class<?> painlessParameterClass = painlessTypeNameToPainlessType(painlessParameterTypeName);
|
||||
Class<?> painlessParameterClass = canonicalTypeNameToType(painlessParameterTypeName);
|
||||
|
||||
painlessParametersTypes.add(painlessParameterClass);
|
||||
javaClassParameters[parameterCount + augmentedOffset] =
|
||||
PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessParameterClass);
|
||||
PainlessLookupUtility.typeToJavaType(painlessParameterClass);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new IllegalArgumentException("struct not defined for method parameter [" + painlessParameterTypeName + "] " +
|
||||
"with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " +
|
||||
|
@ -398,14 +354,14 @@ public class PainlessLookupBuilder {
|
|||
Class<?> painlessReturnClass;
|
||||
|
||||
try {
|
||||
painlessReturnClass = painlessTypeNameToPainlessType(whitelistMethod.painlessReturnTypeName);
|
||||
painlessReturnClass = canonicalTypeNameToType(whitelistMethod.painlessReturnTypeName);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new IllegalArgumentException("struct not defined for return type [" + whitelistMethod.painlessReturnTypeName + "] " +
|
||||
"with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " +
|
||||
"and parameters " + whitelistMethod.painlessParameterTypeNames, iae);
|
||||
}
|
||||
|
||||
if (javaMethod.getReturnType() != PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessReturnClass)) {
|
||||
if (javaMethod.getReturnType() != PainlessLookupUtility.typeToJavaType(painlessReturnClass)) {
|
||||
throw new IllegalArgumentException("specified return type class [" + painlessReturnClass + "] " +
|
||||
"does not match the return type class [" + javaMethod.getReturnType() + "] for the " +
|
||||
"method with name [" + whitelistMethod.javaMethodName + "] " +
|
||||
|
@ -471,7 +427,7 @@ public class PainlessLookupBuilder {
|
|||
}
|
||||
|
||||
private void addField(String ownerStructName, WhitelistField whitelistField) {
|
||||
PainlessClassBuilder ownerStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(ownerStructName));
|
||||
PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(ownerStructName));
|
||||
|
||||
if (ownerStruct == null) {
|
||||
throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " +
|
||||
|
@ -495,7 +451,7 @@ public class PainlessLookupBuilder {
|
|||
Class<?> painlessFieldClass;
|
||||
|
||||
try {
|
||||
painlessFieldClass = painlessTypeNameToPainlessType(whitelistField.painlessFieldTypeName);
|
||||
painlessFieldClass = canonicalTypeNameToType(whitelistField.painlessFieldTypeName);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new IllegalArgumentException("struct not defined for return type [" + whitelistField.painlessFieldTypeName + "] " +
|
||||
"with owner struct [" + ownerStructName + "] and field with name [" + whitelistField.javaFieldName + "]", iae);
|
||||
|
@ -552,7 +508,7 @@ public class PainlessLookupBuilder {
|
|||
}
|
||||
|
||||
private void copyStruct(String struct, List<String> children) {
|
||||
final PainlessClassBuilder owner = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(struct));
|
||||
final PainlessClassBuilder owner = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(struct));
|
||||
|
||||
if (owner == null) {
|
||||
throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for copy.");
|
||||
|
@ -560,7 +516,7 @@ public class PainlessLookupBuilder {
|
|||
|
||||
for (int count = 0; count < children.size(); ++count) {
|
||||
final PainlessClassBuilder child =
|
||||
javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(children.get(count)));
|
||||
classesToPainlessClasses.get(canonicalClassNamesToClasses.get(children.get(count)));
|
||||
|
||||
if (child == null) {
|
||||
throw new IllegalArgumentException("Child struct [" + children.get(count) + "]" +
|
||||
|
@ -734,7 +690,7 @@ public class PainlessLookupBuilder {
|
|||
for (WhitelistClass whitelistStruct : whitelist.whitelistStructs) {
|
||||
String painlessTypeName = whitelistStruct.javaClassName.replace('$', '.');
|
||||
PainlessClassBuilder painlessStruct =
|
||||
javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(painlessTypeName));
|
||||
classesToPainlessClasses.get(canonicalClassNamesToClasses.get(painlessTypeName));
|
||||
|
||||
if (painlessStruct != null && painlessStruct.clazz.getName().equals(whitelistStruct.javaClassName) == false) {
|
||||
throw new IllegalArgumentException("struct [" + painlessStruct.name + "] cannot represent multiple classes " +
|
||||
|
@ -745,8 +701,8 @@ public class PainlessLookupBuilder {
|
|||
addPainlessClass(
|
||||
whitelist.javaClassLoader, whitelistStruct.javaClassName, whitelistStruct.onlyFQNJavaClassName == false);
|
||||
|
||||
painlessStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(painlessTypeName));
|
||||
javaClassesToPainlessClassBuilders.put(painlessStruct.clazz, painlessStruct);
|
||||
painlessStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(painlessTypeName));
|
||||
classesToPainlessClasses.put(painlessStruct.clazz, painlessStruct);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,8 +735,8 @@ public class PainlessLookupBuilder {
|
|||
|
||||
// goes through each Painless struct and determines the inheritance list,
|
||||
// and then adds all inherited types to the Painless struct's whitelist
|
||||
for (Class<?> javaClass : javaClassesToPainlessClassBuilders.keySet()) {
|
||||
PainlessClassBuilder painlessStruct = javaClassesToPainlessClassBuilders.get(javaClass);
|
||||
for (Class<?> javaClass : classesToPainlessClasses.keySet()) {
|
||||
PainlessClassBuilder painlessStruct = classesToPainlessClasses.get(javaClass);
|
||||
|
||||
List<String> painlessSuperStructs = new ArrayList<>();
|
||||
Class<?> javaSuperClass = painlessStruct.clazz.getSuperclass();
|
||||
|
@ -791,7 +747,7 @@ public class PainlessLookupBuilder {
|
|||
// adds super classes to the inheritance list
|
||||
if (javaSuperClass != null && javaSuperClass.isInterface() == false) {
|
||||
while (javaSuperClass != null) {
|
||||
PainlessClassBuilder painlessSuperStruct = javaClassesToPainlessClassBuilders.get(javaSuperClass);
|
||||
PainlessClassBuilder painlessSuperStruct = classesToPainlessClasses.get(javaSuperClass);
|
||||
|
||||
if (painlessSuperStruct != null) {
|
||||
painlessSuperStructs.add(painlessSuperStruct.name);
|
||||
|
@ -807,7 +763,7 @@ public class PainlessLookupBuilder {
|
|||
Class<?> javaInterfaceLookup = javaInteraceLookups.pop();
|
||||
|
||||
for (Class<?> javaSuperInterface : javaInterfaceLookup.getInterfaces()) {
|
||||
PainlessClassBuilder painlessInterfaceStruct = javaClassesToPainlessClassBuilders.get(javaSuperInterface);
|
||||
PainlessClassBuilder painlessInterfaceStruct = classesToPainlessClasses.get(javaSuperInterface);
|
||||
|
||||
if (painlessInterfaceStruct != null) {
|
||||
String painlessInterfaceStructName = painlessInterfaceStruct.name;
|
||||
|
@ -828,7 +784,7 @@ public class PainlessLookupBuilder {
|
|||
|
||||
// copies methods and fields from Object into interface types
|
||||
if (painlessStruct.clazz.isInterface() || (def.class.getSimpleName()).equals(painlessStruct.name)) {
|
||||
PainlessClassBuilder painlessObjectStruct = javaClassesToPainlessClassBuilders.get(Object.class);
|
||||
PainlessClassBuilder painlessObjectStruct = classesToPainlessClasses.get(Object.class);
|
||||
|
||||
if (painlessObjectStruct != null) {
|
||||
copyStruct(painlessStruct.name, Collections.singletonList(painlessObjectStruct.name));
|
||||
|
@ -837,18 +793,18 @@ public class PainlessLookupBuilder {
|
|||
}
|
||||
|
||||
// precompute runtime classes
|
||||
for (PainlessClassBuilder painlessStruct : javaClassesToPainlessClassBuilders.values()) {
|
||||
for (PainlessClassBuilder painlessStruct : classesToPainlessClasses.values()) {
|
||||
addRuntimeClass(painlessStruct);
|
||||
}
|
||||
|
||||
Map<Class<?>, PainlessClass> javaClassesToPainlessClasses = new HashMap<>();
|
||||
|
||||
// copy all structs to make them unmodifiable for outside users:
|
||||
for (Map.Entry<Class<?>,PainlessClassBuilder> entry : javaClassesToPainlessClassBuilders.entrySet()) {
|
||||
for (Map.Entry<Class<?>,PainlessClassBuilder> entry : classesToPainlessClasses.entrySet()) {
|
||||
entry.getValue().functionalMethod = computeFunctionalInterfaceMethod(entry.getValue());
|
||||
javaClassesToPainlessClasses.put(entry.getKey(), entry.getValue().build());
|
||||
}
|
||||
|
||||
return new PainlessLookup(painlessClassNamesToJavaClasses, javaClassesToPainlessClasses);
|
||||
return new PainlessLookup(canonicalClassNamesToClasses, javaClassesToPainlessClasses);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,35 +19,177 @@
|
|||
|
||||
package org.elasticsearch.painless.lookup;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other classes within
|
||||
* PainlessLookupUtility contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other classes within
|
||||
* Painless for conversion between type names and types along with some other various utility methods.
|
||||
*
|
||||
* The following terminology is used for variable names throughout the lookup package:
|
||||
*
|
||||
* - javaClass (Class) - a java class including def and excluding array type java classes
|
||||
* - javaClassName (String) - the fully qualified java class name for a javaClass
|
||||
* - painlessClassName (String) - the fully qualified painless name or imported painless name for a painlessClass
|
||||
* - anyClassName (String) - either a javaClassName or a painlessClassName
|
||||
* - javaType (Class) - a java class excluding def and array type java classes
|
||||
* - painlessType (Class) - a java class including def and array type java classes
|
||||
* - javaTypeName (String) - the fully qualified java Type name for a javaType
|
||||
* - painlessTypeName (String) - the fully qualified painless name or imported painless name for a painlessType
|
||||
* - anyTypeName (String) - either a javaTypeName or a painlessTypeName
|
||||
* - painlessClass (PainlessClass) - a painless class object
|
||||
* A class is a set of methods and fields under a specific class name. A type is either a class or an array under a specific type name.
|
||||
* Note the distinction between class versus type is class means that no array classes will be be represented whereas type allows array
|
||||
* classes to be represented. The set of available classes will always be a subset of the available types.
|
||||
*
|
||||
* Under ambiguous circumstances most variable names are prefixed with asm, java, or painless.
|
||||
* If the variable name is the same for asm, java, and painless, no prefix is used.
|
||||
* Under ambiguous circumstances most variable names are prefixed with asm, java, or painless. If the variable value is the same for asm,
|
||||
* java, and painless, no prefix is used.
|
||||
*
|
||||
* <ul>
|
||||
* <li> - javaClassName (String) - the fully qualified java class name where '$' tokens represent inner classes excluding
|
||||
* def and array types </li>
|
||||
*
|
||||
* <li> - javaClass (Class) - a java class excluding def and array types </li>
|
||||
*
|
||||
* <li> - javaType (Class) - a java class excluding def and including array types </li>
|
||||
*
|
||||
* <li> - importedClassName (String) - the imported painless class name where the java canonical class name is used without
|
||||
* the package qualifier
|
||||
*
|
||||
* <li> - canonicalClassName (String) - the fully qualified painless class name equivalent to the fully
|
||||
* qualified java canonical class name or imported painless class name for a class
|
||||
* including def and excluding array types where '.' tokens represent inner classes <li>
|
||||
*
|
||||
* <li> - canonicalTypeName (String) - the fully qualified painless type name equivalent to the fully
|
||||
* qualified java canonical type name or imported painless type name for a type
|
||||
* including def where '.' tokens represent inner classes and each set of '[]' tokens
|
||||
* at the end of the type name represent a single dimension for an array type <li>
|
||||
*
|
||||
* <li> - class/clazz (Class) - a painless class represented by a java class including def and excluding array
|
||||
* types </li>
|
||||
*
|
||||
* <li> - type (Class) - a painless type represented by a java class including def and array types </li>
|
||||
*
|
||||
* <li> - painlessClass (PainlessClass) - a painless class object </li>
|
||||
*
|
||||
* <li> - painlessMethod (PainlessMethod) - a painless method object </li>
|
||||
*
|
||||
* <li> - painlessField (PainlessField) - a painless field object </li>
|
||||
* </ul>
|
||||
*/
|
||||
public final class PainlessLookupUtility {
|
||||
|
||||
public static Class<?> javaObjectTypeToPainlessDefType(Class<?> javaType) {
|
||||
/**
|
||||
* Converts a canonical type name to a type based on the terminology specified as part of the documentation for
|
||||
* {@link PainlessLookupUtility}. Since canonical class names are a subset of canonical type names, this method will
|
||||
* safely convert a canonical class name to a class as well.
|
||||
*/
|
||||
public static Class<?> canonicalTypeNameToType(String canonicalTypeName, Map<String, Class<?>> canonicalClassNamesToClasses) {
|
||||
Objects.requireNonNull(canonicalTypeName);
|
||||
Objects.requireNonNull(canonicalClassNamesToClasses);
|
||||
|
||||
Class<?> type = canonicalClassNamesToClasses.get(canonicalTypeName);
|
||||
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
|
||||
int arrayDimensions = 0;
|
||||
int arrayIndex = canonicalTypeName.indexOf('[');
|
||||
|
||||
if (arrayIndex != -1) {
|
||||
int typeNameLength = canonicalTypeName.length();
|
||||
|
||||
while (arrayIndex < typeNameLength) {
|
||||
if (canonicalTypeName.charAt(arrayIndex) == '[' &&
|
||||
++arrayIndex < typeNameLength &&
|
||||
canonicalTypeName.charAt(arrayIndex++) == ']') {
|
||||
++arrayDimensions;
|
||||
} else {
|
||||
throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found");
|
||||
}
|
||||
}
|
||||
|
||||
canonicalTypeName = canonicalTypeName.substring(0, canonicalTypeName.indexOf('['));
|
||||
type = canonicalClassNamesToClasses.get(canonicalTypeName);
|
||||
|
||||
char arrayBraces[] = new char[arrayDimensions];
|
||||
Arrays.fill(arrayBraces, '[');
|
||||
String javaTypeName = new String(arrayBraces);
|
||||
|
||||
if (type == boolean.class) {
|
||||
javaTypeName += "Z";
|
||||
} else if (type == byte.class) {
|
||||
javaTypeName += "B";
|
||||
} else if (type == short.class) {
|
||||
javaTypeName += "S";
|
||||
} else if (type == char.class) {
|
||||
javaTypeName += "C";
|
||||
} else if (type == int.class) {
|
||||
javaTypeName += "I";
|
||||
} else if (type == long.class) {
|
||||
javaTypeName += "J";
|
||||
} else if (type == float.class) {
|
||||
javaTypeName += "F";
|
||||
} else if (type == double.class) {
|
||||
javaTypeName += "D";
|
||||
} else {
|
||||
javaTypeName += "L" + type.getName() + ";";
|
||||
}
|
||||
|
||||
try {
|
||||
return Class.forName(javaTypeName);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found", cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a type to a canonical type name based on the terminology specified as part of the documentation for
|
||||
* {@link PainlessLookupUtility}. Since classes are a subset of types, this method will safely convert a class
|
||||
* to a canonical class name as well.
|
||||
*/
|
||||
public static String typeToCanonicalTypeName(Class<?> type) {
|
||||
Objects.requireNonNull(type);
|
||||
|
||||
String canonicalTypeName = type.getCanonicalName();
|
||||
|
||||
if (canonicalTypeName.startsWith(def.class.getName())) {
|
||||
canonicalTypeName = canonicalTypeName.replace(def.class.getName(), DEF_TYPE_NAME);
|
||||
}
|
||||
|
||||
return canonicalTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of types to a list of canonical type names as a string based on the terminology specified as part of the
|
||||
* documentation for {@link PainlessLookupUtility}. Since classes are a subset of types, this method will safely convert a list
|
||||
* of classes or a mixed list of classes and types to a list of canonical type names as a string as well.
|
||||
*/
|
||||
public static String typesToCanonicalTypeNames(List<Class<?>> types) {
|
||||
StringBuilder typesStringBuilder = new StringBuilder("[");
|
||||
|
||||
int anyTypesSize = types.size();
|
||||
int anyTypesIndex = 0;
|
||||
|
||||
for (Class<?> painlessType : types) {
|
||||
String canonicalTypeName = typeToCanonicalTypeName(painlessType);
|
||||
|
||||
typesStringBuilder.append(canonicalTypeName);
|
||||
|
||||
if (++anyTypesIndex < anyTypesSize) {
|
||||
typesStringBuilder.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
typesStringBuilder.append("]");
|
||||
|
||||
return typesStringBuilder.toString();
|
||||
}
|
||||
/**
|
||||
* Converts a java type to a type based on the terminology specified as part of {@link PainlessLookupUtility} where if a type is an
|
||||
* object class or object array, the returned type will be the equivalent def class or def array. Otherwise, this behaves as an
|
||||
* identity function.
|
||||
*/
|
||||
public static Class<?> javaTypeToType(Class<?> javaType) {
|
||||
Objects.requireNonNull(javaType);
|
||||
|
||||
if (javaType.isArray()) {
|
||||
Class<?> javaTypeComponent = javaType.getComponentType();
|
||||
int arrayDimensions = 1;
|
||||
|
@ -58,14 +200,11 @@ public final class PainlessLookupUtility {
|
|||
}
|
||||
|
||||
if (javaTypeComponent == Object.class) {
|
||||
char[] asmDescriptorBraces = new char[arrayDimensions];
|
||||
Arrays.fill(asmDescriptorBraces, '[');
|
||||
|
||||
String asmDescriptor = new String(asmDescriptorBraces) + Type.getType(def.class).getDescriptor();
|
||||
Type asmType = Type.getType(asmDescriptor);
|
||||
char[] arrayBraces = new char[arrayDimensions];
|
||||
Arrays.fill(arrayBraces, '[');
|
||||
|
||||
try {
|
||||
return Class.forName(asmType.getInternalName().replace('/', '.'));
|
||||
return Class.forName(new String(arrayBraces) + "L" + def.class.getName() + ";");
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalStateException("internal error", cnfe);
|
||||
}
|
||||
|
@ -77,206 +216,147 @@ public final class PainlessLookupUtility {
|
|||
return javaType;
|
||||
}
|
||||
|
||||
public static Class<?> painlessDefTypeToJavaObjectType(Class<?> painlessType) {
|
||||
if (painlessType.isArray()) {
|
||||
Class<?> painlessTypeComponent = painlessType.getComponentType();
|
||||
/**
|
||||
* Converts a type to a java type based on the terminology specified as part of {@link PainlessLookupUtility} where if a type is a
|
||||
* def class or def array, the returned type will be the equivalent object class or object array. Otherwise, this behaves as an
|
||||
* identity function.
|
||||
*/
|
||||
public static Class<?> typeToJavaType(Class<?> type) {
|
||||
Objects.requireNonNull(type);
|
||||
|
||||
if (type.isArray()) {
|
||||
Class<?> typeComponent = type.getComponentType();
|
||||
int arrayDimensions = 1;
|
||||
|
||||
while (painlessTypeComponent.isArray()) {
|
||||
painlessTypeComponent = painlessTypeComponent.getComponentType();
|
||||
while (typeComponent.isArray()) {
|
||||
typeComponent = typeComponent.getComponentType();
|
||||
++arrayDimensions;
|
||||
}
|
||||
|
||||
if (painlessTypeComponent == def.class) {
|
||||
char[] asmDescriptorBraces = new char[arrayDimensions];
|
||||
Arrays.fill(asmDescriptorBraces, '[');
|
||||
|
||||
String asmDescriptor = new String(asmDescriptorBraces) + Type.getType(Object.class).getDescriptor();
|
||||
Type asmType = Type.getType(asmDescriptor);
|
||||
if (typeComponent == def.class) {
|
||||
char[] arrayBraces = new char[arrayDimensions];
|
||||
Arrays.fill(arrayBraces, '[');
|
||||
|
||||
try {
|
||||
return Class.forName(asmType.getInternalName().replace('/', '.'));
|
||||
} catch (ClassNotFoundException exception) {
|
||||
throw new IllegalStateException("internal error", exception);
|
||||
return Class.forName(new String(arrayBraces) + "L" + Object.class.getName() + ";");
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalStateException("internal error", cnfe);
|
||||
}
|
||||
}
|
||||
} else if (painlessType == def.class) {
|
||||
} else if (type == def.class) {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
return painlessType;
|
||||
return type;
|
||||
}
|
||||
|
||||
public static String anyTypeNameToPainlessTypeName(String anyTypeName) {
|
||||
return anyTypeName.replace(def.class.getName(), DEF_PAINLESS_CLASS_NAME).replace('$', '.');
|
||||
}
|
||||
/**
|
||||
* Ensures a type exists based on the terminology specified as part of {@link PainlessLookupUtility}. Throws an
|
||||
* {@link IllegalArgumentException} if the type does not exist.
|
||||
*/
|
||||
public static void validateType(Class<?> type, Collection<Class<?>> classes) {
|
||||
String canonicalTypeName = typeToCanonicalTypeName(type);
|
||||
|
||||
public static String anyTypeToPainlessTypeName(Class<?> anyType) {
|
||||
if (anyType.isLocalClass() || anyType.isAnonymousClass()) {
|
||||
return null;
|
||||
} else if (anyType.isArray()) {
|
||||
Class<?> anyTypeComponent = anyType.getComponentType();
|
||||
int arrayDimensions = 1;
|
||||
|
||||
while (anyTypeComponent.isArray()) {
|
||||
anyTypeComponent = anyTypeComponent.getComponentType();
|
||||
++arrayDimensions;
|
||||
}
|
||||
|
||||
if (anyTypeComponent == def.class) {
|
||||
StringBuilder painlessDefTypeNameArrayBuilder = new StringBuilder(DEF_PAINLESS_CLASS_NAME);
|
||||
|
||||
for (int dimension = 0; dimension < arrayDimensions; dimension++) {
|
||||
painlessDefTypeNameArrayBuilder.append("[]");
|
||||
}
|
||||
|
||||
return painlessDefTypeNameArrayBuilder.toString();
|
||||
}
|
||||
} else if (anyType == def.class) {
|
||||
return DEF_PAINLESS_CLASS_NAME;
|
||||
while (type.getComponentType() != null) {
|
||||
type = type.getComponentType();
|
||||
}
|
||||
|
||||
return anyType.getCanonicalName().replace('$', '.');
|
||||
}
|
||||
|
||||
public static Class<?> painlessTypeNameToPainlessType(String painlessTypeName, Map<String, Class<?>> painlessClassNamesToJavaClasses) {
|
||||
Class<?> javaClass = painlessClassNamesToJavaClasses.get(painlessTypeName);
|
||||
|
||||
if (javaClass != null) {
|
||||
return javaClass;
|
||||
}
|
||||
|
||||
int arrayDimensions = 0;
|
||||
int arrayIndex = painlessTypeName.indexOf('[');
|
||||
|
||||
if (arrayIndex != -1) {
|
||||
int painlessTypeNameLength = painlessTypeName.length();
|
||||
|
||||
while (arrayIndex < painlessTypeNameLength) {
|
||||
if (painlessTypeName.charAt(arrayIndex) == '[' &&
|
||||
++arrayIndex < painlessTypeNameLength &&
|
||||
painlessTypeName.charAt(arrayIndex++) == ']') {
|
||||
++arrayDimensions;
|
||||
} else {
|
||||
throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found");
|
||||
}
|
||||
}
|
||||
|
||||
painlessTypeName = painlessTypeName.substring(0, painlessTypeName.indexOf('['));
|
||||
javaClass = painlessClassNamesToJavaClasses.get(painlessTypeName);
|
||||
|
||||
char javaDescriptorBraces[] = new char[arrayDimensions];
|
||||
Arrays.fill(javaDescriptorBraces, '[');
|
||||
String javaDescriptor = new String(javaDescriptorBraces);
|
||||
|
||||
if (javaClass == boolean.class) {
|
||||
javaDescriptor += "Z";
|
||||
} else if (javaClass == byte.class) {
|
||||
javaDescriptor += "B";
|
||||
} else if (javaClass == short.class) {
|
||||
javaDescriptor += "S";
|
||||
} else if (javaClass == char.class) {
|
||||
javaDescriptor += "C";
|
||||
} else if (javaClass == int.class) {
|
||||
javaDescriptor += "I";
|
||||
} else if (javaClass == long.class) {
|
||||
javaDescriptor += "J";
|
||||
} else if (javaClass == float.class) {
|
||||
javaDescriptor += "F";
|
||||
} else if (javaClass == double.class) {
|
||||
javaDescriptor += "D";
|
||||
} else {
|
||||
javaDescriptor += "L" + javaClass.getName() + ";";
|
||||
}
|
||||
|
||||
try {
|
||||
return Class.forName(javaDescriptor);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found", cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found");
|
||||
}
|
||||
|
||||
public static void validatePainlessType(Class<?> painlessType, Collection<Class<?>> javaClasses) {
|
||||
String painlessTypeName = anyTypeNameToPainlessTypeName(painlessType.getName());
|
||||
|
||||
while (painlessType.getComponentType() != null) {
|
||||
painlessType = painlessType.getComponentType();
|
||||
}
|
||||
|
||||
if (javaClasses.contains(painlessType) == false) {
|
||||
throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found");
|
||||
if (classes.contains(type) == false) {
|
||||
throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a type to its boxed type equivalent if one exists based on the terminology specified as part of
|
||||
* {@link PainlessLookupUtility}. Otherwise, this behaves as an identity function.
|
||||
*/
|
||||
public static Class<?> typeToBoxedType(Class<?> type) {
|
||||
if (type == boolean.class) {
|
||||
return Boolean.class;
|
||||
} else if (type == byte.class) {
|
||||
return Byte.class;
|
||||
} else if (type == short.class) {
|
||||
return Short.class;
|
||||
} else if (type == char.class) {
|
||||
return Character.class;
|
||||
} else if (type == int.class) {
|
||||
return Integer.class;
|
||||
} else if (type == long.class) {
|
||||
return Long.class;
|
||||
} else if (type == float.class) {
|
||||
return Float.class;
|
||||
} else if (type == double.class) {
|
||||
return Double.class;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a type to its unboxed type equivalent if one exists based on the terminology specified as part of
|
||||
* {@link PainlessLookupUtility}. Otherwise, this behaves as an identity function.
|
||||
*/
|
||||
public static Class<?> typeToUnboxedType(Class<?> type) {
|
||||
if (type == Boolean.class) {
|
||||
return boolean.class;
|
||||
} else if (type == Byte.class) {
|
||||
return byte.class;
|
||||
} else if (type == Short.class) {
|
||||
return short.class;
|
||||
} else if (type == Character.class) {
|
||||
return char.class;
|
||||
} else if (type == Integer.class) {
|
||||
return int.class;
|
||||
} else if (type == Long.class) {
|
||||
return long.class;
|
||||
} else if (type == Float.class) {
|
||||
return float.class;
|
||||
} else if (type == Double.class) {
|
||||
return double.class;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a type based on the terminology specified as part of {@link PainlessLookupUtility} is available as a constant type
|
||||
* where {@code true} is returned if the type is a constant type and {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isConstantType(Class<?> type) {
|
||||
return type == boolean.class ||
|
||||
type == byte.class ||
|
||||
type == short.class ||
|
||||
type == char.class ||
|
||||
type == int.class ||
|
||||
type == long.class ||
|
||||
type == float.class ||
|
||||
type == double.class ||
|
||||
type == String.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a painless method key used to lookup painless methods from a painless class.
|
||||
*/
|
||||
public static String buildPainlessMethodKey(String methodName, int methodArity) {
|
||||
return methodName + "/" + methodArity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a painless field key used to lookup painless fields from a painless class.
|
||||
*/
|
||||
public static String buildPainlessFieldKey(String fieldName) {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public static Class<?> getBoxedAnyType(Class<?> anyType) {
|
||||
if (anyType == boolean.class) {
|
||||
return Boolean.class;
|
||||
} else if (anyType == byte.class) {
|
||||
return Byte.class;
|
||||
} else if (anyType == short.class) {
|
||||
return Short.class;
|
||||
} else if (anyType == char.class) {
|
||||
return Character.class;
|
||||
} else if (anyType == int.class) {
|
||||
return Integer.class;
|
||||
} else if (anyType == long.class) {
|
||||
return Long.class;
|
||||
} else if (anyType == float.class) {
|
||||
return Float.class;
|
||||
} else if (anyType == double.class) {
|
||||
return Double.class;
|
||||
}
|
||||
/**
|
||||
* The def type name as specified in the source for a script.
|
||||
*/
|
||||
public static final String DEF_TYPE_NAME = "def";
|
||||
|
||||
return anyType;
|
||||
}
|
||||
|
||||
public static Class<?> getUnboxedAnyType(Class<?> anyType) {
|
||||
if (anyType == Boolean.class) {
|
||||
return boolean.class;
|
||||
} else if (anyType == Byte.class) {
|
||||
return byte.class;
|
||||
} else if (anyType == Short.class) {
|
||||
return short.class;
|
||||
} else if (anyType == Character.class) {
|
||||
return char.class;
|
||||
} else if (anyType == Integer.class) {
|
||||
return int.class;
|
||||
} else if (anyType == Long.class) {
|
||||
return long.class;
|
||||
} else if (anyType == Float.class) {
|
||||
return float.class;
|
||||
} else if (anyType == Double.class) {
|
||||
return double.class;
|
||||
}
|
||||
|
||||
return anyType;
|
||||
}
|
||||
|
||||
public static boolean isAnyTypeConstant(Class<?> anyType) {
|
||||
return anyType == boolean.class ||
|
||||
anyType == byte.class ||
|
||||
anyType == short.class ||
|
||||
anyType == char.class ||
|
||||
anyType == int.class ||
|
||||
anyType == long.class ||
|
||||
anyType == float.class ||
|
||||
anyType == double.class ||
|
||||
anyType == String.class;
|
||||
}
|
||||
|
||||
public static final String DEF_PAINLESS_CLASS_NAME = def.class.getSimpleName();
|
||||
public static final String CONSTRUCTOR_ANY_NAME = "<init>";
|
||||
/**
|
||||
* The method name for all constructors.
|
||||
*/
|
||||
public static final String CONSTRUCTOR_NAME = "<init>";
|
||||
|
||||
private PainlessLookupUtility() {
|
||||
|
||||
|
|
|
@ -70,21 +70,21 @@ public class PainlessMethod {
|
|||
params = new Class<?>[1 + arguments.size()];
|
||||
params[0] = augmentation;
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
params[i + 1] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
|
||||
params[i + 1] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
||||
}
|
||||
returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn);
|
||||
returnValue = PainlessLookupUtility.typeToJavaType(rtn);
|
||||
} else if (Modifier.isStatic(modifiers)) {
|
||||
// static method: straightforward copy
|
||||
params = new Class<?>[arguments.size()];
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
params[i] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
|
||||
params[i] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
||||
}
|
||||
returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn);
|
||||
returnValue = PainlessLookupUtility.typeToJavaType(rtn);
|
||||
} else if ("<init>".equals(name)) {
|
||||
// constructor: returns the owner class
|
||||
params = new Class<?>[arguments.size()];
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
params[i] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
|
||||
params[i] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
||||
}
|
||||
returnValue = target;
|
||||
} else {
|
||||
|
@ -92,9 +92,9 @@ public class PainlessMethod {
|
|||
params = new Class<?>[1 + arguments.size()];
|
||||
params[0] = target;
|
||||
for (int i = 0; i < arguments.size(); i++) {
|
||||
params[i + 1] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i));
|
||||
params[i + 1] = PainlessLookupUtility.typeToJavaType(arguments.get(i));
|
||||
}
|
||||
returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn);
|
||||
returnValue = PainlessLookupUtility.typeToJavaType(rtn);
|
||||
}
|
||||
return MethodType.methodType(returnValue, params);
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ public abstract class AExpression extends ANode {
|
|||
|
||||
return ecast;
|
||||
} else {
|
||||
if (PainlessLookupUtility.isAnyTypeConstant(expected)) {
|
||||
if (PainlessLookupUtility.isConstantType(expected)) {
|
||||
// For the case where a cast is required, a constant is set,
|
||||
// and the constant can be immediately cast to the expected type.
|
||||
// An EConstant replaces this node with the constant cast appropriately
|
||||
|
|
|
@ -106,8 +106,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply multiply [*] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -149,8 +149,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply divide [/] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -197,8 +197,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply remainder [%] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -245,8 +245,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply add [+] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -304,8 +304,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply subtract [-] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -363,8 +363,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (lhspromote == null || rhspromote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply left shift [<<] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote = lhspromote;
|
||||
|
@ -411,8 +411,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (lhspromote == null || rhspromote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply right shift [>>] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote = lhspromote;
|
||||
|
@ -462,8 +462,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (lhspromote == null || rhspromote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply unsigned shift [>>>] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (lhspromote == def.class || rhspromote == def.class) {
|
||||
|
@ -506,8 +506,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply and [&] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -546,8 +546,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply xor [^] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
@ -587,8 +587,8 @@ public final class EBinary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply or [|] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
actual = promote;
|
||||
|
|
|
@ -69,7 +69,7 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
|
|||
defPointer = "D" + variable + "." + call + ",1";
|
||||
} else {
|
||||
// typed implementation
|
||||
defPointer = "S" + PainlessLookupUtility.anyTypeToPainlessTypeName(captured.clazz) + "." + call + ",1";
|
||||
defPointer = "S" + PainlessLookupUtility.typeToCanonicalTypeName(captured.clazz) + "." + call + ",1";
|
||||
}
|
||||
actual = String.class;
|
||||
} else {
|
||||
|
@ -77,8 +77,8 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
|
|||
// static case
|
||||
if (captured.clazz != def.class) {
|
||||
try {
|
||||
ref = new FunctionRef(
|
||||
locals.getPainlessLookup(), expected, PainlessLookupUtility.anyTypeToPainlessTypeName(captured.clazz), call, 1);
|
||||
ref = new FunctionRef(locals.getPainlessLookup(), expected,
|
||||
PainlessLookupUtility.typeToCanonicalTypeName(captured.clazz), call, 1);
|
||||
|
||||
// check casts between the interface method and the delegate method are legal
|
||||
for (int i = 0; i < ref.interfaceMethod.arguments.size(); ++i) {
|
||||
|
@ -110,7 +110,7 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
|
|||
// typed interface, dynamic implementation
|
||||
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
|
||||
Type methodType = Type.getMethodType(MethodWriter.getType(expected), MethodWriter.getType(captured.clazz));
|
||||
writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.anyTypeToPainlessTypeName(expected));
|
||||
writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.typeToCanonicalTypeName(expected));
|
||||
} else {
|
||||
// typed interface, typed implementation
|
||||
writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot());
|
||||
|
|
|
@ -63,6 +63,6 @@ final class ECast extends AExpression {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(cast.to), child);
|
||||
return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(cast.to), child);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,8 +93,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply equals [==] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (promotedType == def.class) {
|
||||
|
@ -143,8 +143,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply reference equals [===] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
left.expected = promotedType;
|
||||
|
@ -184,8 +184,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply not equals [!=] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (promotedType == def.class) {
|
||||
|
@ -234,8 +234,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply reference not equals [!==] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
left.expected = promotedType;
|
||||
|
@ -275,8 +275,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply greater than or equals [>=] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (promotedType == def.class) {
|
||||
|
@ -315,8 +315,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply greater than [>] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (promotedType == def.class) {
|
||||
|
@ -355,8 +355,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply less than or equals [<=] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (promotedType == def.class) {
|
||||
|
@ -395,8 +395,8 @@ public final class EComp extends AExpression {
|
|||
|
||||
if (promotedType == null) {
|
||||
throw createError(new ClassCastException("Cannot apply less than [>=] to types " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " +
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "]."));
|
||||
}
|
||||
|
||||
if (promotedType == def.class) {
|
||||
|
|
|
@ -68,13 +68,13 @@ public final class EFunctionRef extends AExpression implements ILambda {
|
|||
PainlessMethod interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod;
|
||||
if (interfaceMethod == null) {
|
||||
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
|
||||
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface");
|
||||
"to [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface");
|
||||
}
|
||||
PainlessMethod delegateMethod =
|
||||
locals.getMethod(PainlessLookupUtility.buildPainlessMethodKey(call, interfaceMethod.arguments.size()));
|
||||
if (delegateMethod == null) {
|
||||
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
|
||||
"to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], function not found");
|
||||
"to [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], function not found");
|
||||
}
|
||||
ref = new FunctionRef(expected, interfaceMethod, delegateMethod, 0);
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@ public final class EInstanceof extends AExpression {
|
|||
}
|
||||
|
||||
// map to wrapped type for primitive types
|
||||
resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.getBoxedAnyType(clazz) :
|
||||
PainlessLookupUtility.painlessDefTypeToJavaObjectType(clazz);
|
||||
resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.typeToBoxedType(clazz) :
|
||||
PainlessLookupUtility.typeToJavaType(clazz);
|
||||
|
||||
// analyze and cast the expression
|
||||
expression.analyze(locals);
|
||||
|
@ -76,7 +76,7 @@ public final class EInstanceof extends AExpression {
|
|||
primitiveExpression = expression.actual.isPrimitive();
|
||||
// map to wrapped type for primitive types
|
||||
expressionType = expression.actual.isPrimitive() ?
|
||||
PainlessLookupUtility.getBoxedAnyType(expression.actual) : PainlessLookupUtility.painlessDefTypeToJavaObjectType(clazz);
|
||||
PainlessLookupUtility.typeToBoxedType(expression.actual) : PainlessLookupUtility.typeToJavaType(clazz);
|
||||
|
||||
actual = boolean.class;
|
||||
}
|
||||
|
|
|
@ -123,12 +123,12 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod;
|
||||
if (interfaceMethod == null) {
|
||||
throw createError(new IllegalArgumentException("Cannot pass lambda to " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface"));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface"));
|
||||
}
|
||||
// check arity before we manipulate parameters
|
||||
if (interfaceMethod.arguments.size() != paramTypeStrs.size())
|
||||
throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name +
|
||||
"] in [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]");
|
||||
"] in [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "]");
|
||||
// for method invocation, its allowed to ignore the return value
|
||||
if (interfaceMethod.rtn == void.class) {
|
||||
returnType = def.class;
|
||||
|
@ -140,7 +140,7 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
for (int i = 0; i < paramTypeStrs.size(); i++) {
|
||||
String paramType = paramTypeStrs.get(i);
|
||||
if (paramType == null) {
|
||||
actualParamTypeStrs.add(PainlessLookupUtility.anyTypeToPainlessTypeName(interfaceMethod.arguments.get(i)));
|
||||
actualParamTypeStrs.add(PainlessLookupUtility.typeToCanonicalTypeName(interfaceMethod.arguments.get(i)));
|
||||
} else {
|
||||
actualParamTypeStrs.add(paramType);
|
||||
}
|
||||
|
@ -162,14 +162,14 @@ public final class ELambda extends AExpression implements ILambda {
|
|||
List<String> paramTypes = new ArrayList<>(captures.size() + actualParamTypeStrs.size());
|
||||
List<String> paramNames = new ArrayList<>(captures.size() + paramNameStrs.size());
|
||||
for (Variable var : captures) {
|
||||
paramTypes.add(PainlessLookupUtility.anyTypeToPainlessTypeName(var.clazz));
|
||||
paramTypes.add(PainlessLookupUtility.typeToCanonicalTypeName(var.clazz));
|
||||
paramNames.add(var.name);
|
||||
}
|
||||
paramTypes.addAll(actualParamTypeStrs);
|
||||
paramNames.addAll(paramNameStrs);
|
||||
|
||||
// desugar lambda body into a synthetic method
|
||||
desugared = new SFunction(reserved, location, PainlessLookupUtility.anyTypeToPainlessTypeName(returnType), name,
|
||||
desugared = new SFunction(reserved, location, PainlessLookupUtility.typeToCanonicalTypeName(returnType), name,
|
||||
paramTypes, paramNames, statements, true);
|
||||
desugared.generateSignature(locals.getPainlessLookup());
|
||||
desugared.analyze(Locals.newLambdaScope(locals.getProgramScope(), returnType,
|
||||
|
|
|
@ -53,7 +53,7 @@ public final class ENull extends AExpression {
|
|||
if (expected != null) {
|
||||
if (expected.isPrimitive()) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
"Cannot cast null to a primitive type [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]."));
|
||||
"Cannot cast null to a primitive type [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "]."));
|
||||
}
|
||||
|
||||
actual = expected;
|
||||
|
|
|
@ -94,7 +94,7 @@ public final class EUnary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply not [~] to type " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(child.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(child.actual) + "]."));
|
||||
}
|
||||
|
||||
child.expected = promote;
|
||||
|
@ -124,7 +124,7 @@ public final class EUnary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply positive [+] to type " +
|
||||
"[" + PainlessLookupUtility.painlessDefTypeToJavaObjectType(child.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToJavaType(child.actual) + "]."));
|
||||
}
|
||||
|
||||
child.expected = promote;
|
||||
|
@ -158,7 +158,7 @@ public final class EUnary extends AExpression {
|
|||
|
||||
if (promote == null) {
|
||||
throw createError(new ClassCastException("Cannot apply negative [-] to type " +
|
||||
"[" + PainlessLookupUtility.painlessDefTypeToJavaObjectType(child.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToJavaType(child.actual) + "]."));
|
||||
}
|
||||
|
||||
child.expected = promote;
|
||||
|
|
|
@ -68,7 +68,7 @@ public final class PBrace extends AStoreable {
|
|||
sub = new PSubListShortcut(location, locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual), index);
|
||||
} else {
|
||||
throw createError(new IllegalArgumentException("Illegal array access on type " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual) + "]."));
|
||||
}
|
||||
|
||||
sub.write = write;
|
||||
|
|
|
@ -73,7 +73,7 @@ public final class PCallInvoke extends AExpression {
|
|||
PainlessClass struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual);
|
||||
|
||||
if (prefix.actual.isPrimitive()) {
|
||||
struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.getBoxedAnyType(prefix.actual));
|
||||
struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.typeToBoxedType(prefix.actual));
|
||||
}
|
||||
|
||||
String methodKey = PainlessLookupUtility.buildPainlessMethodKey(name, arguments.size());
|
||||
|
|
|
@ -63,7 +63,7 @@ public final class PField extends AStoreable {
|
|||
prefix = prefix.cast(locals);
|
||||
|
||||
if (prefix.actual.isArray()) {
|
||||
sub = new PSubArrayLength(location, PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual), value);
|
||||
sub = new PSubArrayLength(location, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), value);
|
||||
} else if (prefix.actual == def.class) {
|
||||
sub = new PSubDefField(location, value);
|
||||
} else {
|
||||
|
@ -85,7 +85,8 @@ public final class PField extends AStoreable {
|
|||
"set" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 1));
|
||||
|
||||
if (getter != null || setter != null) {
|
||||
sub = new PSubShortcut(location, value, PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual), getter, setter);
|
||||
sub = new PSubShortcut(
|
||||
location, value, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), getter, setter);
|
||||
} else {
|
||||
EConstant index = new EConstant(location, value);
|
||||
index.analyze(locals);
|
||||
|
@ -103,7 +104,7 @@ public final class PField extends AStoreable {
|
|||
|
||||
if (sub == null) {
|
||||
throw createError(new IllegalArgumentException(
|
||||
"Unknown field [" + value + "] for type [" + PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual) + "]."));
|
||||
"Unknown field [" + value + "] for type [" + PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual) + "]."));
|
||||
}
|
||||
|
||||
if (nullSafe) {
|
||||
|
|
|
@ -53,7 +53,7 @@ final class PSubField extends AStoreable {
|
|||
void analyze(Locals locals) {
|
||||
if (write && Modifier.isFinal(field.modifiers)) {
|
||||
throw createError(new IllegalArgumentException("Cannot write to read-only field [" + field.name + "] for type " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(field.clazz) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(field.clazz) + "]."));
|
||||
}
|
||||
|
||||
actual = field.clazz;
|
||||
|
|
|
@ -85,7 +85,7 @@ public class SEach extends AStatement {
|
|||
sub = new SSubEachIterable(location, variable, expression, block);
|
||||
} else {
|
||||
throw createError(new IllegalArgumentException("Illegal for each type " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expression.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(expression.actual) + "]."));
|
||||
}
|
||||
|
||||
sub.analyze(locals);
|
||||
|
|
|
@ -136,7 +136,7 @@ public final class SFunction extends AStatement {
|
|||
try {
|
||||
Class<?> paramType = painlessLookup.getJavaClassFromPainlessType(this.paramTypeStrs.get(param));
|
||||
|
||||
paramClasses[param] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(paramType);
|
||||
paramClasses[param] = PainlessLookupUtility.typeToJavaType(paramType);
|
||||
paramTypes.add(paramType);
|
||||
parameters.add(new Parameter(location, paramNameStrs.get(param), paramType));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
|
@ -146,7 +146,7 @@ public final class SFunction extends AStatement {
|
|||
}
|
||||
|
||||
org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType(
|
||||
PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtnType), paramClasses).toMethodDescriptorString());
|
||||
PainlessLookupUtility.typeToJavaType(rtnType), paramClasses).toMethodDescriptorString());
|
||||
this.method = new PainlessMethod(name, null, null, rtnType, paramTypes, method, Modifier.STATIC | Modifier.PRIVATE, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,6 @@ final class SSubEachArray extends AStatement {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(variable.clazz), variable.name, expression, block);
|
||||
return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(variable.clazz), variable.name, expression, block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ final class SSubEachIterable extends AStatement {
|
|||
|
||||
if (method == null) {
|
||||
throw createError(new IllegalArgumentException("Unable to create iterator for the type " +
|
||||
"[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expression.actual) + "]."));
|
||||
"[" + PainlessLookupUtility.typeToCanonicalTypeName(expression.actual) + "]."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,6 @@ final class SSubEachIterable extends AStatement {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(variable.clazz), variable.name, expression, block);
|
||||
return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(variable.clazz), variable.name, expression, block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ public class PainlessDocGenerator {
|
|||
*/
|
||||
private static void emitAnchor(PrintStream stream, Class<?> clazz) {
|
||||
stream.print("painless-api-reference-");
|
||||
stream.print(PainlessLookupUtility.anyTypeToPainlessTypeName(clazz).replace('.', '-'));
|
||||
stream.print(PainlessLookupUtility.typeToCanonicalTypeName(clazz).replace('.', '-'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,7 +234,7 @@ public class PainlessDocGenerator {
|
|||
}
|
||||
|
||||
private static String methodName(PainlessMethod method) {
|
||||
return method.name.equals("<init>") ? PainlessLookupUtility.anyTypeToPainlessTypeName(method.target) : method.name;
|
||||
return method.name.equals("<init>") ? PainlessLookupUtility.typeToCanonicalTypeName(method.target) : method.name;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -156,16 +156,6 @@ if (isEclipse) {
|
|||
compileJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-try,-unchecked"
|
||||
compileTestJava.options.compilerArgs << "-Xlint:-cast,-deprecation,-rawtypes,-try,-unchecked"
|
||||
|
||||
// TODO: remove ScriptDocValuesMissingV6BehaviourTests in 7.0
|
||||
additionalTest('testScriptDocValuesMissingV6Behaviour'){
|
||||
include '**/ScriptDocValuesMissingV6BehaviourTests.class'
|
||||
systemProperty 'es.scripting.exception_for_missing_value', 'false'
|
||||
}
|
||||
test {
|
||||
// these are tested explicitly in separate test tasks
|
||||
exclude '**/*ScriptDocValuesMissingV6BehaviourTests.class'
|
||||
}
|
||||
|
||||
forbiddenPatterns {
|
||||
exclude '**/*.json'
|
||||
exclude '**/*.jmx'
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.elasticsearch.common.geo.GeoPoint;
|
|||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.MutableDateTime;
|
||||
|
@ -126,11 +125,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
|
||||
public long getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return 0L;
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return values[0];
|
||||
}
|
||||
|
@ -172,11 +168,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
*/
|
||||
public ReadableDateTime getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return EPOCH;
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return get(0);
|
||||
}
|
||||
|
@ -277,11 +270,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
|
||||
public double getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return 0d;
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return values[0];
|
||||
}
|
||||
|
@ -337,11 +327,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
|
||||
public GeoPoint getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return values[0];
|
||||
}
|
||||
|
@ -454,11 +441,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
|
||||
public boolean getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return false;
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return values[0];
|
||||
}
|
||||
|
@ -544,11 +528,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
|
||||
public String getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return get(0);
|
||||
}
|
||||
|
@ -572,11 +553,8 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
|
|||
|
||||
public BytesRef getValue() {
|
||||
if (count == 0) {
|
||||
if (ScriptModule.EXCEPTION_FOR_MISSING_VALUE) {
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
throw new IllegalStateException("A document doesn't have a value for a field! " +
|
||||
"Use doc[<field>].size()==0 to check if a document is missing a field!");
|
||||
}
|
||||
return new BytesRef();
|
||||
}
|
||||
return get(0);
|
||||
}
|
||||
|
|
|
@ -31,9 +31,7 @@ import org.elasticsearch.common.settings.ClusterSettings;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.search.aggregations.pipeline.movfn.MovingFunctionScript;
|
||||
import org.elasticsearch.common.Booleans;
|
||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
|
||||
|
||||
/**
|
||||
* Manages building {@link ScriptService}.
|
||||
|
@ -64,11 +62,6 @@ public class ScriptModule {
|
|||
).collect(Collectors.toMap(c -> c.name, Function.identity()));
|
||||
}
|
||||
|
||||
public static final boolean EXCEPTION_FOR_MISSING_VALUE =
|
||||
Booleans.parseBoolean(System.getProperty("es.scripting.exception_for_missing_value", "false"));
|
||||
|
||||
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(Loggers.getLogger(ScriptModule.class));
|
||||
|
||||
private final ScriptService scriptService;
|
||||
|
||||
public ScriptModule(Settings settings, List<ScriptPlugin> scriptPlugins) {
|
||||
|
@ -92,10 +85,6 @@ public class ScriptModule {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (EXCEPTION_FOR_MISSING_VALUE == false)
|
||||
DEPRECATION_LOGGER.deprecated("Script: returning default values for missing document values is deprecated. " +
|
||||
"Set system property '-Des.scripting.exception_for_missing_value=true' " +
|
||||
"to make behaviour compatible with future major versions.");
|
||||
scriptService = new ScriptService(settings, Collections.unmodifiableMap(engines), Collections.unmodifiableMap(contexts));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
/*
|
||||
* 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.index.fielddata;
|
||||
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.fielddata.ScriptDocValues.Longs;
|
||||
import org.elasticsearch.index.fielddata.ScriptDocValues.Dates;
|
||||
import org.elasticsearch.index.fielddata.ScriptDocValues.Booleans;
|
||||
import org.elasticsearch.plugins.ScriptPlugin;
|
||||
import org.elasticsearch.script.MockScriptEngine;
|
||||
import org.elasticsearch.script.ScriptContext;
|
||||
import org.elasticsearch.script.ScriptEngine;
|
||||
import org.elasticsearch.script.ScriptModule;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.ReadableDateTime;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
public class ScriptDocValuesMissingV6BehaviourTests extends ESTestCase {
|
||||
|
||||
public void testScriptMissingValuesWarning(){
|
||||
new ScriptModule(Settings.EMPTY, singletonList(new ScriptPlugin() {
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine(Settings settings, Collection<ScriptContext<?>> contexts) {
|
||||
return new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"));
|
||||
}
|
||||
}));
|
||||
assertWarnings("Script: returning default values for missing document values is deprecated. " +
|
||||
"Set system property '-Des.scripting.exception_for_missing_value=true' " +
|
||||
"to make behaviour compatible with future major versions.");
|
||||
}
|
||||
|
||||
public void testZeroForMissingValueLong() throws IOException {
|
||||
long[][] values = new long[between(3, 10)][];
|
||||
for (int d = 0; d < values.length; d++) {
|
||||
values[d] = new long[0];
|
||||
}
|
||||
Longs longs = wrap(values);
|
||||
for (int round = 0; round < 10; round++) {
|
||||
int d = between(0, values.length - 1);
|
||||
longs.setNextDocId(d);
|
||||
assertEquals(0, longs.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void testEpochForMissingValueDate() throws IOException {
|
||||
final ReadableDateTime EPOCH = new DateTime(0, DateTimeZone.UTC);
|
||||
long[][] values = new long[between(3, 10)][];
|
||||
for (int d = 0; d < values.length; d++) {
|
||||
values[d] = new long[0];
|
||||
}
|
||||
Dates dates = wrapDates(values);
|
||||
for (int round = 0; round < 10; round++) {
|
||||
int d = between(0, values.length - 1);
|
||||
dates.setNextDocId(d);
|
||||
assertEquals(EPOCH, dates.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void testFalseForMissingValueBoolean() throws IOException {
|
||||
long[][] values = new long[between(3, 10)][];
|
||||
for (int d = 0; d < values.length; d++) {
|
||||
values[d] = new long[0];
|
||||
}
|
||||
Booleans bools = wrapBooleans(values);
|
||||
for (int round = 0; round < 10; round++) {
|
||||
int d = between(0, values.length - 1);
|
||||
bools.setNextDocId(d);
|
||||
assertEquals(false, bools.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void testNullForMissingValueGeo() throws IOException{
|
||||
final MultiGeoPointValues values = wrap(new GeoPoint[0]);
|
||||
final ScriptDocValues.GeoPoints script = new ScriptDocValues.GeoPoints(values);
|
||||
script.setNextDocId(0);
|
||||
assertEquals(null, script.getValue());
|
||||
}
|
||||
|
||||
|
||||
private Longs wrap(long[][] values) {
|
||||
return new Longs(new AbstractSortedNumericDocValues() {
|
||||
long[] current;
|
||||
int i;
|
||||
@Override
|
||||
public boolean advanceExact(int doc) {
|
||||
i = 0;
|
||||
current = values[doc];
|
||||
return current.length > 0;
|
||||
}
|
||||
@Override
|
||||
public int docValueCount() {
|
||||
return current.length;
|
||||
}
|
||||
@Override
|
||||
public long nextValue() {
|
||||
return current[i++];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Booleans wrapBooleans(long[][] values) {
|
||||
return new Booleans(new AbstractSortedNumericDocValues() {
|
||||
long[] current;
|
||||
int i;
|
||||
@Override
|
||||
public boolean advanceExact(int doc) {
|
||||
i = 0;
|
||||
current = values[doc];
|
||||
return current.length > 0;
|
||||
}
|
||||
@Override
|
||||
public int docValueCount() {
|
||||
return current.length;
|
||||
}
|
||||
@Override
|
||||
public long nextValue() {
|
||||
return current[i++];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Dates wrapDates(long[][] values) {
|
||||
return new Dates(new AbstractSortedNumericDocValues() {
|
||||
long[] current;
|
||||
int i;
|
||||
@Override
|
||||
public boolean advanceExact(int doc) {
|
||||
current = values[doc];
|
||||
i = 0;
|
||||
return current.length > 0;
|
||||
}
|
||||
@Override
|
||||
public int docValueCount() {
|
||||
return current.length;
|
||||
}
|
||||
@Override
|
||||
public long nextValue() {
|
||||
return current[i++];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static MultiGeoPointValues wrap(final GeoPoint... points) {
|
||||
return new MultiGeoPointValues() {
|
||||
int docID = -1;
|
||||
int i;
|
||||
@Override
|
||||
public GeoPoint nextValue() {
|
||||
if (docID != 0) {
|
||||
fail();
|
||||
}
|
||||
return points[i++];
|
||||
}
|
||||
@Override
|
||||
public boolean advanceExact(int docId) {
|
||||
docID = docId;
|
||||
return points.length > 0;
|
||||
}
|
||||
@Override
|
||||
public int docValueCount() {
|
||||
if (docID != 0) {
|
||||
return 0;
|
||||
}
|
||||
return points.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -120,7 +120,8 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste
|
|||
this.scheduler = new SchedulerEngine(clock);
|
||||
this.licenseState = licenseState;
|
||||
this.operationModeFileWatcher = new OperationModeFileWatcher(resourceWatcherService,
|
||||
XPackPlugin.resolveConfigFile(env, "license_mode"), logger, () -> updateLicenseState(getLicense()));
|
||||
XPackPlugin.resolveConfigFile(env, "license_mode"), logger,
|
||||
() -> updateLicenseState(getLicensesMetaData()));
|
||||
this.scheduler.register(this);
|
||||
populateExpirationCallbacks();
|
||||
}
|
||||
|
@ -265,11 +266,11 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste
|
|||
|
||||
@Override
|
||||
public void triggered(SchedulerEngine.Event event) {
|
||||
final LicensesMetaData licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE);
|
||||
final LicensesMetaData licensesMetaData = getLicensesMetaData();
|
||||
if (licensesMetaData != null) {
|
||||
final License license = licensesMetaData.getLicense();
|
||||
if (event.getJobName().equals(LICENSE_JOB)) {
|
||||
updateLicenseState(license);
|
||||
updateLicenseState(license, licensesMetaData.getMostRecentTrialVersion());
|
||||
} else if (event.getJobName().startsWith(ExpirationCallback.EXPIRATION_JOB_PREFIX)) {
|
||||
expirationCallbacks.stream()
|
||||
.filter(expirationCallback -> expirationCallback.getId().equals(event.getJobName()))
|
||||
|
@ -311,6 +312,10 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste
|
|||
return license == LicensesMetaData.LICENSE_TOMBSTONE ? null : license;
|
||||
}
|
||||
|
||||
private LicensesMetaData getLicensesMetaData() {
|
||||
return this.clusterService.state().metaData().custom(LicensesMetaData.TYPE);
|
||||
}
|
||||
|
||||
void startTrialLicense(PostStartTrialRequest request, final ActionListener<PostStartTrialResponse> listener) {
|
||||
if (VALID_TRIAL_TYPES.contains(request.getType()) == false) {
|
||||
throw new IllegalArgumentException("Cannot start trial of type [" + request.getType() + "]. Valid trial types are "
|
||||
|
@ -422,10 +427,16 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste
|
|||
}
|
||||
}
|
||||
|
||||
protected void updateLicenseState(final License license) {
|
||||
private void updateLicenseState(LicensesMetaData licensesMetaData) {
|
||||
if (licensesMetaData != null) {
|
||||
updateLicenseState(getLicense(licensesMetaData), licensesMetaData.getMostRecentTrialVersion());
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateLicenseState(final License license, Version mostRecentTrialVersion) {
|
||||
if (license == LicensesMetaData.LICENSE_TOMBSTONE) {
|
||||
// implies license has been explicitly deleted
|
||||
licenseState.update(License.OperationMode.MISSING, false);
|
||||
licenseState.update(License.OperationMode.MISSING, false, mostRecentTrialVersion);
|
||||
return;
|
||||
}
|
||||
if (license != null) {
|
||||
|
@ -438,7 +449,7 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste
|
|||
// date that is near Long.MAX_VALUE
|
||||
active = time >= license.issueDate() && time - GRACE_PERIOD_DURATION.getMillis() < license.expiryDate();
|
||||
}
|
||||
licenseState.update(license.operationMode(), active);
|
||||
licenseState.update(license.operationMode(), active, mostRecentTrialVersion);
|
||||
|
||||
if (active) {
|
||||
if (time < license.expiryDate()) {
|
||||
|
@ -480,7 +491,7 @@ public class LicenseService extends AbstractLifecycleComponent implements Cluste
|
|||
logger.info("license [{}] mode [{}] - valid", license.uid(),
|
||||
license.operationMode().name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
updateLicenseState(license);
|
||||
updateLicenseState(license, currentLicensesMetaData.getMostRecentTrialVersion());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
*/
|
||||
package org.elasticsearch.license;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.logging.LoggerMessageFormat;
|
||||
import org.elasticsearch.common.logging.Loggers;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.license.License.OperationMode;
|
||||
import org.elasticsearch.xpack.core.XPackField;
|
||||
|
@ -266,6 +269,7 @@ public class XPackLicenseState {
|
|||
private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
|
||||
private final boolean isSecurityEnabled;
|
||||
private final boolean isSecurityExplicitlyEnabled;
|
||||
private volatile boolean isSecurityEnabledByTrialVersion;
|
||||
|
||||
public XPackLicenseState(Settings settings) {
|
||||
this.isSecurityEnabled = XPackSettings.SECURITY_ENABLED.get(settings);
|
||||
|
@ -274,11 +278,30 @@ public class XPackLicenseState {
|
|||
// setting is not explicitly set
|
||||
this.isSecurityExplicitlyEnabled = isSecurityEnabled &&
|
||||
(settings.hasValue(XPackSettings.SECURITY_ENABLED.getKey()) || XPackSettings.TRANSPORT_SSL_ENABLED.get(settings));
|
||||
this.isSecurityEnabledByTrialVersion = false;
|
||||
}
|
||||
|
||||
/** Updates the current state of the license, which will change what features are available. */
|
||||
void update(OperationMode mode, boolean active) {
|
||||
/**
|
||||
* Updates the current state of the license, which will change what features are available.
|
||||
*
|
||||
* @param mode The mode (type) of the current license.
|
||||
* @param active True if the current license exists and is within its allowed usage period; false if it is expired or missing.
|
||||
* @param mostRecentTrialVersion If this cluster has, at some point commenced a trial, the most recent version on which they did that.
|
||||
* May be {@code null} if they have never generated a trial license on this cluster, or the most recent
|
||||
* trial was prior to this metadata being tracked (6.1)
|
||||
*/
|
||||
void update(OperationMode mode, boolean active, @Nullable Version mostRecentTrialVersion) {
|
||||
status = new Status(mode, active);
|
||||
if (isSecurityEnabled == true && isSecurityExplicitlyEnabled == false && mode == OperationMode.TRIAL
|
||||
&& isSecurityEnabledByTrialVersion == false) {
|
||||
// Before 6.3, Trial licenses would default having security enabled.
|
||||
// If this license was generated before that version, then treat it as if security is explicitly enabled
|
||||
if (mostRecentTrialVersion == null || mostRecentTrialVersion.before(Version.V_6_3_0)) {
|
||||
Loggers.getLogger(getClass()).info("Automatically enabling security for older trial license ({})",
|
||||
mostRecentTrialVersion == null ? "[pre 6.1.0]" : mostRecentTrialVersion.toString());
|
||||
isSecurityEnabledByTrialVersion = true;
|
||||
}
|
||||
}
|
||||
listeners.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
|
@ -603,6 +626,6 @@ public class XPackLicenseState {
|
|||
|
||||
public boolean isSecurityEnabled() {
|
||||
final OperationMode mode = status.mode;
|
||||
return mode == OperationMode.TRIAL ? isSecurityExplicitlyEnabled : isSecurityEnabled;
|
||||
return mode == OperationMode.TRIAL ? (isSecurityExplicitlyEnabled || isSecurityEnabledByTrialVersion) : isSecurityEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package org.elasticsearch.license;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.RandomizedTest;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -353,20 +354,22 @@ public class TestUtils {
|
|||
public static class AssertingLicenseState extends XPackLicenseState {
|
||||
public final List<License.OperationMode> modeUpdates = new ArrayList<>();
|
||||
public final List<Boolean> activeUpdates = new ArrayList<>();
|
||||
public final List<Version> trialVersionUpdates = new ArrayList<>();
|
||||
|
||||
public AssertingLicenseState() {
|
||||
super(Settings.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
void update(License.OperationMode mode, boolean active) {
|
||||
void update(License.OperationMode mode, boolean active, Version mostRecentTrialVersion) {
|
||||
modeUpdates.add(mode);
|
||||
activeUpdates.add(active);
|
||||
trialVersionUpdates.add(mostRecentTrialVersion);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A license state that makes the {@link #update(License.OperationMode, boolean)}
|
||||
* A license state that makes the {@link #update(License.OperationMode, boolean, Version)}
|
||||
* method public for use in tests.
|
||||
*/
|
||||
public static class UpdatableLicenseState extends XPackLicenseState {
|
||||
|
@ -379,8 +382,8 @@ public class TestUtils {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void update(License.OperationMode mode, boolean active) {
|
||||
super.update(mode, active);
|
||||
public void update(License.OperationMode mode, boolean active, Version mostRecentTrialVersion) {
|
||||
super.update(mode, active, mostRecentTrialVersion);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
*/
|
||||
package org.elasticsearch.license;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.license.License.OperationMode;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.VersionUtils;
|
||||
import org.elasticsearch.xpack.core.XPackField;
|
||||
import org.elasticsearch.xpack.core.XPackSettings;
|
||||
|
||||
|
@ -31,7 +33,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
/** Creates a license state with the given license type and active state, and checks the given method returns expected. */
|
||||
void assertAllowed(OperationMode mode, boolean active, Predicate<XPackLicenseState> predicate, boolean expected) {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(mode, active);
|
||||
licenseState.update(mode, active, null);
|
||||
assertEquals(expected, predicate.test(licenseState));
|
||||
}
|
||||
|
||||
|
@ -102,7 +104,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityBasic() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(BASIC, true);
|
||||
licenseState.update(BASIC, true, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(false));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(false));
|
||||
|
@ -116,7 +118,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityBasicExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(BASIC, false);
|
||||
licenseState.update(BASIC, false, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(false));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(false));
|
||||
|
@ -130,7 +132,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityStandard() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(STANDARD, true);
|
||||
licenseState.update(STANDARD, true, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(false));
|
||||
|
@ -144,7 +146,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityStandardExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(STANDARD, false);
|
||||
licenseState.update(STANDARD, false, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(false));
|
||||
|
@ -158,7 +160,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityGold() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(GOLD, true);
|
||||
licenseState.update(GOLD, true, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(true));
|
||||
|
@ -172,7 +174,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityGoldExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(GOLD, false);
|
||||
licenseState.update(GOLD, false, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(true));
|
||||
|
@ -186,7 +188,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityPlatinum() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(PLATINUM, true);
|
||||
licenseState.update(PLATINUM, true, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(true));
|
||||
|
@ -200,7 +202,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
public void testSecurityPlatinumExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
|
||||
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
|
||||
licenseState.update(PLATINUM, false);
|
||||
licenseState.update(PLATINUM, false, null);
|
||||
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(true));
|
||||
|
@ -211,6 +213,34 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(false));
|
||||
}
|
||||
|
||||
public void testNewTrialDefaultsSecurityOff() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(TRIAL, true, VersionUtils.randomVersionBetween(random(), Version.V_6_3_0, Version.CURRENT));
|
||||
|
||||
assertThat(licenseState.isSecurityEnabled(), is(false));
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(true));
|
||||
assertThat(licenseState.isAuditingAllowed(), is(true));
|
||||
assertThat(licenseState.isStatsAndHealthAllowed(), is(true));
|
||||
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true));
|
||||
assertThat(licenseState.allowedRealmType(), is(XPackLicenseState.AllowedRealmType.ALL));
|
||||
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(true));
|
||||
}
|
||||
|
||||
public void testOldTrialDefaultsSecurityOn() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(TRIAL, true, rarely() ? null : VersionUtils.randomVersionBetween(random(), Version.V_5_6_0, Version.V_6_2_4));
|
||||
|
||||
assertThat(licenseState.isSecurityEnabled(), is(true));
|
||||
assertThat(licenseState.isAuthAllowed(), is(true));
|
||||
assertThat(licenseState.isIpFilteringAllowed(), is(true));
|
||||
assertThat(licenseState.isAuditingAllowed(), is(true));
|
||||
assertThat(licenseState.isStatsAndHealthAllowed(), is(true));
|
||||
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true));
|
||||
assertThat(licenseState.allowedRealmType(), is(XPackLicenseState.AllowedRealmType.ALL));
|
||||
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(true));
|
||||
}
|
||||
|
||||
public void testSecurityAckBasicToNotGoldOrStandard() {
|
||||
OperationMode toMode = randomFrom(OperationMode.values(), mode -> mode != GOLD && mode != STANDARD);
|
||||
assertAckMesssages(XPackField.SECURITY, BASIC, toMode, 0);
|
||||
|
@ -354,7 +384,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlBasic() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(BASIC, true);
|
||||
licenseState.update(BASIC, true, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(true));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
@ -362,7 +392,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlBasicExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(BASIC, false);
|
||||
licenseState.update(BASIC, false, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(false));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
@ -370,7 +400,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlStandard() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(STANDARD, true);
|
||||
licenseState.update(STANDARD, true, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(true));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
@ -378,7 +408,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlStandardExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(STANDARD, false);
|
||||
licenseState.update(STANDARD, false, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(false));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
@ -386,7 +416,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlGold() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(GOLD, true);
|
||||
licenseState.update(GOLD, true, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(true));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
@ -394,7 +424,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlGoldExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(GOLD, false);
|
||||
licenseState.update(GOLD, false, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(false));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
@ -402,7 +432,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlPlatinum() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(PLATINUM, true);
|
||||
licenseState.update(PLATINUM, true, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(true));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(true));
|
||||
|
@ -410,7 +440,7 @@ public class XPackLicenseStateTests extends ESTestCase {
|
|||
|
||||
public void testSqlPlatinumExpired() {
|
||||
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
|
||||
licenseState.update(PLATINUM, false);
|
||||
licenseState.update(PLATINUM, false, null);
|
||||
|
||||
assertThat(licenseState.isSqlAllowed(), is(false));
|
||||
assertThat(licenseState.isJdbcAllowed(), is(false));
|
||||
|
|
|
@ -99,7 +99,7 @@ public class MachineLearningLicensingTests extends BaseMlIntegTestCase {
|
|||
PutJobAction.Response response = putJobListener.actionGet();
|
||||
assertNotNull(response);
|
||||
}
|
||||
|
||||
|
||||
// Pick a license that does not allow machine learning
|
||||
License.OperationMode mode = randomInvalidLicenseType();
|
||||
enableLicensing(mode);
|
||||
|
@ -151,7 +151,7 @@ public class MachineLearningLicensingTests extends BaseMlIntegTestCase {
|
|||
PutJobAction.Response putJobResponse = putJobListener.actionGet();
|
||||
assertNotNull(putJobResponse);
|
||||
}
|
||||
|
||||
|
||||
// Pick a license that does not allow machine learning
|
||||
License.OperationMode mode = randomInvalidLicenseType();
|
||||
enableLicensing(mode);
|
||||
|
@ -551,7 +551,7 @@ public class MachineLearningLicensingTests extends BaseMlIntegTestCase {
|
|||
|
||||
public static void disableLicensing(License.OperationMode operationMode) {
|
||||
for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) {
|
||||
licenseState.update(operationMode, false);
|
||||
licenseState.update(operationMode, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,7 +561,7 @@ public class MachineLearningLicensingTests extends BaseMlIntegTestCase {
|
|||
|
||||
public static void enableLicensing(License.OperationMode operationMode) {
|
||||
for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) {
|
||||
licenseState.update(operationMode, true);
|
||||
licenseState.update(operationMode, true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,7 +307,7 @@ public class LicensingTests extends SecurityIntegTestCase {
|
|||
|
||||
public static void disableLicensing(License.OperationMode operationMode) {
|
||||
for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) {
|
||||
licenseState.update(operationMode, false);
|
||||
licenseState.update(operationMode, false, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,7 +317,7 @@ public class LicensingTests extends SecurityIntegTestCase {
|
|||
|
||||
public static void enableLicensing(License.OperationMode operationMode) {
|
||||
for (XPackLicenseState licenseState : internalCluster().getInstances(XPackLicenseState.class)) {
|
||||
licenseState.update(operationMode, true);
|
||||
licenseState.update(operationMode, true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -399,7 +399,8 @@ public class SecurityTests extends ESTestCase {
|
|||
createComponents(Settings.EMPTY);
|
||||
Function<String, Predicate<String>> fieldFilter = security.getFieldFilter();
|
||||
assertNotSame(MapperPlugin.NOOP_FIELD_FILTER, fieldFilter);
|
||||
licenseState.update(randomFrom(License.OperationMode.BASIC, License.OperationMode.STANDARD, License.OperationMode.GOLD), true);
|
||||
licenseState.update(
|
||||
randomFrom(License.OperationMode.BASIC, License.OperationMode.STANDARD, License.OperationMode.GOLD), true, null);
|
||||
assertNotSame(MapperPlugin.NOOP_FIELD_FILTER, fieldFilter);
|
||||
assertSame(MapperPlugin.NOOP_FIELD_PREDICATE, fieldFilter.apply(randomAlphaOfLengthBetween(3, 6)));
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ public class CompositeRolesStoreTests extends ESTestCase {
|
|||
|
||||
UpdatableLicenseState xPackLicenseState = new UpdatableLicenseState(SECURITY_ENABLED_SETTINGS);
|
||||
// these licenses don't allow custom role providers
|
||||
xPackLicenseState.update(randomFrom(OperationMode.BASIC, OperationMode.GOLD, OperationMode.STANDARD), true);
|
||||
xPackLicenseState.update(randomFrom(OperationMode.BASIC, OperationMode.GOLD, OperationMode.STANDARD), true, null);
|
||||
CompositeRolesStore compositeRolesStore = new CompositeRolesStore(
|
||||
Settings.EMPTY, fileRolesStore, nativeRolesStore, reservedRolesStore,
|
||||
Arrays.asList(inMemoryProvider), new ThreadContext(Settings.EMPTY), xPackLicenseState);
|
||||
|
@ -427,7 +427,7 @@ public class CompositeRolesStoreTests extends ESTestCase {
|
|||
Settings.EMPTY, fileRolesStore, nativeRolesStore, reservedRolesStore,
|
||||
Arrays.asList(inMemoryProvider), new ThreadContext(Settings.EMPTY), xPackLicenseState);
|
||||
// these licenses allow custom role providers
|
||||
xPackLicenseState.update(randomFrom(OperationMode.PLATINUM, OperationMode.TRIAL), true);
|
||||
xPackLicenseState.update(randomFrom(OperationMode.PLATINUM, OperationMode.TRIAL), true, null);
|
||||
roleNames = Sets.newHashSet("roleA");
|
||||
future = new PlainActionFuture<>();
|
||||
fieldPermissionsCache = new FieldPermissionsCache(Settings.EMPTY);
|
||||
|
@ -441,7 +441,7 @@ public class CompositeRolesStoreTests extends ESTestCase {
|
|||
compositeRolesStore = new CompositeRolesStore(
|
||||
Settings.EMPTY, fileRolesStore, nativeRolesStore, reservedRolesStore,
|
||||
Arrays.asList(inMemoryProvider), new ThreadContext(Settings.EMPTY), xPackLicenseState);
|
||||
xPackLicenseState.update(randomFrom(OperationMode.PLATINUM, OperationMode.TRIAL), false);
|
||||
xPackLicenseState.update(randomFrom(OperationMode.PLATINUM, OperationMode.TRIAL), false, null);
|
||||
roleNames = Sets.newHashSet("roleA");
|
||||
future = new PlainActionFuture<>();
|
||||
fieldPermissionsCache = new FieldPermissionsCache(Settings.EMPTY);
|
||||
|
|
|
@ -48,7 +48,7 @@ public class SamlBaseRestHandlerTests extends ESTestCase {
|
|||
.put(XPackSettings.SECURITY_ENABLED.getKey(), true)
|
||||
.build();
|
||||
final TestUtils.UpdatableLicenseState licenseState = new TestUtils.UpdatableLicenseState(settings);
|
||||
licenseState.update(licenseMode, true);
|
||||
licenseState.update(licenseMode, true, null);
|
||||
|
||||
return new SamlBaseRestHandler(settings, licenseState) {
|
||||
|
||||
|
@ -64,4 +64,4 @@ public class SamlBaseRestHandlerTests extends ESTestCase {
|
|||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ public class ADLdapUserSearchSessionFactoryTests extends AbstractActiveDirectory
|
|||
Settings.Builder builder = Settings.builder()
|
||||
.put(globalSettings);
|
||||
settings.keySet().forEach(k -> {
|
||||
builder.copy("xpack.security.authc.realms.ldap." + k, k, settings);
|
||||
builder.copy("xpack.security.authc.realms.ad-as-ldap-test." + k, k, settings);
|
||||
|
||||
});
|
||||
Settings fullSettings = builder.build();
|
||||
|
|
|
@ -12,6 +12,7 @@ import org.elasticsearch.common.settings.SecureString;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.common.util.concurrent.UncategorizedExecutionException;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.env.TestEnvironment;
|
||||
import org.elasticsearch.threadpool.TestThreadPool;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
|
@ -59,9 +60,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testAdAuth() throws Exception {
|
||||
RealmConfig config = new RealmConfig("ad-test",
|
||||
buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false),
|
||||
globalSettings, TestEnvironment.newEnvironment(globalSettings), new ThreadContext(Settings.EMPTY));
|
||||
RealmConfig config = configureRealm("ad-test", buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false));
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
String userName = "ironman";
|
||||
|
@ -82,11 +81,21 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
}
|
||||
}
|
||||
|
||||
private RealmConfig configureRealm(String name, Settings settings) {
|
||||
final Environment env = TestEnvironment.newEnvironment(globalSettings);
|
||||
final Settings mergedSettings = Settings.builder()
|
||||
.put(settings)
|
||||
.normalizePrefix("xpack.security.authc.realms." + name + ".")
|
||||
.put(globalSettings)
|
||||
.build();
|
||||
this.sslService = new SSLService(mergedSettings, env);
|
||||
return new RealmConfig(name, settings, globalSettings, env, new ThreadContext(globalSettings));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testNetbiosAuth() throws Exception {
|
||||
final String adUrl = randomFrom(AD_LDAP_URL, AD_LDAP_GC_URL);
|
||||
RealmConfig config = new RealmConfig("ad-test", buildAdSettings(adUrl, AD_DOMAIN, false), globalSettings,
|
||||
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", buildAdSettings(adUrl, AD_DOMAIN, false));
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
String userName = "ades\\ironman";
|
||||
|
@ -108,8 +117,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
}
|
||||
|
||||
public void testAdAuthAvengers() throws Exception {
|
||||
RealmConfig config = new RealmConfig("ad-test", buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false), globalSettings,
|
||||
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false));
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
String[] users = new String[]{"cap", "hawkeye", "hulk", "ironman", "thor", "blackwidow"};
|
||||
|
@ -126,8 +134,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
public void testAuthenticate() throws Exception {
|
||||
Settings settings = buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com",
|
||||
LdapSearchScope.ONE_LEVEL, false);
|
||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", settings);
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
String userName = "hulk";
|
||||
|
@ -151,8 +158,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
public void testAuthenticateBaseUserSearch() throws Exception {
|
||||
Settings settings = buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Bruce Banner, CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com",
|
||||
LdapSearchScope.BASE, false);
|
||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", settings);
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
String userName = "hulk";
|
||||
|
@ -180,8 +186,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
"CN=Avengers,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
||||
.put(ActiveDirectorySessionFactorySettings.AD_GROUP_SEARCH_SCOPE_SETTING, LdapSearchScope.BASE)
|
||||
.build();
|
||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", settings);
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
String userName = "hulk";
|
||||
|
@ -198,8 +203,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
public void testAuthenticateWithUserPrincipalName() throws Exception {
|
||||
Settings settings = buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com",
|
||||
LdapSearchScope.ONE_LEVEL, false);
|
||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", settings);
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
//Login with the UserPrincipalName
|
||||
|
@ -220,8 +224,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
public void testAuthenticateWithSAMAccountName() throws Exception {
|
||||
Settings settings = buildAdSettings(AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com",
|
||||
LdapSearchScope.ONE_LEVEL, false);
|
||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", settings);
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
//login with sAMAccountName
|
||||
|
@ -247,8 +250,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
.put(ActiveDirectorySessionFactorySettings.AD_USER_SEARCH_FILTER_SETTING,
|
||||
"(&(objectclass=user)(userPrincipalName={0}@ad.test.elasticsearch.com))")
|
||||
.build();
|
||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-test", settings);
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
//Login with the UserPrincipalName
|
||||
|
@ -284,8 +286,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
.putList("ssl.certificate_authorities", certificatePaths)
|
||||
.build();
|
||||
}
|
||||
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-as-ldap-test", settings);
|
||||
LdapSessionFactory sessionFactory = new LdapSessionFactory(config, sslService, threadPool);
|
||||
|
||||
String user = "Bruce Banner";
|
||||
|
@ -348,8 +349,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
.putList("ssl.certificate_authorities", certificatePaths)
|
||||
.build();
|
||||
}
|
||||
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||
new ThreadContext(globalSettings));
|
||||
RealmConfig config = configureRealm("ad-as-ldap-test", settings);
|
||||
LdapSessionFactory sessionFactory = new LdapSessionFactory(config, sslService, threadPool);
|
||||
|
||||
String user = "Bruce Banner";
|
||||
|
@ -366,9 +366,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryT
|
|||
}
|
||||
|
||||
public void testADLookup() throws Exception {
|
||||
RealmConfig config = new RealmConfig("ad-test",
|
||||
buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false, true),
|
||||
globalSettings, TestEnvironment.newEnvironment(globalSettings), new ThreadContext(Settings.EMPTY));
|
||||
RealmConfig config = configureRealm("ad-test", buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false, true));
|
||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||
|
||||
List<String> users = randomSubsetOf(Arrays.asList("cap", "hawkeye", "hulk", "ironman", "thor", "blackwidow",
|
||||
|
|
Loading…
Reference in New Issue