Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render ConfigMapping elements properly in the Dev UI Configuration editor #44567

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.Properties;
import java.util.Set;
import java.util.function.Consumer;
Expand Down Expand Up @@ -87,7 +84,7 @@ public void accept(Container node) {
String defaultDefault;
final Class<?> valueClass = field.getType();

EffectiveConfigTypeAndValues effectiveConfigTypeAndValues = getTypeName(field);
EffectiveConfigTypeAndValues effectiveConfigTypeAndValues = getTypeName(valueClass, field.getGenericType());

if (valueClass == boolean.class) {
defaultDefault = "false";
Expand All @@ -112,8 +109,8 @@ public void accept(Container node) {
ret.add(new ConfigDescriptionBuildItem(name,
defVal,
javadoc.getProperty(javadocKey),
effectiveConfigTypeAndValues.getTypeName(),
effectiveConfigTypeAndValues.getAllowedValues(),
effectiveConfigTypeAndValues.typeName(),
effectiveConfigTypeAndValues.allowedValues(),
configPhase));
}
});
Expand Down Expand Up @@ -147,136 +144,75 @@ private void processMappings(List<ConfigClass> mappings, List<ConfigDescriptionB
}

String javadocKey = method.getDeclaringClass().getName().replace('$', '.') + '.' + method.getName();
// TODO - radcortez - Fix nulls
EffectiveConfigTypeAndValues typeName = getTypeName(method.getReturnType(), method.getGenericReturnType());
descriptionBuildItems.add(new ConfigDescriptionBuildItem(propertyName, defaultValue,
javaDocProperties.getProperty(javadocKey), null, null, configPhase));
javaDocProperties.getProperty(javadocKey), typeName.typeName(), typeName.allowedValues(), configPhase));
}
}
}

private EffectiveConfigTypeAndValues getTypeName(Field field) {
final Class<?> valueClass = field.getType();
return getTypeName(field, valueClass);
}

private EffectiveConfigTypeAndValues getTypeName(Field field, Class<?> valueClass) {
EffectiveConfigTypeAndValues typeAndValues = new EffectiveConfigTypeAndValues();
String name = valueClass.getName();
private EffectiveConfigTypeAndValues getTypeName(Class<?> valueClass, Type genericType) {
final String name;
final List<String> allowedValues = new ArrayList<>();

// Extract Optionals, Lists and Sets
if ((valueClass.equals(Optional.class) || valueClass.equals(List.class) || valueClass.equals(Set.class))) {

if (field != null) {
Type genericType = field.getGenericType();
name = genericType.getTypeName();
String thisName = valueClass.getName();
if (genericType != null) {
thisName = genericType.getTypeName();
}

if (name.contains("<") && name.contains(">")) {
name = name.substring(name.lastIndexOf("<") + 1, name.indexOf(">"));
if (thisName.contains("<") && thisName.contains(">")) {
thisName = thisName.substring(thisName.lastIndexOf("<") + 1, thisName.indexOf(">"));
}

try {
Class<?> c = Class.forName(name);
return getTypeName(null, c);
Class<?> c = Class.forName(thisName);
return getTypeName(c, null);
} catch (ClassNotFoundException ex) {
// Then we use the name as is.
}
}

// Check other optionals
if (valueClass.equals(OptionalInt.class)) {
name = Integer.class.getName();
} else if (valueClass.equals(OptionalDouble.class)) {
name = Double.class.getName();
} else if (valueClass.equals(OptionalLong.class)) {
name = Long.class.getName();
}

// Check if this is an enum
if (Enum.class.isAssignableFrom(valueClass)) {
name = thisName;
} else if (Enum.class.isAssignableFrom(valueClass)) {
// Check if this is an enum
name = Enum.class.getName();

Object[] values = valueClass.getEnumConstants();
for (Object v : values) {
Enum casted = (Enum) valueClass.cast(v);
typeAndValues.addAllowedValue(casted.name());
Enum<?> casted = (Enum<?>) valueClass.cast(v);
allowedValues.add(casted.name());
}
} else {
// Map all primitives
name = switch (valueClass.getName()) {
case "java.util.OptionalInt", "int" -> Integer.class.getName();
case "boolean" -> Boolean.class.getName();
case "float" -> Float.class.getName();
case "java.util.OptionalDouble", "double" -> Double.class.getName();
case "java.util.OptionalLong", "long" -> Long.class.getName();
case "byte" -> Byte.class.getName();
case "short" -> Short.class.getName();
case "char" -> Character.class.getName();
default -> valueClass.getName();
};
}

// Special case for Log level
if (valueClass.isAssignableFrom(Level.class)) {
typeAndValues.addAllowedValue(Level.ALL.getName());
typeAndValues.addAllowedValue(Level.CONFIG.getName());
typeAndValues.addAllowedValue(Level.FINE.getName());
typeAndValues.addAllowedValue(Level.FINER.getName());
typeAndValues.addAllowedValue(Level.FINEST.getName());
typeAndValues.addAllowedValue(Level.INFO.getName());
typeAndValues.addAllowedValue(Level.OFF.getName());
typeAndValues.addAllowedValue(Level.SEVERE.getName());
typeAndValues.addAllowedValue(Level.WARNING.getName());
}

// Map all primitives
if (name.equals("int")) {
name = Integer.class.getName();
} else if (name.equals("boolean")) {
name = Boolean.class.getName();
} else if (name.equals("float")) {
name = Float.class.getName();
} else if (name.equals("double")) {
name = Double.class.getName();
} else if (name.equals("long")) {
name = Long.class.getName();
} else if (name.equals("byte")) {
name = Byte.class.getName();
} else if (name.equals("short")) {
name = Short.class.getName();
} else if (name.equals("char")) {
name = Character.class.getName();
}

typeAndValues.setTypeName(name);
return typeAndValues;
allowedValues.add(Level.ALL.getName());
allowedValues.add(Level.CONFIG.getName());
allowedValues.add(Level.FINE.getName());
allowedValues.add(Level.FINER.getName());
allowedValues.add(Level.FINEST.getName());
allowedValues.add(Level.INFO.getName());
allowedValues.add(Level.OFF.getName());
allowedValues.add(Level.SEVERE.getName());
allowedValues.add(Level.WARNING.getName());
}

return new EffectiveConfigTypeAndValues(name, allowedValues);
}

static class EffectiveConfigTypeAndValues {
private String typeName;
private List<String> allowedValues;

public EffectiveConfigTypeAndValues() {

}

public EffectiveConfigTypeAndValues(String typeName) {
this.typeName = typeName;
}

public EffectiveConfigTypeAndValues(String typeName, List<String> allowedValues) {
this.typeName = typeName;
this.allowedValues = allowedValues;
}

public String getTypeName() {
return typeName;
}

public void setTypeName(String typeName) {
this.typeName = typeName;
}

public List<String> getAllowedValues() {
return allowedValues;
}

public void setAllowedValues(List<String> allowedValues) {
this.allowedValues = allowedValues;
}

public void addAllowedValue(String v) {
if (allowedValues == null) {
allowedValues = new ArrayList<>();
}
allowedValues.add(v);
}
private record EffectiveConfigTypeAndValues(String typeName, List<String> allowedValues) {
}
}
Loading