/*
 * JBoss, Home of Professional Open Source.
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * 
 * This library 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 library 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

package org.teiid.rhq.plugin.util;

import java.io.File;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.naming.NamingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.deployers.spi.management.KnownDeploymentTypes;
import org.jboss.deployers.spi.management.ManagementView;
import org.jboss.deployers.spi.management.deploy.DeploymentManager;
import org.jboss.managed.api.ComponentType;
import org.jboss.managed.api.ManagedCommon;
import org.jboss.managed.api.ManagedComponent;
import org.jboss.managed.api.ManagedDeployment;
import org.jboss.managed.api.ManagedProperty;
import org.jboss.managed.api.annotation.ViewUse;
import org.jboss.metatype.api.types.MapCompositeMetaType;
import org.jboss.metatype.api.types.MetaType;
import org.jboss.metatype.api.types.SimpleMetaType;
import org.jboss.metatype.api.values.EnumValue;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.metatype.api.values.SimpleValue;
import org.jboss.metatype.api.values.SimpleValueSupport;
import org.jboss.profileservice.spi.ProfileService;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.ConfigurationTemplate;
import org.rhq.core.domain.configuration.definition.PropertyDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionList;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.plugins.jbossas5.connection.ProfileServiceConnection;
import org.teiid.rhq.plugin.TranslatorComponent;
import org.teiid.rhq.plugin.adapter.api.PropertyAdapter;
import org.teiid.rhq.plugin.adapter.api.PropertyAdapterFactory;

import com.sun.istack.NotNull;

public class ProfileServiceUtil {

	protected final static Log LOG = LogFactory
			.getLog(PluginConstants.DEFAULT_LOGGER_CATEGORY); 
	private static ComponentType DQPTYPE = new ComponentType("teiid", "dqp"); //$NON-NLS-1$ //$NON-NLS-2$
	private static String DQPNAME = "RuntimeEngineDeployer"; //$NON-NLS-1$
	private static String BUFFERSERVICE = "BufferService"; //$NON-NLS-1$
	private static final Map<String, ComponentType> COMPONENT_TYPE_CACHE = new HashMap<String, ComponentType>();
	
	protected static final String PLUGIN = "ProfileService"; //$NON-NLS-1$

	public static ComponentType getComponentType(
			@NotNull ResourceType resourceType) {
		String resourceTypeName = resourceType.getName();
		if (COMPONENT_TYPE_CACHE.containsKey(resourceTypeName))
			return COMPONENT_TYPE_CACHE.get(resourceTypeName);
		Configuration defaultPluginConfig = getDefaultPluginConfiguration(resourceType);
		String type = defaultPluginConfig.getSimpleValue(
				TranslatorComponent.Config.COMPONENT_TYPE, null);
		if (type == null || type.equals("")) //$NON-NLS-1$
			throw new IllegalStateException(
					"Required plugin configuration property '" //$NON-NLS-1$
							+ TranslatorComponent.Config.COMPONENT_TYPE
							+ "' is not defined in default template."); //$NON-NLS-1$
		String subtype = defaultPluginConfig.getSimpleValue(
				TranslatorComponent.Config.COMPONENT_SUBTYPE, null);
		if (subtype == null || subtype.equals("")) //$NON-NLS-1$
			throw new IllegalStateException(
					"Required plugin configuration property '" //$NON-NLS-1$
							+ TranslatorComponent.Config.COMPONENT_SUBTYPE 
							+ "' is not defined in default template."); //$NON-NLS-1$
		ComponentType componentType = new ComponentType(type, subtype);
		COMPONENT_TYPE_CACHE.put(resourceTypeName, componentType);
		return componentType;
	}

	private static Configuration getDefaultPluginConfiguration(
			ResourceType resourceType) {
		ConfigurationTemplate pluginConfigDefaultTemplate = resourceType
				.getPluginConfigurationDefinition().getDefaultTemplate();
		return (pluginConfigDefaultTemplate != null) ? pluginConfigDefaultTemplate
				.createConfiguration()
				: new Configuration();
	}

	/**
	 * @param name
	 * @param componentType
	 * @return
	 */
	public static boolean isManagedComponent(
			ProfileServiceConnection connection, String name,
			ComponentType componentType) {
		boolean isDeployed = false;
		if (name != null) {
			try {
				ManagedComponent component = getManagedComponent(connection,
						componentType, name);
				if (component != null)
					isDeployed = true;
			} catch (Exception e) {
				// Setting it to true to be safe than sorry, since there might
				// be a component
				// already deployed in the AS.
				isDeployed = true;
			}
		}
		return isDeployed;
	}

	/**
	 * Get the passed in {@link ManagedComponent}
	 * 
	 * @return {@link ManagedComponent}
	 * @throws NamingException
	 * @throws Exception
	 */
	public static ManagedComponent getManagedComponent(
			ProfileServiceConnection connection, ComponentType componentType,
			String componentName) throws NamingException, Exception {
		ManagedComponent mc = connection.getManagementView().getComponent(
				componentName, componentType);

		return mc;
	}

	/**
	 * Get the {@link ManagedComponent} for the {@link ComponentType} and sub
	 * type.
	 * 
	 * @return Set of {@link ManagedComponent}s
	 * @throws NamingException
	 *             , Exception
	 * @throws Exception
	 */
	public static Set<ManagedComponent> getManagedComponents(ProfileServiceConnection connection,
			ComponentType componentType) throws NamingException, Exception {
		
		Set<ManagedComponent> mcSet = connection.getManagementView().getComponentsForType(componentType);

		return mcSet;
	}

	/**
	 * @param {@link ManagementView}
	 * @return
	 */
	public static ManagementView getManagementView(ProfileService ps,
			boolean load) {
		ManagementView mv = ps.getViewManager();
		if (load) {
			mv.load();
		}
		return mv;
	}

	/**
	 * Get the {@link DeploymentManager} from the ProfileService
	 * 
	 * @return DeploymentManager
	 * @throws NamingException
	 * @throws Exception
	 */
	public static DeploymentManager getDeploymentManager(ProfileServiceConnection connection)
			throws NamingException, Exception {

		return connection.getDeploymentManager();
	}

	/**
	 * @return {@link File}
	 * @throws NamingException
	 *             , Exception
	 */
	public static File getDeployDirectory(ProfileServiceConnection connection) throws NamingException, Exception {
		Set<ManagedDeployment> warDeployments;
		try {
			warDeployments = connection.getManagementView()
					.getDeploymentsForType(KnownDeploymentTypes.JavaEEWebApplication
							.getType());
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
		ManagedDeployment standaloneWarDeployment = null;
		for (ManagedDeployment warDeployment : warDeployments) {
			if (warDeployment.getParent() == null) {
				standaloneWarDeployment = warDeployment;
				break;
			}
		}
		if (standaloneWarDeployment == null)
			// This could happen if no standalone WARs, including the admin
			// console WAR, have been fully deployed yet.
			return null;
		URL warUrl;
		try {
			warUrl = new URL(standaloneWarDeployment.getName());
		} catch (MalformedURLException e) {
			throw new IllegalStateException(e);
		}
		File warFile = new File(warUrl.getPath());
		File deployDir = warFile.getParentFile();
		return deployDir;
	}

	public static ManagedComponent getRuntimeEngineDeployer(
			ProfileServiceConnection connection) throws NamingException,
			Exception {

		return getManagedComponent(connection, DQPTYPE, DQPNAME);
	}
	
	public static ManagedComponent getBufferService(
			ProfileServiceConnection connection) throws NamingException,
			Exception {

		return getManagedComponent(connection, DQPTYPE, BUFFERSERVICE);
	}

	public static String stringValue(MetaValue v1) throws Exception {
		if (v1 != null) {
			MetaType type = v1.getMetaType();
			if (type instanceof SimpleMetaType) {
				SimpleValue simple = (SimpleValue) v1;
				return simple.getValue().toString();
			}
			throw new Exception("Failed to convert value to string value"); //$NON-NLS-1$
		}
		return null;
	}

	public static Boolean booleanValue(MetaValue v1) throws Exception {
		if (v1 != null) {
			MetaType type = v1.getMetaType();
			if (type instanceof SimpleMetaType) {
				SimpleValue simple = (SimpleValue) v1;
				return Boolean.valueOf(simple.getValue().toString());
			}
			throw new Exception("Failed to convert value to boolean value"); //$NON-NLS-1$
		}
		return null;
	}

	public static Double doubleValue(MetaValue v1) throws Exception {
		if (v1 != null) {
			MetaType type = v1.getMetaType();
			if (type instanceof SimpleMetaType) {
				SimpleValue simple = (SimpleValue) v1;
				return Double.valueOf(simple.getValue().toString());
			}
			throw new Exception("Failed to convert value to double value"); //$NON-NLS-1$
		}
		return null;
	}
	
	public static Long longValue(MetaValue v1) throws Exception {
		if (v1 != null) {
			MetaType type = v1.getMetaType();
			if (type instanceof SimpleMetaType) {
				SimpleValue simple = (SimpleValue) v1;
				return Long.valueOf(simple.getValue().toString());
			}
			throw new Exception("Failed to convert value to long value"); //$NON-NLS-1$
		}
		return null;
	}
	
	public static Integer integerValue(MetaValue v1) throws Exception {
		if (v1 != null) {
			MetaType type = v1.getMetaType();
			if (type instanceof SimpleMetaType) {
				SimpleValue simple = (SimpleValue) v1;
				return Integer.valueOf(simple.getValue().toString());
			}
			throw new Exception("Failed to convert value to integer value"); //$NON-NLS-1$
		}
		return null;
	}
	
	public static <T> T getSimpleValue(ManagedComponent mc, String prop,
			Class<T> expectedType) {
		ManagedProperty mp = mc.getProperty(prop);
		if (mp != null) {
			MetaType metaType = mp.getMetaType();
			if (metaType.isSimple()) {
				SimpleValue simpleValue = (SimpleValue) mp.getValue();
				return expectedType.cast((simpleValue != null) ? simpleValue
						.getValue() : null);
			} else if (metaType.isEnum()) {
				EnumValue enumValue = (EnumValue) mp.getValue();
				return expectedType.cast((enumValue != null) ? enumValue
						.getValue() : null);
			}
			throw new IllegalStateException(prop + " is not a simple type"); //$NON-NLS-1$
		}
		return null;
	}

	public static <T> T getSimpleValue(MetaValue prop,
			Class<T> expectedType) {
		if (prop != null) {
			MetaType metaType = prop.getMetaType();
			if (metaType.isSimple()) {
				SimpleValue simpleValue = (SimpleValue) prop;
				return expectedType.cast((simpleValue != null) ? simpleValue
						.getValue() : null);
			} else if (metaType.isEnum()) {
				EnumValue enumValue = (EnumValue) prop;
				return expectedType.cast((enumValue != null) ? enumValue
						.getValue() : null);
			}
			throw new IllegalStateException(prop + " is not a simple type"); //$NON-NLS-1$
		}
		return null;
	}
	
	public static <T> T getSimpleValue(ManagedCommon mc, String prop,
			Class<T> expectedType) {
		ManagedProperty mp = mc.getProperty(prop);
		if (mp != null) {
			MetaType metaType = mp.getMetaType();
			if (metaType.isSimple()) {
				SimpleValue simpleValue = (SimpleValue) mp.getValue();
				return expectedType.cast((simpleValue != null) ? simpleValue
						.getValue() : null);
			} else if (metaType.isEnum()) {
				EnumValue enumValue = (EnumValue) mp.getValue();
				return expectedType.cast((enumValue != null) ? enumValue
						.getValue() : null);
			}
			throw new IllegalArgumentException(prop + " is not a simple type"); //$NON-NLS-1$
		}
		return null;
	}

	public static Map<String, PropertySimple> getCustomProperties(
			Configuration pluginConfig) {
		Map<String, PropertySimple> customProperties = new LinkedHashMap<String, PropertySimple>();
		if (pluginConfig == null)
			return customProperties;
		PropertyMap customPropsMap = pluginConfig.getMap("custom-properties"); //$NON-NLS-1$
		if (customPropsMap != null) {
			Collection<Property> customProps = customPropsMap.getMap().values();
			for (Property customProp : customProps) {
				if (!(customProp instanceof PropertySimple)) {
					LOG
							.error("Custom property definitions in plugin configuration must be simple properties - property " //$NON-NLS-1$
									+ customProp + " is not - ignoring..."); //$NON-NLS-1$
					continue;
				}
				customProperties.put(customProp.getName(),
						(PropertySimple) customProp);
			}
		}
		return customProperties;
	}

	public static Configuration convertManagedObjectToConfiguration(
			Map<String, ManagedProperty> managedProperties,
			Map<String, PropertySimple> customProps, ResourceType resourceType) {
		Configuration config = new Configuration();
		ConfigurationDefinition configDef = resourceType
				.getResourceConfigurationDefinition();
		Map<String, PropertyDefinition> propDefs = configDef
				.getPropertyDefinitions();
		Set<String> propNames = managedProperties.keySet();
		for (String propName : propNames) {
			PropertyDefinition propertyDefinition = propDefs.get(propName);
			ManagedProperty managedProperty = managedProperties.get(propName);
			if (propertyDefinition == null) {
				if (!managedProperty.hasViewUse(ViewUse.STATISTIC))
					LOG
							.debug(resourceType
									+ " does not define a property corresponding to ManagedProperty '" //$NON-NLS-1$
									+ propName + "'."); //$NON-NLS-1$
				continue;
			}
			if (managedProperty == null) {
				// This should never happen, but don't let it blow us up.
				LOG.error("ManagedProperty '" + propName //$NON-NLS-1$
						+ "' has a null value in the ManagedProperties Map."); //$NON-NLS-1$
				continue;
			}
			MetaValue metaValue = managedProperty.getValue();
			if (managedProperty.isRemoved() || metaValue == null) {
				// Don't even add a Property to the Configuration if the
				// ManagedProperty is flagged as removed or has a
				// null value.
				continue;
			}
			PropertySimple customProp = customProps.get(propName);
			PropertyAdapter<Property, PropertyDefinition> propertyAdapter = PropertyAdapterFactory
					.getCustomPropertyAdapter(customProp);
			if (propertyAdapter == null)
				propertyAdapter = PropertyAdapterFactory
						.getPropertyAdapter(metaValue);
			if (propertyAdapter == null) {
				LOG
						.error("Unable to find a PropertyAdapter for ManagedProperty '" //$NON-NLS-1$
								+ propName
								+ "' with MetaType [" //$NON-NLS-1$
								+ metaValue.getMetaType()
								+ "] for ResourceType '" //$NON-NLS-1$
								+ resourceType.getName() + "'."); //$NON-NLS-1$
				continue; 
			}
			Property property = propertyAdapter.convertToProperty(metaValue,
					propertyDefinition);
			config.put(property);
		}
		return config;
	}

	public static void convertConfigurationToManagedProperties(Map<String, ManagedProperty> managedProperties, Configuration configuration, ResourceType resourceType, String prefix) {
		ConfigurationDefinition configDefinition = resourceType.getResourceConfigurationDefinition();
		for (ManagedProperty managedProperty : managedProperties.values()) {
			String propertyName = managedProperty.getName();
			if (prefix != null) {
				propertyName = prefix + "." + propertyName; //$NON-NLS-1$
			}
			PropertyDefinition propertyDefinition = configDefinition.get(propertyName);
			if (propertyDefinition == null) {
				// The managed property is not defined in the configuration
				continue;
			}
			populateManagedPropertyFromProperty(managedProperty,propertyDefinition, configuration);
		}
		return;
	}

	public static void populateManagedPropertyFromProperty(ManagedProperty managedProperty, PropertyDefinition propertyDefinition, Configuration configuration) {
		// If the ManagedProperty defines a default value, assume it's more
		// definitive than any default value that may
		// have been defined in the plugin descriptor, and update the
		// PropertyDefinition to use that as its default
		// value.
		MetaValue defaultValue = managedProperty.getDefaultValue();
		if (defaultValue != null) {
			updateDefaultValueOnPropertyDefinition(propertyDefinition,defaultValue);
		}
		MetaValue metaValue = managedProperty.getValue();
		PropertyAdapter propertyAdapter = null;
		if (metaValue != null) {
			LOG.trace("Populating existing MetaValue of type " //$NON-NLS-1$
					+ metaValue.getMetaType() + " from Teiid property " //$NON-NLS-1$
					+ propertyDefinition.getName() + " with definition " //$NON-NLS-1$
					+ propertyDefinition + "..."); //$NON-NLS-1$
			propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaValue);

			propertyAdapter.populateMetaValueFromProperty(configuration.getSimple(propertyDefinition.getName()), metaValue, propertyDefinition);
			managedProperty.setValue(metaValue);
		} else {
			MetaType metaType = managedProperty.getMetaType();
			propertyAdapter = PropertyAdapterFactory.getPropertyAdapter(metaType);
			LOG.trace("Converting property " + propertyDefinition.getName() 	+ " with definition " + propertyDefinition 	+ " to MetaValue of type " + metaType + "..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			metaValue = propertyAdapter.convertToMetaValue(configuration.getSimple(propertyDefinition.getName()),propertyDefinition, metaType);
			managedProperty.setValue(metaValue);
		}

	}

	private static void updateDefaultValueOnPropertyDefinition(
			PropertyDefinition propertyDefinition,
			@NotNull MetaValue defaultValue) {
		if (!(propertyDefinition instanceof PropertyDefinitionSimple)) {
			LOG.debug("Cannot update default value on non-simple property definition " //$NON-NLS-1$
							+ propertyDefinition + "(default value is " //$NON-NLS-1$
							+ defaultValue + ")."); //$NON-NLS-1$
			return;
		}
		MetaType metaType = defaultValue.getMetaType();
		if (!metaType.isSimple() && !metaType.isEnum()) {
			LOG.debug("Cannot update default value on " + propertyDefinition //$NON-NLS-1$
					+ ", because default value's type (" + metaType //$NON-NLS-1$
					+ ") is not simple or enum."); //$NON-NLS-1$
			return;
		}
		PropertyDefinitionSimple propertyDefinitionSimple = (PropertyDefinitionSimple) propertyDefinition;
		if (metaType.isSimple()) {
			SimpleValue defaultSimpleValue = (SimpleValue) defaultValue;
			Serializable value = defaultSimpleValue.getValue();
			propertyDefinitionSimple.setDefaultValue((value != null) ? value.toString() : null);
		} else { // defaultValueMetaType.isEnum()
			EnumValue defaultEnumValue = (EnumValue) defaultValue;
			Serializable value = defaultEnumValue.getValue();
			propertyDefinitionSimple.setDefaultValue((value != null) ? value.toString() : null);
		}
	}

	public static MetaType convertPropertyDefinitionToMetaType(
			PropertyDefinition propDef) {
		MetaType memberMetaType;
		if (propDef instanceof PropertyDefinitionSimple) {
			PropertySimpleType propSimpleType = ((PropertyDefinitionSimple) propDef)
					.getType();
			memberMetaType = convertPropertySimpleTypeToSimpleMetaType(propSimpleType);
		} else if (propDef instanceof PropertyDefinitionList) {
			// TODO (very low priority, since lists of lists are not going to be
			// at all common)
			memberMetaType = null;
		} else if (propDef instanceof PropertyDefinitionMap) {
			Map<String, PropertyDefinition> memberPropDefs = ((PropertyDefinitionMap) propDef)
					.getPropertyDefinitions();
			if (memberPropDefs.isEmpty())
				throw new IllegalStateException(
						"PropertyDefinitionMap doesn't contain any member PropertyDefinitions."); //$NON-NLS-1$
			// NOTE: We assume member prop defs are all of the same type, since
			// for MapCompositeMetaTypes, they have to be.
			PropertyDefinition mapMemberPropDef = memberPropDefs.values()
					.iterator().next();
			MetaType mapMemberMetaType = convertPropertyDefinitionToMetaType(mapMemberPropDef);
			memberMetaType = new MapCompositeMetaType(mapMemberMetaType);
		} else {
			throw new IllegalStateException(
					"List member PropertyDefinition has unknown type: " //$NON-NLS-1$
							+ propDef.getClass().getName());
		}
		return memberMetaType;
	}

	private static MetaType convertPropertySimpleTypeToSimpleMetaType(
			PropertySimpleType memberSimpleType) {
		MetaType memberMetaType;
		Class memberClass;
		switch (memberSimpleType) {
		case BOOLEAN:
			memberClass = Boolean.class;
			break;
		case INTEGER:
			memberClass = Integer.class;
			break;
		case LONG:
			memberClass = Long.class;
			break;
		case FLOAT:
			memberClass = Float.class;
			break;
		case DOUBLE:
			memberClass = Double.class;
			break;
		default:
			memberClass = String.class;
			break;
		}
		memberMetaType = SimpleMetaType.resolve(memberClass.getName());
		return memberMetaType;
	}

	public static SimpleValue wrap(MetaType type, String value)
			throws Exception {
		if (type instanceof SimpleMetaType) {
			SimpleMetaType st = (SimpleMetaType) type;

			if (SimpleMetaType.BIGDECIMAL.equals(st)) {
				return new SimpleValueSupport(st, new BigDecimal(value));
			} else if (SimpleMetaType.BIGINTEGER.equals(st)) {
				return new SimpleValueSupport(st, new BigInteger(value));
			} else if (SimpleMetaType.BOOLEAN.equals(st)) {
				return new SimpleValueSupport(st, Boolean.valueOf(value));
			} else if (SimpleMetaType.BOOLEAN_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, Boolean.valueOf(value)
						.booleanValue());
			} else if (SimpleMetaType.BYTE.equals(st)) {
				return new SimpleValueSupport(st, new Byte(value.getBytes()[0]));
			} else if (SimpleMetaType.BYTE_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, value.getBytes()[0]);
			} else if (SimpleMetaType.CHARACTER.equals(st)) {
				return new SimpleValueSupport(st,
						new Character(value.charAt(0)));
			} else if (SimpleMetaType.CHARACTER_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, value.charAt(0));
			} else if (SimpleMetaType.DATE.equals(st)) {
				try {
					return new SimpleValueSupport(st, SimpleDateFormat
							.getInstance().parse(value));
				} catch (ParseException e) {
					throw new Exception(
							"Failed to convert value to SimpleValue", e); //$NON-NLS-1$
				}
			} else if (SimpleMetaType.DOUBLE.equals(st)) {
				return new SimpleValueSupport(st, Double.valueOf(value));
			} else if (SimpleMetaType.DOUBLE_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, Double.parseDouble(value));
			} else if (SimpleMetaType.FLOAT.equals(st)) {
				return new SimpleValueSupport(st, Float.parseFloat(value));
			} else if (SimpleMetaType.FLOAT_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, Float.valueOf(value));
			} else if (SimpleMetaType.INTEGER.equals(st)) {
				return new SimpleValueSupport(st, Integer.valueOf(value));
			} else if (SimpleMetaType.INTEGER_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, Integer.parseInt(value));
			} else if (SimpleMetaType.LONG.equals(st)) {
				return new SimpleValueSupport(st, Long.valueOf(value));
			} else if (SimpleMetaType.LONG_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, Long.parseLong(value));
			} else if (SimpleMetaType.SHORT.equals(st)) {
				return new SimpleValueSupport(st, Short.valueOf(value));
			} else if (SimpleMetaType.SHORT_PRIMITIVE.equals(st)) {
				return new SimpleValueSupport(st, Short.parseShort(value));
			} else if (SimpleMetaType.STRING.equals(st)) {
				return new SimpleValueSupport(st, value);
			}
		}
		throw new Exception("Failed to convert value to SimpleValue"); //$NON-NLS-1$
	}

}
