mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2024-12-24 08:00:00 -06:00
improve type-safe intention mapping
This commit is contained in:
parent
35871718d5
commit
a1834ca5ef
@ -15,6 +15,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
@ -97,8 +98,8 @@ public class ParsedOp implements LongFunction<Map<String, ?>>, StaticFieldReader
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefinedDynamic(String field) {
|
||||
return tmap.isDefinedDynamic(field);
|
||||
public boolean isDynamic(String field) {
|
||||
return tmap.isDynamic(field);
|
||||
}
|
||||
|
||||
|
||||
@ -261,15 +262,18 @@ public class ParsedOp implements LongFunction<Map<String, ?>>, StaticFieldReader
|
||||
* @param type The value type which the field must be assignable to
|
||||
* @return A function which can provide a value for the given name and type
|
||||
*/
|
||||
public <V> Optional<LongFunction<V>> getAsOptionalFunction(String name, Class<? extends V> type) {
|
||||
public <V> Optional<LongFunction<V>> getAsOptionalFunction(String name, Class<V> type) {
|
||||
return tmap.getAsOptionalFunction(name, type);
|
||||
}
|
||||
public <V extends Enum<V>> Optional<LongFunction<V>> getAsOptionalEnumFunction(String name, Class<V> type) {
|
||||
return tmap.getAsOptionalEnumFunction(name, type);
|
||||
}
|
||||
|
||||
public <V> Optional<LongFunction<String>> getAsOptionalFunction(String name) {
|
||||
return this.getAsOptionalFunction(name, String.class);
|
||||
}
|
||||
|
||||
public <V> LongFunction<? extends V> getAsRequiredFunction(String name, Class<? extends V> type) {
|
||||
public <V> LongFunction<V> getAsRequiredFunction(String name, Class<? extends V> type) {
|
||||
return tmap.getAsRequiredFunction(name, type);
|
||||
}
|
||||
|
||||
@ -289,8 +293,8 @@ public class ParsedOp implements LongFunction<Map<String, ?>>, StaticFieldReader
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a LongFunction that first creates a LongFunction of String as in {@link #getAsFunction(String, Class)}, but then
|
||||
* applies the result and cached it for subsequent access. This relies on {@link ObjectCache} internally.
|
||||
* Get a LongFunction that first creates a LongFunction of String as in {@link #getAsRequiredFunction(String, Class)}, but then
|
||||
* applies the result and caches it for subsequent access. This relies on {@link ObjectCache} internally.
|
||||
*
|
||||
* @param fieldname The name of the field which could contain a static or dynamic value
|
||||
* @param defaultValue The default value to use in the init function if the fieldname is not defined as static nor dynamic
|
||||
@ -420,12 +424,32 @@ public class ParsedOp implements LongFunction<Map<String, ?>>, StaticFieldReader
|
||||
* @return Optionally, an enum value which matches, or {@link Optional#empty()}
|
||||
* @throws OpConfigError if more than one field matches
|
||||
*/
|
||||
public <E extends Enum<E>> Optional<NamedTarget<E>> getTypeFromEnum(Class<E> enumclass) {
|
||||
return tmap.getOptionalTypeFromEnum(enumclass);
|
||||
public <E extends Enum<E>,V> Optional<TypeAndTarget<E,V>> getTypeFromEnum(Class<E> enumclass, Class<V> valueClass) {
|
||||
return tmap.getOptionalTargetEnum(enumclass,valueClass);
|
||||
}
|
||||
|
||||
public <E extends Enum<E>> NamedTarget<E> getRequiredTypeFromEnum(Class<E> enumclass) {
|
||||
return tmap.getRequiredTypeFromEnum(enumclass);
|
||||
public <E extends Enum<E>,V> Optional<TypeAndTarget<E,V>> getOptionalTargetEnum(
|
||||
Class<E> enumclass,
|
||||
Class<V> valueClass
|
||||
){
|
||||
return tmap.getOptionalTargetEnum(enumclass,valueClass);
|
||||
}
|
||||
|
||||
public <E extends Enum<E>,V> Optional<TypeAndTarget<E,V>> getOptionalTargetEnum(
|
||||
Class<E> enumclass,
|
||||
Class<V> valueClass,
|
||||
String alternateTypeField,
|
||||
String alternateValueField
|
||||
) {
|
||||
return tmap.getOptionalTargetEnum(enumclass, valueClass, alternateTypeField, alternateValueField);
|
||||
}
|
||||
|
||||
public <E extends Enum<E>,V> TypeAndTarget<E,V> getTargetEnum(Class<E> enumclass, Class<V> valueClass) {
|
||||
return tmap.getTargetEnum(enumclass, valueClass);
|
||||
}
|
||||
|
||||
public <E extends Enum<E>,V> TypeAndTarget<E,V> getTargetEnum(Class<E> enumclass, Class<V> valueclass, String tname, String vname) {
|
||||
return tmap.getTargetEnum(enumclass, valueclass,tname,vname);
|
||||
}
|
||||
|
||||
public <E extends Enum<E>> Optional<E> getOptionalEnumFromField(Class<E> enumclass, String fieldName) {
|
||||
@ -435,4 +459,67 @@ public class ParsedOp implements LongFunction<Map<String, ?>>, StaticFieldReader
|
||||
public <E extends Enum<E>> E getEnumFromFieldOr(Class<E> enumClass, E defaultEnum, String fieldName) {
|
||||
return getOptionalEnumFromField(enumClass,fieldName).orElse(defaultEnum);
|
||||
}
|
||||
|
||||
public <FA,FE> Optional<LongFunction<FA>> enhance(
|
||||
Optional<LongFunction<FA>> func,
|
||||
String field,
|
||||
Class<FE> type,
|
||||
FE defaultFe,
|
||||
BiFunction<FA,FE,FA> combiner
|
||||
) {
|
||||
if (func.isEmpty()) {
|
||||
return func;
|
||||
}
|
||||
LongFunction<FE> fieldEnhancerFunc = getAsFunctionOr(field, defaultFe);
|
||||
LongFunction<FA> faLongFunction = func.get();
|
||||
LongFunction<FA> lfa = l -> combiner.apply(faLongFunction.apply(l),fieldEnhancerFunc.apply(l));
|
||||
return Optional.of(lfa);
|
||||
}
|
||||
|
||||
public <FA,FE> Optional<LongFunction<FA>> enhance(
|
||||
Optional<LongFunction<FA>> func,
|
||||
String field,
|
||||
Class<FE> type,
|
||||
BiFunction<FA,FE,FA> combiner
|
||||
) {
|
||||
Optional<LongFunction<FE>> fieldEnhancerFunc = getAsOptionalFunction(field, type);
|
||||
if (func.isEmpty()||fieldEnhancerFunc.isEmpty()) {
|
||||
return func;
|
||||
}
|
||||
LongFunction<FA> faLongFunction = func.get();
|
||||
LongFunction<FE> feLongFunction = fieldEnhancerFunc.get();
|
||||
LongFunction<FA> lfa = l -> combiner.apply(faLongFunction.apply(l),feLongFunction.apply(l));
|
||||
return Optional.of(lfa);
|
||||
}
|
||||
|
||||
public <FA,FE> LongFunction<FA> enhance(
|
||||
LongFunction<FA> func,
|
||||
String field,
|
||||
Class<FE> type,
|
||||
BiFunction<FA,FE,FA> combiner
|
||||
) {
|
||||
Optional<LongFunction<FE>> fieldEnhancerFunc = getAsOptionalFunction(field, type);
|
||||
if (fieldEnhancerFunc.isEmpty()) {
|
||||
return func;
|
||||
}
|
||||
LongFunction<FE> feLongFunction = fieldEnhancerFunc.get();
|
||||
LongFunction<FA> lfa = l -> combiner.apply(func.apply(l),feLongFunction.apply(l));
|
||||
return lfa;
|
||||
}
|
||||
|
||||
public <FA,FE extends Enum<FE>> LongFunction<FA> enhanceEnum(
|
||||
LongFunction<FA> func,
|
||||
String field,
|
||||
Class<FE> type,
|
||||
BiFunction<FA,FE,FA> combiner
|
||||
) {
|
||||
Optional<LongFunction<FE>> fieldEnhancerFunc = getAsOptionalEnumFunction(field, type);
|
||||
if (fieldEnhancerFunc.isEmpty()) {
|
||||
return func;
|
||||
}
|
||||
LongFunction<FE> feLongFunction = fieldEnhancerFunc.get();
|
||||
LongFunction<FA> lfa = l -> combiner.apply(func.apply(l),feLongFunction.apply(l));
|
||||
return lfa;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -107,6 +107,9 @@ public class NBTypeSafeConversions implements NBTypeConverters {
|
||||
return Float.parseFloat(in);
|
||||
}
|
||||
|
||||
public static boolean to_boolean(String in) {
|
||||
return Boolean.parseBoolean(in);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
package io.nosqlbench.engine.api.templating;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
/**
|
||||
* <p>The result type from calling {@link ParsedOp#getRequiredTypeFromEnum(Class)}, which
|
||||
* captures the matching enum type as well as the field name and a value function.</p>
|
||||
*
|
||||
* <p>The <em>enumId</em> is type-safe enum value from the provided enum to the above method.
|
||||
* The <em>field</em> is the field name which was passed. The <em>targetFunction</em> is
|
||||
* a {@link LongFunction} of Object which can be called to return an associated target value.</p>
|
||||
*
|
||||
* For example, with an emum like <pre>{@code
|
||||
* public enum LandMovers {
|
||||
* BullDozer,
|
||||
* DumpTruck
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* and a parsed op like <pre>{@code
|
||||
* (json)
|
||||
* {
|
||||
* "op": {
|
||||
* "bulldozer": "{dozerid}"
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* (yaml)
|
||||
* op:
|
||||
* bulldozer: "{dozerid}
|
||||
* }</pre>
|
||||
* the result will be returned with the following: <pre>{@code
|
||||
* enumId: BullDozer
|
||||
* field: bulldozer
|
||||
* targetFunction: (long l) -> ...
|
||||
* }</pre>
|
||||
* @param <E>
|
||||
*/
|
||||
public class NamedTarget<E extends Enum<E>> {
|
||||
public final E enumId;
|
||||
public final String field;
|
||||
public final LongFunction<?> targetFunction;
|
||||
|
||||
public NamedTarget(E enumId, String matchingOpFieldName, LongFunction<?> value) {
|
||||
this.enumId = enumId;
|
||||
this.field = matchingOpFieldName;
|
||||
this.targetFunction = value;
|
||||
}
|
||||
}
|
@ -367,6 +367,11 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
return getAsRequiredFunction(name, String.class);
|
||||
}
|
||||
|
||||
public <V extends Enum<V>> Optional<LongFunction<V>> getAsOptionalEnumFunction(String name, Class<V> type) {
|
||||
Optional<LongFunction<String>> nameFunc = this.getAsOptionalFunction(name, String.class);
|
||||
return nameFunc.map((f) -> (l) -> Enum.valueOf(type, f.apply(l)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the op field as a {@link LongFunction}
|
||||
*
|
||||
@ -378,11 +383,23 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
public <V> Optional<LongFunction<V>> getAsOptionalFunction(String name, Class<? extends V> type) {
|
||||
if (isStatic(name)) {
|
||||
V value = getStaticValue(name);
|
||||
return Optional.of((cycle) -> value);
|
||||
} else if (isDefinedDynamic(name)) {
|
||||
if (type.isAssignableFrom(value.getClass())) {
|
||||
return Optional.of((cycle) -> value);
|
||||
} else if (NBTypeConverter.canConvert(value, type)) {
|
||||
V converted = NBTypeConverter.convert(value, type);
|
||||
return Optional.of((cycle) -> converted);
|
||||
} else {
|
||||
throw new OpConfigError(
|
||||
"function for '" + name + "' yielded a " + value.getClass().getCanonicalName()
|
||||
+ " type, which is not assignable to a " + type.getCanonicalName() + "'"
|
||||
);
|
||||
}
|
||||
} else if (isDynamic(name)) {
|
||||
Object testValue = dynamics.get(name).apply(0L);
|
||||
if (type.isAssignableFrom(testValue.getClass())) {
|
||||
return Optional.of((LongFunction<V>) dynamics.get(name));
|
||||
} else if (NBTypeConverter.canConvert(testValue, type)) {
|
||||
return Optional.of(l -> NBTypeConverter.convert(dynamics.get(name).apply(l), type));
|
||||
} else {
|
||||
throw new OpConfigError(
|
||||
"function for '" + name + "' yielded a " + testValue.getClass().getCanonicalName()
|
||||
@ -393,8 +410,8 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
}
|
||||
}
|
||||
|
||||
public <V> LongFunction<? extends V> getAsRequiredFunction(String name, Class<? extends V> type) {
|
||||
Optional<? extends LongFunction<? extends V>> sf = getAsOptionalFunction(name, type);
|
||||
public <V> LongFunction<V> getAsRequiredFunction(String name, Class<? extends V> type) {
|
||||
Optional<? extends LongFunction<V>> sf = getAsOptionalFunction(name, type);
|
||||
return sf.orElseThrow(() -> new OpConfigError("The op field '" + name + "' is required, but it wasn't found in the op template."));
|
||||
}
|
||||
|
||||
@ -439,7 +456,7 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
} else {
|
||||
throw new OpConfigError("Unable to compose string to object cache with non-String value of type " + defaultValue.getClass().getCanonicalName());
|
||||
}
|
||||
} else if (isDefinedDynamic(fieldname)) {
|
||||
} else if (isDynamic(fieldname)) {
|
||||
LongFunction<V> f = l -> get(fieldname, l);
|
||||
V testValue = f.apply(0);
|
||||
if (testValue instanceof String) {
|
||||
@ -608,6 +625,55 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
|
||||
}
|
||||
|
||||
|
||||
public <E extends Enum<E>, V> Optional<TypeAndTarget<E, V>> getOptionalTargetEnum(
|
||||
Class<E> enumclass,
|
||||
String typeFieldName,
|
||||
String valueFieldName,
|
||||
Class<V> valueClass
|
||||
) {
|
||||
if (isStatic(typeFieldName)) {
|
||||
String enumValue = statics.get(typeFieldName).toString();
|
||||
E verifiedEnumValue;
|
||||
|
||||
try {
|
||||
verifiedEnumValue = Enum.valueOf(enumclass, enumValue);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
throw new OpConfigError("type designator field '" + typeFieldName + "' had value of '" + enumValue + ", but this failed to match " +
|
||||
"any of known types in " + EnumSet.allOf(enumclass));
|
||||
}
|
||||
|
||||
if (isDefined(valueFieldName)) {
|
||||
if (isStatic(typeFieldName)) {
|
||||
return Optional.of(
|
||||
new TypeAndTarget<E, V>(verifiedEnumValue, typeFieldName, l -> NBTypeConverter.convert(statics.get(valueFieldName), valueClass))
|
||||
);
|
||||
} else if (isDynamic(valueFieldName)) {
|
||||
return Optional.of(
|
||||
new TypeAndTarget<E, V>(verifiedEnumValue, typeFieldName, getAsRequiredFunction(valueFieldName, valueClass))
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (isDynamic(typeFieldName)) {
|
||||
throw new OpConfigError("The op template field '" + typeFieldName + "' must be a static value. You can not vary it by cycle.");
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public <E extends Enum<E>, V> Optional<TypeAndTarget<E, V>> getOptionalTargetEnum(
|
||||
Class<E> enumclass,
|
||||
Class<V> valueClass,
|
||||
String alternateTypeField,
|
||||
String alternateValueField
|
||||
) {
|
||||
Optional<TypeAndTarget<E, V>> result = getOptionalTargetEnum(enumclass, valueClass);
|
||||
if (result.isPresent()) {
|
||||
return result;
|
||||
}
|
||||
return getOptionalTargetEnum(enumclass,alternateTypeField,alternateValueField,valueClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an enum of any type, return the enum value which is found in any of the field names of the op template,
|
||||
* ignoring case and any non-word characters. This is useful for matching op templates to op types where the presence
|
||||
@ -619,37 +685,58 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
* @return Optionally, an enum value which matches, or {@link Optional#empty()}
|
||||
* @throws OpConfigError if more than one field matches
|
||||
*/
|
||||
public <E extends Enum<E>> Optional<NamedTarget<E>> getOptionalTypeFromEnum(Class<E> enumclass) {
|
||||
List<NamedTarget<E>> matched = new ArrayList<>();
|
||||
public <E extends Enum<E>, V> Optional<TypeAndTarget<E, V>> getOptionalTargetEnum(
|
||||
Class<E> enumclass,
|
||||
Class<? extends V> valueClass
|
||||
) {
|
||||
List<TypeAndTarget<E, V>> matched = new ArrayList<>();
|
||||
for (E e : EnumSet.allOf(enumclass)) {
|
||||
String lowerenum = e.name().toLowerCase(Locale.ROOT).replaceAll("[^\\w]", "");
|
||||
for (String s : statics.keySet()) {
|
||||
String lowerkey = s.toLowerCase(Locale.ROOT).replaceAll("[^\\w]", "");
|
||||
if (lowerkey.equals(lowerenum)) {
|
||||
matched.add(new NamedTarget<>(e, s, null));
|
||||
matched.add(new TypeAndTarget<>(e, s, null));
|
||||
}
|
||||
}
|
||||
for (String s : dynamics.keySet()) {
|
||||
String lowerkey = s.toLowerCase(Locale.ROOT).replaceAll("[^\\w]", "");
|
||||
if (lowerkey.equals(lowerenum)) {
|
||||
matched.add(new NamedTarget<>(e, s, null));
|
||||
matched.add(new TypeAndTarget<>(e, s, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matched.size() == 1) {
|
||||
NamedTarget<E> prototype = matched.get(0);
|
||||
LongFunction<? extends String> asFunction = getAsRequiredFunction(prototype.field);
|
||||
return Optional.of(new NamedTarget<>(prototype.enumId, prototype.field, asFunction));
|
||||
}
|
||||
if (matched.size() > 1) {
|
||||
TypeAndTarget<E, V> prototype = matched.get(0);
|
||||
LongFunction<V> asFunction = getAsRequiredFunction(prototype.field, valueClass);
|
||||
return Optional.of(new TypeAndTarget<E, V>(prototype.enumId, prototype.field, asFunction));
|
||||
} else if (matched.size() > 1) {
|
||||
throw new OpConfigError("Multiple matches were found from op template fieldnames ["
|
||||
+ getDefinedNames() + "] to possible enums: [" + EnumSet.allOf(enumclass) + "]");
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public <E extends Enum<E>> NamedTarget<E> getRequiredTypeFromEnum(Class<E> enumclass) {
|
||||
Optional<NamedTarget<E>> typeFromEnum = getOptionalTypeFromEnum(enumclass);
|
||||
public <E extends Enum<E>,V> TypeAndTarget<E,V> getTargetEnum(
|
||||
Class<E> enumclass,
|
||||
Class<V> valueClass,
|
||||
String tname,
|
||||
String vname
|
||||
) {
|
||||
Optional<TypeAndTarget<E, V>> optionalMappedEnum = getOptionalTargetEnum(enumclass, valueClass);
|
||||
if (optionalMappedEnum.isPresent()) {
|
||||
return optionalMappedEnum.get();
|
||||
}
|
||||
Optional<TypeAndTarget<E, V>> optionalSpecifiedEnum = getOptionalTargetEnum(enumclass, tname, vname, valueClass);
|
||||
if (optionalSpecifiedEnum.isPresent()) {
|
||||
return optionalSpecifiedEnum.get();
|
||||
}
|
||||
throw new OpConfigError("Unable to map the type and target for possible values " + EnumSet.allOf(enumclass) +" either by key or by fields " + tname + " and " + vname + ". " +
|
||||
"Fields considered: static:" + statics.keySet() + " dynamic:" + dynamics.keySet());
|
||||
}
|
||||
|
||||
public <E extends Enum<E>, V> TypeAndTarget<E, V> getTargetEnum(Class<E> enumclass, Class<V> valueClass) {
|
||||
Optional<TypeAndTarget<E, V>> typeFromEnum = getOptionalTargetEnum(enumclass, valueClass);
|
||||
|
||||
return typeFromEnum.orElseThrow(
|
||||
() -> {
|
||||
@ -666,12 +753,12 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
/**
|
||||
* Map a named op field to an enum
|
||||
*
|
||||
* @param enumclass The type of enum to look within
|
||||
* @param fieldname The field name to look for
|
||||
* @param <E> The generic type of the enum
|
||||
* @param enumclass The type of enum to look within
|
||||
* @param fieldname The field name to look for
|
||||
* @param <E> The generic type of the enum
|
||||
* @return An optional enum value
|
||||
*/
|
||||
public <E extends Enum<E>> Optional<E> getOptionalEnumFromField(Class<E> enumclass,String fieldname) {
|
||||
public <E extends Enum<E>> Optional<E> getOptionalEnumFromField(Class<E> enumclass, String fieldname) {
|
||||
|
||||
Optional<String> enumField = getOptionalStaticConfig(fieldname, String.class);
|
||||
if (enumField.isEmpty()) {
|
||||
@ -696,4 +783,5 @@ public class ParsedTemplateMap implements LongFunction<Map<String, ?>>, StaticFi
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package io.nosqlbench.engine.api.templating;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
/**
|
||||
* <p>A convenient pattern for users to specify a command is that of <em>type and target</em>. This
|
||||
* emphasizes that users often need to specify what kind of action to take, and what subject to
|
||||
* take the action on. This concept pervades programming, exmplified by a simple <pre>{@code function(object) } call</pre>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* To facilitate this pattern in op templates with the help of type safety, this helper type allows
|
||||
* for the scanning of a map for a matching enum field. If any map key matches one of the possible
|
||||
* enum values, case-insensitively, and with only a single match, then the matching enum value is
|
||||
* taken as a specific type of action, and the matching value in the map is taken as the intended target.
|
||||
*</p>
|
||||
*
|
||||
* <p>Further, the target may be indirect, such as a binding, rather than a specific literal or structured
|
||||
* value. In such cases, only a lambda-style function may be available. The provided <em>targetFunction</em> is
|
||||
* a {@link LongFunction} of Object which can be called to return an associated target value once the
|
||||
* cycle value is known.</p>
|
||||
*
|
||||
* For example, with an enum like <pre>{@code
|
||||
* public enum LandMovers {
|
||||
* BullDozer,
|
||||
* DumpTruck
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* and a parsed op like <pre>{@code
|
||||
* (json)
|
||||
* {
|
||||
* "op": {
|
||||
* "bulldozer": "{dozerid}"
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* (yaml)
|
||||
* op:
|
||||
* bulldozer: "{dozerid}
|
||||
* }</pre>
|
||||
* the result will be returned with the following: <pre>{@code
|
||||
* enumId: (Enum field) BullDozer
|
||||
* field: (String) bulldozer
|
||||
* targetFunction: (long l) -> template function for {dozerid}
|
||||
* }</pre>
|
||||
* @param <E>
|
||||
*/
|
||||
public class TypeAndTarget<E extends Enum<E>,T> {
|
||||
public final E enumId;
|
||||
public final String field;
|
||||
public final LongFunction<T> targetFunction;
|
||||
|
||||
public TypeAndTarget(E enumId, String matchingOpFieldName, LongFunction<T> value) {
|
||||
this.enumId = enumId;
|
||||
this.field = matchingOpFieldName;
|
||||
this.targetFunction = value;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user