use of org.jboss.hal.dmr.ModelType in project console by hal.
the class ModelNodeMapping method persistModel.
@Override
@SuppressWarnings("unchecked")
public void persistModel(String id, T model, Iterable<FormItem> formItems) {
for (FormItem formItem : formItems) {
String name = formItem.getName();
if (formItem.isModified()) {
ModelNode attributeDescription = findAttribute(name);
if (attributeDescription == null) {
logger.error("{}: Unable to persist attribute '{}': No attribute description found in\n{}", id, name, attributeDescriptions);
continue;
}
if (formItem instanceof ModelNodeItem) {
if (formItem.getValue() == null) {
failSafeRemove(model, name);
} else {
model.get(name).set(((ModelNodeItem) formItem).getValue());
}
} else {
if (formItem.isExpressionValue()) {
model.get(name).setExpression(formItem.getExpressionValue());
} else {
ModelType type = attributeDescription.get(TYPE).asType();
Object value = formItem.getValue();
switch(type) {
case BOOLEAN:
Boolean booleanValue = (Boolean) value;
if (booleanValue == null) {
failSafeRemove(model, name);
} else {
model.get(name).set(booleanValue);
}
break;
case BIG_INTEGER:
case INT:
case LONG:
Long longValue = (Long) value;
if (longValue == null) {
failSafeRemove(model, name);
} else {
if (type == BIG_INTEGER) {
model.get(name).set(BigInteger.valueOf(longValue));
} else if (type == INT) {
model.get(name).set(longValue.intValue());
} else {
model.get(name).set(longValue);
}
}
break;
case DOUBLE:
Double doubleValue = (Double) value;
if (doubleValue == null) {
failSafeRemove(model, name);
} else {
model.get(name).set(doubleValue);
}
break;
case LIST:
List<String> list = (List<String>) value;
if (list == null || list.isEmpty()) {
failSafeRemove(model, name);
} else {
ModelNode listNode = new ModelNode();
for (String s : list) {
listNode.add(s);
}
model.get(name).set(listNode);
}
break;
case OBJECT:
boolean stringValueType = attributeDescription.get(VALUE_TYPE).getType().equals(ModelType.TYPE) && attributeDescription.get(VALUE_TYPE).asType().equals(ModelType.STRING);
if (stringValueType) {
Map<String, String> map = (Map<String, String>) value;
if (map == null || map.isEmpty()) {
failSafeRemove(model, name);
} else {
ModelNode mapNode = new ModelNode();
for (Map.Entry<String, String> entry : map.entrySet()) {
mapNode.get(entry.getKey()).set(entry.getValue());
}
model.get(name).set(mapNode);
}
}
break;
case STRING:
String stringValue = value == null ? null : String.valueOf(value);
if (Strings.isNullOrEmpty(stringValue)) {
failSafeRemove(model, name);
} else {
model.get(name).set(stringValue);
}
break;
// unsupported types
case BIG_DECIMAL:
case BYTES:
case EXPRESSION:
case PROPERTY:
case TYPE:
case UNDEFINED:
logger.warn("{}: persisting form field '{}' to type '{}' not implemented", id, name, type);
break;
default:
break;
}
}
}
}
}
}
use of org.jboss.hal.dmr.ModelType in project console by hal.
the class OperationFactory method resetResource.
/**
* Creates a composite operation which resets the attributes of the specified resource. Only attributes which are nillable,
* w/o alternatives and not read-only will be reset. The composite contains
* {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#UNDEFINE_ATTRIBUTE_OPERATION undefine-attribute} operations for
* each attribute of type {@code EXPRESSION, LIST, OBJECT, PROPERTY} or {@code STRING} and
* {@linkplain org.jboss.hal.dmr.ModelDescriptionConstants#WRITE_ATTRIBUTE_OPERATION write-attribute} operations for
* attributes of type {@code BIG_DECIMAL, BIG_INTEGER, BOOLEAN, BYTES, DOUBLE, INT} or {@code LONG} if they have a default
* value.
*
* @param address the fq address used for the operations
* @param attributes the attributes to reset
* @param metadata the metadata which should contain the attribute definitions of the change-set
* @return a composite to reset the attributes or an empty composite if no attributes could be reset.
*/
Composite resetResource(ResourceAddress address, Set<String> attributes, Metadata metadata) {
List<Operation> operations = new ArrayList<>();
ResourceDescription description = metadata.getDescription();
// collect all attributes from the 'requires' list of this attribute
// HashMultimap<String, String> requires = HashMultimap.create();
TreeSet<String> requires = new TreeSet<>();
ModelNode attributesDescription = description.get(ATTRIBUTES);
attributes.forEach(attribute -> {
ModelNode attributeDescription = attributesDescription.get(attribute);
if (attributeDescription != null && attributeDescription.hasDefined(REQUIRES)) {
failSafeList(attributeDescription, REQUIRES).forEach(node -> requires.add(node.asString()));
/*
* .map(ModelNode::asString) .forEach(requiresName -> { requires.add(requiresName); });
*/
}
});
attributes.stream().map(attribute -> description.findAttribute(ATTRIBUTES, attribute)).filter(Objects::nonNull).forEach(property -> {
ModelNode attributeDescription = property.getValue();
boolean nillable = attributeDescription.hasDefined(NILLABLE) && attributeDescription.get(NILLABLE).asBoolean();
boolean readOnly = attributeDescription.hasDefined(ACCESS_TYPE) && READ_ONLY.equals(attributeDescription.get(ACCESS_TYPE).asString());
boolean alternatives = attributeDescription.hasDefined(ALTERNATIVES) && !attributeDescription.get(ALTERNATIVES).asList().isEmpty();
boolean requiredBy = requires.contains(property.getName());
if (nillable && !readOnly && !alternatives && !requiredBy) {
boolean hasDefault = attributeDescription.hasDefined(DEFAULT);
ModelType type = attributeDescription.get(TYPE).asType();
switch(type) {
case BIG_DECIMAL:
case BIG_INTEGER:
case BOOLEAN:
case BYTES:
case DOUBLE:
case INT:
case LONG:
if (hasDefault) {
operations.add(undefineAttribute(address, property.getName()));
}
break;
case EXPRESSION:
case LIST:
case OBJECT:
case PROPERTY:
case STRING:
operations.add(undefineAttribute(address, property.getName()));
break;
case TYPE:
case UNDEFINED:
break;
default:
break;
}
}
});
return new Composite(operations);
}
use of org.jboss.hal.dmr.ModelType in project console by hal.
the class DefaultFormItemProvider method createFrom.
@Override
public FormItem<?> createFrom(Property property) {
FormItem<?> formItem = null;
String name = property.getName();
String label = labelBuilder.label(property);
ModelNode attributeDescription = property.getValue();
// don't use 'required' here!
boolean required = attributeDescription.hasDefined(NILLABLE) && !attributeDescription.get(NILLABLE).asBoolean();
boolean expressionAllowed = attributeDescription.hasDefined(EXPRESSIONS_ALLOWED) && attributeDescription.get(EXPRESSIONS_ALLOWED).asBoolean();
boolean readOnly = attributeDescription.hasDefined(ACCESS_TYPE) && (READ_ONLY.equals(attributeDescription.get(ACCESS_TYPE).asString()) || METRIC.equals(attributeDescription.get(ACCESS_TYPE).asString()));
String unit = attributeDescription.hasDefined(UNIT) ? attributeDescription.get(UNIT).asString() : null;
Deprecation deprecation = attributeDescription.hasDefined(DEPRECATED) ? new Deprecation(attributeDescription.get(DEPRECATED)) : null;
if (attributeDescription.hasDefined(TYPE)) {
ModelType type = attributeDescription.get(TYPE).asType();
ModelType valueType = (attributeDescription.has(VALUE_TYPE) && attributeDescription.get(VALUE_TYPE).getType() != ModelType.OBJECT) ? ModelType.valueOf(attributeDescription.get(VALUE_TYPE).asString()) : null;
switch(type) {
case BOOLEAN:
{
SwitchItem switchItem = new SwitchItem(name, label);
if (attributeDescription.hasDefined(DEFAULT)) {
switchItem.assignDefaultValue(attributeDescription.get(DEFAULT).asBoolean());
}
formItem = switchItem;
break;
}
case BIG_INTEGER:
case INT:
case LONG:
{
long min, max;
if (type == ModelType.INT) {
min = attributeDescription.get(MIN).asLong(Integer.MIN_VALUE);
max = attributeDescription.get(MAX).asLong(Integer.MAX_VALUE);
} else {
min = attributeDescription.get(MIN).asLong(MIN_SAFE_LONG);
max = attributeDescription.get(MAX).asLong(MAX_SAFE_LONG);
}
NumberItem numberItem = new NumberItem(name, label, unit, min, max);
if (attributeDescription.hasDefined(DEFAULT)) {
long defaultValue = attributeDescription.get(DEFAULT).asLong();
numberItem.assignDefaultValue(defaultValue);
}
formItem = numberItem;
break;
}
case DOUBLE:
{
long min = attributeDescription.get(MIN).asLong(MIN_SAFE_LONG);
long max = attributeDescription.get(MAX).asLong(MAX_SAFE_LONG);
NumberDoubleItem numberItem = new NumberDoubleItem(name, label, unit, min, max);
if (attributeDescription.hasDefined(DEFAULT)) {
double defaultValue = attributeDescription.get(DEFAULT).asDouble();
numberItem.assignDefaultValue(defaultValue);
}
formItem = numberItem;
break;
}
case LIST:
{
if (valueType != null && ModelType.STRING == valueType) {
List<String> allowedValues = stringValues(attributeDescription, ALLOWED);
if (!allowedValues.isEmpty()) {
MultiSelectBoxItem multiSelectBoxItem = new MultiSelectBoxItem(name, label, allowedValues);
if (attributeDescription.hasDefined(DEFAULT)) {
List<String> defaultValues = stringValues(attributeDescription, DEFAULT);
if (!defaultValues.isEmpty()) {
multiSelectBoxItem.assignDefaultValue(defaultValues);
}
}
formItem = multiSelectBoxItem;
} else {
ListItem listItem = new ListItem(name, label);
if (attributeDescription.hasDefined(DEFAULT)) {
List<String> defaultValues = stringValues(attributeDescription, DEFAULT);
if (!defaultValues.isEmpty()) {
listItem.assignDefaultValue(defaultValues);
}
}
formItem = listItem;
checkCapabilityReference(attributeDescription, formItem);
}
} else if (isSimpleTuple(attributeDescription)) {
// process OBJECT type attribute if all of its subattributes are simple types
formItem = new TuplesListItem(name, label, metadata.forComplexAttribute(property.getName()));
} else {
logger.warn("Unsupported model type {} for attribute {} in metadata {}. Unable to create a form item. Attribute will be skipped.", type.name(), property.getName(), metadata.getTemplate());
break;
}
break;
}
case OBJECT:
{
if (valueType != null && ModelType.STRING == valueType) {
PropertiesItem propertiesItem = new PropertiesItem(name, label);
List<Property> properties = ModelNodeHelper.getOrDefault(attributeDescription, DEFAULT, () -> attributeDescription.get(DEFAULT).asPropertyList(), emptyList());
if (!properties.isEmpty()) {
Map<String, String> defaultValues = new HashMap<>();
for (Property p : properties) {
defaultValues.put(p.getName(), p.getValue().asString());
}
propertiesItem.assignDefaultValue(defaultValues);
}
formItem = propertiesItem;
}
break;
}
case STRING:
{
List<String> allowedValues = stringValues(attributeDescription, ALLOWED);
if (allowedValues.isEmpty()) {
FormItem<String> textBoxItem = new TextBoxItem(name, label, null);
boolean sensitive = failSafeGet(attributeDescription, ACCESS_CONSTRAINTS + "/" + SENSITIVE).isDefined();
if (PASSWORD.equals(name) || sensitive) {
textBoxItem.mask();
}
if (attributeDescription.hasDefined(DEFAULT)) {
textBoxItem.assignDefaultValue(attributeDescription.get(DEFAULT).asString());
}
formItem = textBoxItem;
checkCapabilityReference(attributeDescription, formItem);
} else {
SingleSelectBoxItem singleSelectBoxItem = new SingleSelectBoxItem(name, label, allowedValues, !required);
if (attributeDescription.hasDefined(DEFAULT)) {
singleSelectBoxItem.assignDefaultValue(attributeDescription.get(DEFAULT).asString());
}
formItem = singleSelectBoxItem;
}
break;
}
// unsupported types
case BIG_DECIMAL:
case BYTES:
case EXPRESSION:
case PROPERTY:
case TYPE:
case UNDEFINED:
logger.warn("Unsupported model type {} for attribute {} in metadata {}. Unable to create a form item. Attribute will be skipped.", type.name(), property.getName(), metadata.getTemplate());
break;
default:
break;
}
if (formItem != null) {
formItem.setRequired(required);
formItem.setDeprecated(deprecation);
if (formItem.supportsExpressions()) {
formItem.setExpressionAllowed(expressionAllowed);
formItem.addResolveExpressionHandler(event -> {
// resend as application event
Core.INSTANCE.eventBus().fireEvent(event);
});
}
if (readOnly) {
formItem.setEnabled(false);
// if the attribute is read-only and required, the form validation prevents to save the form
// remove the required constraint to allow the save operation.
formItem.setRequired(false);
}
}
}
return formItem;
}
use of org.jboss.hal.dmr.ModelType in project console by hal.
the class ModelNodeMapping method populateFormItems.
@Override
@SuppressWarnings("unchecked")
public void populateFormItems(T model, Form<T> form) {
String id = id(form);
for (FormItem formItem : form.getBoundFormItems()) {
formItem.clearError();
String name = formItem.getName();
if (model.hasDefined(name)) {
ModelNode attributeDescription = findAttribute(name);
if (attributeDescription == null) {
logger.error("{}: Unable to populate form item '{}': No attribute description found in\n{}", id, name, attributeDescriptions);
continue;
}
ModelNode value = model.get(name);
ModelType valueType = value.getType();
if (valueType == EXPRESSION) {
if (formItem.supportsExpressions()) {
formItem.setExpressionValue(value.asString());
formItem.setUndefined(false);
} else {
logger.error("{}: Unable to populate form item '{}': Value is an expression, but form item does not support expressions", id, name);
continue;
}
} else if (formItem instanceof ModelNodeItem) {
formItem.setValue(value);
} else {
populateFormItem(id, name, attributeDescription, value, formItem);
}
formItem.setUndefined(false);
} else {
formItem.clearValue();
formItem.setUndefined(true);
}
}
}
use of org.jboss.hal.dmr.ModelType in project console by hal.
the class ModelNodeMapping method populateFormItem.
@SuppressWarnings("unchecked")
public void populateFormItem(String id, String name, ModelNode attributeDescription, ModelNode value, FormItem formItem) {
ModelType descriptionType = attributeDescription.get(TYPE).asType();
try {
switch(descriptionType) {
case BOOLEAN:
formItem.setValue(value.asBoolean());
break;
case INT:
// NumberItem uses *always* long
try {
formItem.setValue((long) value.asInt());
} catch (IllegalArgumentException e) {
logger.error("{}: Unable to populate form item '{}': Metadata says it's an INT, but value is not '{}'", id, name, value.asString());
}
break;
case DOUBLE:
try {
formItem.setValue(value.asDouble());
} catch (IllegalArgumentException e) {
logger.error("{}: Unable to populate form item '{}': Metadata says it's an DOUBLE, but value is not '{}'", id, name, value.asString());
}
break;
case BIG_INTEGER:
case LONG:
try {
formItem.setValue(value.asLong());
} catch (IllegalArgumentException e) {
logger.error("{}: Unable to populate form item '{}': Metadata says it's a {}, but value is not '{}'", id, name, descriptionType.name(), value.asString());
}
break;
case LIST:
List<String> list = value.asList().stream().map(ModelNode::asString).collect(toList());
formItem.setValue(list);
break;
case OBJECT:
boolean stringValueType = attributeDescription.get(VALUE_TYPE).getType().equals(ModelType.TYPE) && attributeDescription.get(VALUE_TYPE).asType().equals(ModelType.STRING);
if (stringValueType) {
List<Property> properties = value.asPropertyList();
Map<String, String> map = new HashMap<>();
for (Property property : properties) {
map.put(property.getName(), property.getValue().asString());
}
formItem.setValue(map);
} else {
formItem.setValue(value);
}
break;
case STRING:
formItem.setValue(value.asString());
break;
// unsupported types
case BIG_DECIMAL:
case BYTES:
case EXPRESSION:
case PROPERTY:
case TYPE:
case UNDEFINED:
logger.warn("{}: populating form field '{}' of type '{}' not implemented", id, name, descriptionType);
break;
default:
break;
}
} catch (IllegalArgumentException e) {
logger.error("{}: Unable to populate form item '{}'. Declared type in r-r-d does not match type in model node: '{}' != '{}'", id, name, descriptionType.name(), value.getType());
formItem.setEnabled(false);
}
}
Aggregations