/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.jmx.model;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE_TYPE;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import org.jboss.as.jmx.logging.JmxLogger;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.jboss.dmr.Property;
import org.jboss.dmr.ValueExpression;
/**
* Converts between Open MBean types/data and ModelController types/data
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
*/
class TypeConverters {
static final Pattern VAULT_PATTERN = Pattern.compile("\\$\\{VAULT::.*::.*::.*\\}");
private static final SimpleTypeConverter BIG_DECIMAL_NO_EXPR = new SimpleTypeConverter(BigDecimalValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter BIG_DECIMAL_EXPR = new SimpleTypeConverter(BigDecimalValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter BIG_INTEGER_NO_EXPR = new SimpleTypeConverter(BigIntegerValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter BIG_INTEGER_EXPR = new SimpleTypeConverter(BigIntegerValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter BOOLEAN_NO_EXPR = new SimpleTypeConverter(BooleanValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter BOOLEAN_EXPR = new SimpleTypeConverter(BooleanValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter BYTES_NO_EXPR = new SimpleTypeConverter(BytesValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter DOUBLE_NO_EXPR = new SimpleTypeConverter(DoubleValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter DOUBLE_EXPR = new SimpleTypeConverter(DoubleValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter STRING_NO_EXPR = new SimpleTypeConverter(StringValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter STRING_EXPR = new SimpleTypeConverter(StringValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter PROPERTY_NO_EXPR = new SimpleTypeConverter(StringValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter INT_NO_EXPR = new SimpleTypeConverter(IntegerValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter INT_EXPR = new SimpleTypeConverter(IntegerValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter LONG_NO_EXPR = new SimpleTypeConverter(LongValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter LONG_EXPR = new SimpleTypeConverter(LongValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter TYPE_NO_EXPR = new SimpleTypeConverter(ModelTypeValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter TYPE_EXPR = new SimpleTypeConverter(ModelTypeValueAccessor.INSTANCE, true);
private static final SimpleTypeConverter UNDEFINED_NO_EXPR = new SimpleTypeConverter(UndefinedValueAccessor.INSTANCE, false);
private static final SimpleTypeConverter UNDEFINED_EXPR = new SimpleTypeConverter(UndefinedValueAccessor.INSTANCE, true);
private final boolean expressions;
//Older versions simply used a DMR string for PROPERTY types
private final boolean legacyWithProperPropertyFormat;
private TypeConverters(boolean expressions, boolean legacyWithProperPropertyFormat) {
this.expressions = expressions;
this.legacyWithProperPropertyFormat = legacyWithProperPropertyFormat;
}
public static TypeConverters createLegacyTypeConverters(boolean properPropertyFormat) {
return new TypeConverters(false, properPropertyFormat);
}
public static TypeConverters createExpressionTypeConverters() {
return new TypeConverters(true, true);
}
OpenType<?> convertToMBeanType(final ModelNode description) {
return getConverter(description).getOpenType();
}
ModelNode toModelNode(final ModelNode description, final Object value) {
ModelNode node = new ModelNode();
if (value == null) {
return node;
}
return getConverter(description).toModelNode(value);
}
Object fromModelNode(final ModelNode description, final ModelNode value) {
if (value == null || !value.isDefined()) {
return null;
}
return getConverter(description).fromModelNode(value);
}
public ModelType getType(ModelNode typeNode) {
if (typeNode == null) {
return ModelType.UNDEFINED;
}
try {
return ModelType.valueOf(typeNode.toString());
} catch (RuntimeException e) {
return null;
}
}
public TypeConverter getConverter(ModelNode description) {
return getConverter(description.hasDefined(TYPE) ? description.get(TYPE) : null,
description.hasDefined(VALUE_TYPE) ? description.get(VALUE_TYPE) : null);
}
TypeConverter getConverter(ModelType modelType, ModelNode valueTypeNode) {
switch (modelType) {
case BIG_DECIMAL:
return expressions ? BIG_DECIMAL_EXPR : BIG_DECIMAL_NO_EXPR;
case BIG_INTEGER:
return expressions ? BIG_INTEGER_EXPR : BIG_INTEGER_NO_EXPR;
case BOOLEAN:
return expressions ? BOOLEAN_EXPR : BOOLEAN_NO_EXPR;
case BYTES:
//Allowing expressions for byte[] seems pointless
return BYTES_NO_EXPR;
case DOUBLE:
return expressions ? DOUBLE_EXPR : DOUBLE_NO_EXPR;
case STRING:
return expressions ? STRING_EXPR : STRING_NO_EXPR;
case PROPERTY:
//For the legacy setup properties are converted to a dmr string
//For the expr setup or legacy with legacyWithProperPropertyFormat=true we use a composite type
return expressions || legacyWithProperPropertyFormat ? new PropertyTypeConverter(valueTypeNode) : PROPERTY_NO_EXPR;
case INT:
return expressions ? INT_EXPR : INT_NO_EXPR;
case LONG:
return expressions ? LONG_EXPR : LONG_NO_EXPR;
case TYPE:
return expressions ? TYPE_EXPR : TYPE_NO_EXPR;
case UNDEFINED:
return expressions ? UNDEFINED_EXPR : UNDEFINED_NO_EXPR;
case OBJECT:
return new ObjectTypeConverter(valueTypeNode);
case LIST:
return new ListTypeConverter(valueTypeNode);
default:
throw JmxLogger.ROOT_LOGGER.unknownType(modelType);
}
}
TypeConverter getConverter(ModelNode typeNode, ModelNode valueTypeNode) {
ModelType modelType = getType(typeNode);
if (modelType == null) {
return new ComplexTypeConverter(typeNode);
}
return getConverter(modelType, valueTypeNode);
}
private static ModelNode nullNodeAsUndefined(ModelNode node) {
if (node == null) {
return new ModelNode();
}
return node;
}
interface TypeConverter {
OpenType<?> getOpenType();
Object fromModelNode(final ModelNode node);
ModelNode toModelNode(final Object o);
Object[] toArray(final List<Object> list);
}
private static class SimpleTypeConverter implements TypeConverter {
private final SimpleValueAccessor valueAccessor;
private final boolean expressions;
public SimpleTypeConverter(SimpleValueAccessor valueAccessor, boolean expressions) {
this.valueAccessor = valueAccessor;
this.expressions = expressions;
}
@Override
public OpenType<?> getOpenType() {
if (!expressions) {
return valueAccessor.getOpenType();
} else {
return SimpleType.STRING;
}
}
@Override
public Object fromModelNode(final ModelNode node) {
if (node == null || !node.isDefined() || node.asString().isEmpty()) {
return null;
}
if (!expressions || valueAccessor == UndefinedValueAccessor.INSTANCE) {
if (!expressions && node.getType() == ModelType.EXPRESSION) {
if (!VAULT_PATTERN.matcher(node.asString()).matches()) {
return valueAccessor.fromModelNode(node.resolve());
}
}
return valueAccessor.fromModelNode(node);
} else {
return node.asString();
}
}
@Override
public ModelNode toModelNode(final Object o) {
if (o == null) {
return new ModelNode();
}
boolean possibleExpression = false;
if (o instanceof String) {
possibleExpression = isPossibleExpression((String)o);
}
if (expressions) {
if (possibleExpression) {
return new ModelNode().set(new ValueExpression((String)o));
}
return valueAccessor.toModelNodeFromString((String)o);
} else {
if (possibleExpression) {
if (valueAccessor != StringValueAccessor.INSTANCE) {
throw JmxLogger.ROOT_LOGGER.expressionCannotBeConvertedIntoTargeteType(valueAccessor.getOpenType());
}
return new ModelNode().set(new ValueExpression((String)o));
}
return valueAccessor.toModelNode(o);
}
}
private boolean isPossibleExpression(String s) {
int start = s.indexOf("${");
return start != -1 && s.indexOf('}', start) != -1;
}
public Object[] toArray(final List<Object> list) {
if (expressions) {
return list.toArray(new String[list.size()]);
} else {
return valueAccessor.toArray(list);
}
}
}
private class ObjectTypeConverter implements TypeConverter {
final ModelNode valueTypeNode;
final ModelType valueType;
OpenType<?> openType;
ObjectTypeConverter(ModelNode valueTypeNode) {
this.valueTypeNode = nullNodeAsUndefined(valueTypeNode);
ModelType valueType = getType(valueTypeNode);
this.valueType = valueType == ModelType.UNDEFINED ? null : valueType;
}
@Override
public OpenType<?> getOpenType() {
if (openType != null) {
return openType;
}
openType = getConverter(valueTypeNode, null).getOpenType();
if (valueType == null && (openType instanceof CompositeType || !valueTypeNode.isDefined())) {
//For complex value types just return the composite type
return openType;
}
try {
CompositeType rowType = new CompositeType(
JmxLogger.ROOT_LOGGER.compositeEntryTypeName(),
JmxLogger.ROOT_LOGGER.compositeEntryTypeDescription(),
new String[] {"key", "value"},
new String[] { JmxLogger.ROOT_LOGGER.compositeEntryKeyDescription(), JmxLogger.ROOT_LOGGER.compositeEntryValueDescription()},
new OpenType[] {SimpleType.STRING, openType});
openType = new TabularType(JmxLogger.ROOT_LOGGER.compositeMapName(), JmxLogger.ROOT_LOGGER.compositeMapDescription(), rowType, new String[] {"key"});
return openType;
} catch (OpenDataException e1) {
throw new RuntimeException(e1);
}
}
@Override
public Object fromModelNode(final ModelNode node) {
if (node == null || !node.isDefined()) {
return null;
}
if (valueType != null) {
return fromSimpleModelNode(node);
} else {
TypeConverter converter = getConverter(valueTypeNode, null);
return converter.fromModelNode(node);
}
}
Object fromSimpleModelNode(final ModelNode node) {
final TabularType tabularType = (TabularType)getOpenType();
final TabularDataSupport tabularData = new TabularDataSupport(tabularType);
final Map<String, ModelNode> values = new HashMap<String, ModelNode>();
final List<Property> properties = node.isDefined() ? node.asPropertyList() : null;
if (properties != null) {
for (Property prop : properties) {
values.put(prop.getName(), prop.getValue());
}
}
final TypeConverter converter = getConverter(valueTypeNode, null);
for (Map.Entry<String, ModelNode> prop : values.entrySet()) {
Map<String, Object> rowData = new HashMap<String, Object>();
rowData.put("key", prop.getKey());
rowData.put("value", converter.fromModelNode(prop.getValue()));
try {
tabularData.put(new CompositeDataSupport(tabularType.getRowType(), rowData));
} catch (OpenDataException e) {
throw new RuntimeException(e);
}
}
return tabularData;
}
@Override
public ModelNode toModelNode(Object o) {
if (o == null) {
return new ModelNode();
}
if (valueType == null) {
//complex
return getConverter(valueTypeNode, null).toModelNode(o);
} else {
//map
final ModelNode node = new ModelNode();
final TypeConverter converter = getConverter(valueTypeNode, null);
for (Map.Entry<String, Object> entry : ((Map<String, Object>)o).entrySet()) {
entry = convertTabularTypeEntryToMapEntry(entry);
node.get(entry.getKey()).set(converter.toModelNode(entry.getValue()));
}
return node;
}
}
@Override
public Object[] toArray(List<Object> list) {
if (getOpenType() == SimpleType.STRING) {
return list.toArray(new String[list.size()]);
}
return list.toArray(new Object[list.size()]);
}
//TODO this may go depending on if we want to force tabular types only
private Map.Entry<String, Object> convertTabularTypeEntryToMapEntry(final Map.Entry<?, Object> entry) {
if (entry.getKey() instanceof List) {
//It comes from a TabularType
return new Map.Entry<String, Object>() {
@Override
public String getKey() {
List<?> keyList = (List<?>)entry.getKey();
if (keyList.size() != 1) {
throw JmxLogger.ROOT_LOGGER.invalidKey(keyList, entry);
}
return (String)keyList.get(0);
}
@Override
public Object getValue() {
return ((CompositeDataSupport)entry.getValue()).get("value");
}
@Override
public Object setValue(Object value) {
throw new UnsupportedOperationException();
}
};
} else {
return new Map.Entry<String, Object>() {
@Override
public String getKey() {
return (String)entry.getKey();
}
@Override
public Object getValue() {
return entry.getValue();
}
@Override
public Object setValue(Object value) {
throw new UnsupportedOperationException();
}
};
}
}
}
private class ListTypeConverter implements TypeConverter {
final ModelNode valueTypeNode;
ListTypeConverter(ModelNode valueTypeNode) {
this.valueTypeNode = nullNodeAsUndefined(valueTypeNode);
}
@Override
public OpenType<?> getOpenType() {
try {
return ArrayType.getArrayType(getConverter(valueTypeNode, null).getOpenType());
} catch (OpenDataException e) {
throw new RuntimeException(e);
}
}
@Override
public Object fromModelNode(final ModelNode node) {
if (node == null || !node.isDefined()) {
return null;
}
final List<Object> list = new ArrayList<Object>();
final TypeConverter converter = getConverter(valueTypeNode, null);
for (ModelNode element : node.asList()) {
list.add(converter.fromModelNode(element));
}
return converter.toArray(list);
}
@Override
public ModelNode toModelNode(Object o) {
if (o == null) {
return new ModelNode();
}
ModelNode node = new ModelNode();
final TypeConverter converter = getConverter(valueTypeNode, null);
for (Object value : (Object[])o) {
node.add(converter.toModelNode(value));
}
return node;
}
@Override
public Object[] toArray(List<Object> list) {
return null;
}
}
private class ComplexTypeConverter implements TypeConverter {
final ModelNode typeNode;
ComplexTypeConverter(final ModelNode typeNode) {
this.typeNode = nullNodeAsUndefined(typeNode);
}
@Override
public OpenType<?> getOpenType() {
List<String> itemNames = new ArrayList<String>();
List<String> itemDescriptions = new ArrayList<String>();
List<OpenType<?>> itemTypes = new ArrayList<OpenType<?>>();
//Some of the common operation descriptions use value-types like "The type will be that of the attribute found".
if (!typeNode.isDefined() || typeNode.getType() == ModelType.STRING) {
return SimpleType.STRING;
}
for (String name : typeNode.keys()) {
ModelNode current = typeNode.get(name);
itemNames.add(name);
String description = null;
if (!current.hasDefined(DESCRIPTION)) {
description = "-";
}
else {
description = current.get(DESCRIPTION).asString().trim();
if (description.length() == 0) {
description = "-";
}
}
itemDescriptions.add(getDescription(current));
itemTypes.add(getConverter(current).getOpenType());
}
try {
return new CompositeType(JmxLogger.ROOT_LOGGER.complexCompositeEntryTypeName(),
JmxLogger.ROOT_LOGGER.complexCompositeEntryTypeDescription(),
itemNames.toArray(new String[itemNames.size()]),
itemDescriptions.toArray(new String[itemDescriptions.size()]),
itemTypes.toArray(new OpenType[itemTypes.size()]));
} catch (OpenDataException e) {
throw new RuntimeException(e);
}
}
String getDescription(ModelNode node) {
if (!node.hasDefined(DESCRIPTION)) {
return "-";
}
String description = node.get(DESCRIPTION).asString();
if (description.trim().length() == 0) {
return "-";
}
return description;
}
@Override
public Object fromModelNode(ModelNode node) {
if (node == null || !node.isDefined()) {
return null;
}
final OpenType<?> openType = getOpenType();
if (openType instanceof CompositeType) {
final CompositeType compositeType = (CompositeType)openType;
//Create a composite
final Map<String, Object> items = new HashMap<String, Object>();
for (String attrName : compositeType.keySet()) {
TypeConverter converter = getConverter(typeNode.get(attrName, TYPE), typeNode.get(attrName, VALUE_TYPE));
items.put(attrName, converter.fromModelNode(node.get(attrName)));
}
try {
return new CompositeDataSupport(compositeType, items);
} catch (OpenDataException e) {
throw new RuntimeException(e);
}
} else {
return node.toJSONString(false);
}
}
@Override
public ModelNode toModelNode(Object o) {
if (o == null) {
return new ModelNode();
}
if (o instanceof CompositeData) {
final ModelNode node = new ModelNode();
final CompositeData composite = (CompositeData)o;
for (String key : composite.getCompositeType().keySet()) {
if (!typeNode.hasDefined(key)){
throw JmxLogger.ROOT_LOGGER.unknownValue(key);
}
TypeConverter converter = getConverter(typeNode.get(key, TYPE), typeNode.get(key, VALUE_TYPE));
node.get(key).set(converter.toModelNode(composite.get(key)));
}
return node;
} else {
return ModelNode.fromJSONString((String)o);
}
}
@Override
public Object[] toArray(List<Object> list) {
return list.toArray(new CompositeData[list.size()]);
}
}
private class PropertyTypeConverter implements TypeConverter {
final ModelNode typeNode;
public PropertyTypeConverter(ModelNode typeNode) {
this.typeNode = typeNode;
}
@Override
public CompositeType getOpenType() {
try {
return new CompositeType(
"property",
JmxLogger.ROOT_LOGGER.propertyCompositeType(),
new String[] {"name", "value"},
new String[] { JmxLogger.ROOT_LOGGER.propertyName(), JmxLogger.ROOT_LOGGER.propertyValue()},
new OpenType[] {SimpleType.STRING, getConverter().getOpenType()});
} catch (OpenDataException e) {
throw new RuntimeException(e);
}
}
@Override
public Object fromModelNode(ModelNode node) {
Property prop = node.asProperty();
Map<String, Object> items = new HashMap<String, Object>();
items.put("name", prop.getName());
items.put("value", getConverter().fromModelNode(prop.getValue()));
try {
return new CompositeDataSupport(getOpenType(), items);
} catch (OpenDataException e) {
throw new IllegalStateException(e);
}
}
@Override
public ModelNode toModelNode(Object o) {
CompositeData data = (CompositeData)o;
String name = (String)data.get("name");
ModelNode value = getConverter().toModelNode(data.get("value"));
ModelNode node = new ModelNode();
node.set(name, value);
return node;
}
@Override
public Object[] toArray(List<Object> list) {
return list.toArray(new Object[list.size()]);
}
private TypeConverter getConverter() {
if (typeNode == null) {
return expressions ? STRING_EXPR : STRING_NO_EXPR;
}
return TypeConverters.this.getConverter(typeNode, null);
}
}
private abstract static class SimpleValueAccessor {
abstract OpenType<?> getOpenType();
abstract Object fromModelNode(ModelNode node);
abstract ModelNode toModelNode(Object o);
abstract ModelNode toModelNodeFromString(String s);
abstract Object[] toArray(final List<Object> list);
}
private static class BigDecimalValueAccessor extends SimpleValueAccessor {
static final BigDecimalValueAccessor INSTANCE = new BigDecimalValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.BIGDECIMAL;
}
Object fromModelNode(final ModelNode node) {
return node.asBigDecimal();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((BigDecimal)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new BigDecimal[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(new BigDecimal(s));
}
}
private static class BigIntegerValueAccessor extends SimpleValueAccessor {
static final BigIntegerValueAccessor INSTANCE = new BigIntegerValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.BIGINTEGER;
}
Object fromModelNode(final ModelNode node) {
return node.asBigInteger();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((BigInteger)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new BigInteger[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(new BigInteger(s));
}
}
private static class BooleanValueAccessor extends SimpleValueAccessor {
static final BooleanValueAccessor INSTANCE = new BooleanValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.BOOLEAN;
}
Object fromModelNode(final ModelNode node) {
return node.asBoolean();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((Boolean)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new Boolean[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(Boolean.valueOf(s));
}
}
private static class BytesValueAccessor extends SimpleValueAccessor {
static final BytesValueAccessor INSTANCE = new BytesValueAccessor();
static final ArrayType<byte[]> ARRAY_TYPE = ArrayType.getPrimitiveArrayType(byte[].class);
OpenType<?> getOpenType() {
return ARRAY_TYPE;
}
Object fromModelNode(final ModelNode node) {
return node.resolve().asBytes();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((byte[])o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new byte[list.size()][]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(s);
}
}
private static class DoubleValueAccessor extends SimpleValueAccessor {
static final DoubleValueAccessor INSTANCE = new DoubleValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.DOUBLE;
}
Object fromModelNode(final ModelNode node) {
return node.asDouble();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((Double)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new Double[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(Double.valueOf(s));
}
}
private static class IntegerValueAccessor extends SimpleValueAccessor {
static final IntegerValueAccessor INSTANCE = new IntegerValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.INTEGER;
}
Object fromModelNode(final ModelNode node) {
return node.asInt();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((Integer)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new Integer[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(Integer.valueOf(s));
}
}
private static class StringValueAccessor extends SimpleValueAccessor {
static final StringValueAccessor INSTANCE = new StringValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.STRING;
}
Object fromModelNode(final ModelNode node) {
return node.asString();
}
ModelNode toModelNode(final Object o) {
if (o == null) {
return new ModelNode();
}
return new ModelNode().set((String)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new String[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(s);
}
}
private static class UndefinedValueAccessor extends SimpleValueAccessor {
static final UndefinedValueAccessor INSTANCE = new UndefinedValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.STRING;
}
Object fromModelNode(final ModelNode node) {
return node.toJSONString(false);
}
ModelNode toModelNode(final Object o) {
return toModelNodeFromString((String)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new String[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return ModelNode.fromJSONString(s);
}
}
private static class LongValueAccessor extends SimpleValueAccessor {
static final LongValueAccessor INSTANCE = new LongValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.LONG;
}
Object fromModelNode(final ModelNode node) {
return node.asLong();
}
ModelNode toModelNode(final Object o) {
return new ModelNode().set((Long)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new Long[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode(Long.valueOf(s));
}
}
private static class ModelTypeValueAccessor extends SimpleValueAccessor {
static final ModelTypeValueAccessor INSTANCE = new ModelTypeValueAccessor();
OpenType<?> getOpenType() {
return SimpleType.STRING;
}
Object fromModelNode(final ModelNode node) {
return node.asString();
}
ModelNode toModelNode(final Object o) {
return toModelNodeFromString((String)o);
}
Object[] toArray(final List<Object> list) {
return list.toArray(new String[list.size()]);
}
@Override
ModelNode toModelNodeFromString(String s) {
return new ModelNode().set(ModelType.valueOf(s));
}
}
}