/*
* Jopr Management Platform
* Copyright (C) 2005-2009 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation, and/or the GNU Lesser
* General Public License, version 2.1, also as published by the Free
* Software Foundation.
*
* This program 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 General Public License and the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* and the GNU Lesser General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.rhq.plugins.jbossas5.adapter.impl.configuration.custom;
import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedHashMap;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyList;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.plugins.jbossas5.adapter.api.AbstractPropertyListAdapter;
import org.jboss.metatype.api.types.MetaType;
import org.jboss.metatype.api.types.SimpleMetaType;
import org.jboss.metatype.api.values.MapCompositeValueSupport;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.metatype.api.values.SimpleValue;
import org.jboss.metatype.api.values.SimpleValueSupport;
/**
* This class maps between a {@link PropertyList} of a {@link PropertyMap}s of name, type and value {@link
* PropertySimple}s and a {@link MapCompositeValueSupport} where the keys are the config-property names and values are
* config-property values. We need a custom adapter for this because we need to support editing the type of the
* config-property entries.
* <p/>
* JBoss Profile service exposes a type of a config property in a slightly "interesting" manner. A config-property
* defined as
* <p/>
* <code> <config-property name="property" type="java.lang.String">value</config-property> </code>
* <p/>
* is exposed as a pair of entries in the map:
* <p/>
* <code> [key = "property", value = "value"] <br/> [key = "property.type", value = "java.lang.String"] </code>
*
* @author Lukas Krejci
*/
public class ConnectionFactoryConfigPropertyAdapter extends
AbstractPropertyListAdapter
{
public MetaValue convertToMetaValue(PropertyList property,
PropertyDefinitionList propertyDefinition, MetaType metaType)
{
MapCompositeValueSupport valuesMap = new MapCompositeValueSupport(
metaType);
populateMetaValueFromProperty(property, valuesMap, propertyDefinition);
return valuesMap;
}
public void populateMetaValueFromProperty(PropertyList property,
MetaValue metaValue, PropertyDefinitionList propertyDefinition)
{
MapCompositeValueSupport valuesMap = (MapCompositeValueSupport)metaValue;
for (Property p : property.getList())
{
PropertyMap propertyMap = (PropertyMap)p;
PropertySimple nameProperty = (PropertySimple)propertyMap
.get("name");
PropertySimple typeProperty = (PropertySimple)propertyMap
.get("type");
PropertySimple valueProperty = (PropertySimple)propertyMap
.get("value");
String configPropertyName = nameProperty.getStringValue();
String configPropertyType = typeProperty.getStringValue();
String configPropertyValue = valueProperty.getStringValue();
if (!ConfigPropertyType.fromTypeName(configPropertyType)
.isValueValid(configPropertyValue))
{
String message = "The value of Config Property '"
+ configPropertyName
+ "' has an invalid value for its type.";
property.setErrorMessage(message);
throw new IllegalArgumentException(message);
}
valuesMap.put(configPropertyName, new SimpleValueSupport(
SimpleMetaType.STRING, valueProperty.getStringValue()));
valuesMap.put(configPropertyName + ".type", new SimpleValueSupport(
SimpleMetaType.STRING, typeProperty.getStringValue()));
}
}
public void populatePropertyFromMetaValue(PropertyList property,
MetaValue metaValue, PropertyDefinitionList propertyDefinition)
{
MapCompositeValueSupport valuesMap = (MapCompositeValueSupport)metaValue;
for (ConfigProperty configProperty : getConfigProperties(valuesMap))
{
PropertySimple name = new PropertySimple("name", configProperty
.getName());
PropertySimple type = new PropertySimple("type", configProperty
.getType().getTypeName());
PropertySimple value = new PropertySimple("value", configProperty
.getValue());
property.add(new PropertyMap("config-property", name, type, value));
}
}
private Collection<ConfigProperty> getConfigProperties(
MapCompositeValueSupport valuesMap)
{
LinkedHashMap<String, ConfigProperty> results = new LinkedHashMap<String, ConfigProperty>();
for (String key : valuesMap.getMetaType().keySet())
{
String propertyName;
ConfigPropertyType propertyType = null;
Serializable propertyValue = null;
if (key.endsWith(".type"))
{
propertyName = key.substring(0, key.length() - 5);
SimpleValue typeName = (SimpleValue)valuesMap.get(key);
propertyType = ConfigPropertyType.fromTypeName(typeName
.getValue().toString());
}
else
{
propertyName = key;
SimpleValue value = (SimpleValue)valuesMap.get(key);
if (value != null)
{
propertyValue = value.getValue();
}
}
ConfigProperty property = results.get(propertyName);
if (property == null)
{
property = new ConfigProperty();
property.setName(propertyName);
results.put(propertyName, property);
}
if (propertyType != null)
{
property.setType(propertyType);
}
if (propertyValue != null)
{
property.setValue(propertyValue);
}
}
return results.values();
}
private enum ConfigPropertyType
{
STRING(SimpleMetaType.STRING)
{
public boolean isValueValid(String value)
{
return true;
}
},
CHARACTER(SimpleMetaType.CHARACTER)
{
public boolean isValueValid(String value)
{
return value == null || value.length() == 1;
}
},
BOOLEAN(SimpleMetaType.BOOLEAN)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
return value.equalsIgnoreCase("true")
|| value.equalsIgnoreCase("false");
}
},
BYTE(SimpleMetaType.BYTE)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
try
{
Byte.parseByte(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
},
SHORT(SimpleMetaType.SHORT)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
try
{
Short.parseShort(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
},
INTEGER(SimpleMetaType.INTEGER)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
try
{
Integer.parseInt(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
},
LONG(SimpleMetaType.LONG)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
try
{
Long.parseLong(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
},
FLOAT(SimpleMetaType.FLOAT)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
try
{
Float.parseFloat(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
},
DOUBLE(SimpleMetaType.DOUBLE)
{
public boolean isValueValid(String value)
{
if (value == null)
return false;
try
{
Double.parseDouble(value);
return true;
}
catch (NumberFormatException e)
{
return false;
}
}
},
INVALID(SimpleMetaType.VOID)
{
public boolean isValueValid(String value)
{
return false;
}
};
private SimpleMetaType metaType;
private ConfigPropertyType(SimpleMetaType metaType)
{
this.metaType = metaType;
}
public static ConfigPropertyType fromTypeName(String typeName)
{
for (ConfigPropertyType type : values())
{
if (type.getTypeName().equals(typeName))
{
return type;
}
}
return INVALID;
}
public String getTypeName()
{
return metaType.getClassName();
}
public SimpleMetaType getMetaType()
{
return metaType;
}
public abstract boolean isValueValid(String value);
public String toString()
{
return name().toLowerCase();
}
}
private static class ConfigProperty
{
private String name;
private ConfigPropertyType type;
private Serializable value;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public ConfigPropertyType getType()
{
return type;
}
public void setType(ConfigPropertyType type)
{
this.type = type;
}
public Serializable getValue()
{
return value;
}
public void setValue(Serializable value)
{
this.value = value;
}
public String toString()
{
return "ConfigProperty[" + name + "(" + type + ") : " + value + "]";
}
public SimpleValue getTypeDefinitionValue()
{
return new SimpleValueSupport(SimpleMetaType.STRING, type
.getTypeName());
}
public SimpleValue getValueDefinitionValue()
{
return new SimpleValueSupport(type.getMetaType(), value);
}
}
}