/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.uima.fit.factory;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.IllegalClassException;
import org.apache.uima.UIMA_IllegalArgumentException;
import org.apache.uima.fit.factory.ExternalResourceFactory.ResourceValueType;
import org.apache.uima.fit.internal.ReflectionUtil;
import org.apache.uima.fit.internal.propertyeditors.PropertyEditorUtil;
import org.apache.uima.resource.ConfigurableDataResourceSpecifier;
import org.apache.uima.resource.CustomResourceSpecifier;
import org.apache.uima.resource.Parameter;
import org.apache.uima.resource.PearSpecifier;
import org.apache.uima.resource.ResourceCreationSpecifier;
import org.apache.uima.resource.ResourceSpecifier;
import org.apache.uima.resource.impl.Parameter_impl;
import org.apache.uima.resource.metadata.ConfigurationParameter;
import org.apache.uima.resource.metadata.NameValuePair;
import org.apache.uima.resource.metadata.ResourceMetaData;
import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.TypeMismatchException;

/**
 */

public final class ConfigurationParameterFactory {
  private ConfigurationParameterFactory() {
    // This class is not meant to be instantiated
  }

  /**
   * A mapping from Java class names to UIMA configuration parameter type names. Used by
   * setConfigurationParameters().
   */
  private static final Map<String, String> JAVA_UIMA_TYPE_MAP = new HashMap<String, String>();
  static {
    JAVA_UIMA_TYPE_MAP.put(Boolean.class.getName(), ConfigurationParameter.TYPE_BOOLEAN);
    JAVA_UIMA_TYPE_MAP.put(Float.class.getName(), ConfigurationParameter.TYPE_FLOAT);
    JAVA_UIMA_TYPE_MAP.put(Double.class.getName(), ConfigurationParameter.TYPE_FLOAT);
    JAVA_UIMA_TYPE_MAP.put(Integer.class.getName(), ConfigurationParameter.TYPE_INTEGER);
    JAVA_UIMA_TYPE_MAP.put(String.class.getName(), ConfigurationParameter.TYPE_STRING);
    JAVA_UIMA_TYPE_MAP.put("boolean", ConfigurationParameter.TYPE_BOOLEAN);
    JAVA_UIMA_TYPE_MAP.put("float", ConfigurationParameter.TYPE_FLOAT);
    JAVA_UIMA_TYPE_MAP.put("double", ConfigurationParameter.TYPE_FLOAT);
    JAVA_UIMA_TYPE_MAP.put("int", ConfigurationParameter.TYPE_INTEGER);

  }

  /**
   * This method determines if the field is annotated with
   * {@link org.apache.uima.fit.descriptor.ConfigurationParameter}.
   * 
   * @param field
   *          the field to analyze
   * @return whether the field is marked as a configuration parameter
   */
  public static boolean isConfigurationParameterField(Field field) {
    return ReflectionUtil.isAnnotationPresent(field,
            org.apache.uima.fit.descriptor.ConfigurationParameter.class);
  }

  /**
   * Determines the default value of an annotated configuration parameter. The returned value is not
   * necessarily the value that the annotated member variable will be instantiated with in
   * ConfigurationParameterInitializer which does extra work to convert the UIMA configuration
   * parameter value to comply with the type of the member variable.
   * 
   * @param field
   *          the field to analyze
   * @return the default value
   */
  public static Object getDefaultValue(Field field) {
    if (isConfigurationParameterField(field)) {
      org.apache.uima.fit.descriptor.ConfigurationParameter annotation = ReflectionUtil
              .getAnnotation(field, org.apache.uima.fit.descriptor.ConfigurationParameter.class);

      String[] stringValue = annotation.defaultValue();
      if (stringValue.length == 1
              && stringValue[0]
                      .equals(org.apache.uima.fit.descriptor.ConfigurationParameter.NO_DEFAULT_VALUE)) {
        return null;
      }

      String valueType = getConfigurationParameterType(field);
      boolean isMultiValued = isMultiValued(field);

      if (!isMultiValued) {
        if (ConfigurationParameter.TYPE_BOOLEAN.equals(valueType)) {
          return Boolean.parseBoolean(stringValue[0]);
        } else if (ConfigurationParameter.TYPE_FLOAT.equals(valueType)) {
          return Float.parseFloat(stringValue[0]);
        } else if (ConfigurationParameter.TYPE_INTEGER.equals(valueType)) {
          return Integer.parseInt(stringValue[0]);
        } else if (ConfigurationParameter.TYPE_STRING.equals(valueType)) {
          return stringValue[0];
        }
        throw new UIMA_IllegalArgumentException(
                UIMA_IllegalArgumentException.METADATA_ATTRIBUTE_TYPE_MISMATCH, new Object[] {
                    valueType, "type" });
      } else {
        if (ConfigurationParameter.TYPE_BOOLEAN.equals(valueType)) {
          Boolean[] returnValues = new Boolean[stringValue.length];
          for (int i = 0; i < stringValue.length; i++) {
            returnValues[i] = Boolean.parseBoolean(stringValue[i]);
          }
          return returnValues;
        } else if (ConfigurationParameter.TYPE_FLOAT.equals(valueType)) {
          Float[] returnValues = new Float[stringValue.length];
          for (int i = 0; i < stringValue.length; i++) {
            returnValues[i] = Float.parseFloat(stringValue[i]);
          }
          return returnValues;
        } else if (ConfigurationParameter.TYPE_INTEGER.equals(valueType)) {
          Integer[] returnValues = new Integer[stringValue.length];
          for (int i = 0; i < stringValue.length; i++) {
            returnValues[i] = Integer.parseInt(stringValue[i]);
          }
          return returnValues;
        } else if (ConfigurationParameter.TYPE_STRING.equals(valueType)) {
          return stringValue;
        }
        throw new UIMA_IllegalArgumentException(
                UIMA_IllegalArgumentException.METADATA_ATTRIBUTE_TYPE_MISMATCH, new Object[] {
                    valueType, "type" });

      }

    } else {
      throw new IllegalArgumentException("field is not annotated with annotation of type "
              + org.apache.uima.fit.descriptor.ConfigurationParameter.class.getName());
    }
  }

  private static String getConfigurationParameterType(Field field) {
    Class<?> parameterClass = field.getType();
    String parameterClassName;
    if (parameterClass.isArray()) {
      parameterClassName = parameterClass.getComponentType().getName();
    } else if (Collection.class.isAssignableFrom(parameterClass)) {
      ParameterizedType collectionType = (ParameterizedType) field.getGenericType();
      parameterClassName = ((Class<?>) (collectionType.getActualTypeArguments()[0])).getName();
    } else {
      parameterClassName = parameterClass.getName();
    }
    String parameterType = JAVA_UIMA_TYPE_MAP.get(parameterClassName);
    if (parameterType == null) {
      return ConfigurationParameter.TYPE_STRING;
    }
    return parameterType;
  }

  private static boolean isMultiValued(Field field) {
    Class<?> parameterClass = field.getType();
    if (parameterClass.isArray()) {
      return true;
    } else if (Collection.class.isAssignableFrom(parameterClass)) {
      return true;
    }
    return false;
  }

  /**
   * This method generates the default name of a configuration parameter that is defined by an
   * {@link org.apache.uima.fit.descriptor.ConfigurationParameter} annotation when no name is given
   * 
   * @param field
   *          the field to analyze
   * @return the parameter name
   */
  public static String getConfigurationParameterName(Field field) {
    if (isConfigurationParameterField(field)) {
      org.apache.uima.fit.descriptor.ConfigurationParameter annotation = ReflectionUtil
              .getAnnotation(field, org.apache.uima.fit.descriptor.ConfigurationParameter.class);
      String name = annotation.name();
      if (name.equals(org.apache.uima.fit.descriptor.ConfigurationParameter.USE_FIELD_NAME)) {
        name = field.getName();
      }
      return name;
    }
    return null;
  }

  /**
   * A factory method for creating a ConfigurationParameter from a given field definition
   * 
   * @param field
   *          the field to analyze
   * @return the configuration parameter.
   */
  public static ConfigurationParameter createPrimitiveParameter(Field field) {
    if (isConfigurationParameterField(field)) {
      org.apache.uima.fit.descriptor.ConfigurationParameter annotation = ReflectionUtil
              .getAnnotation(field, org.apache.uima.fit.descriptor.ConfigurationParameter.class);
      String name = getConfigurationParameterName(field);
      boolean multiValued = isMultiValued(field);
      String parameterType = getConfigurationParameterType(field);
      return createPrimitiveParameter(name, parameterType, annotation.description(), multiValued,
              annotation.mandatory());
    } else {
      throw new IllegalArgumentException("field is not annotated with annotation of type "
              + org.apache.uima.fit.descriptor.ConfigurationParameter.class.getName());
    }
  }

  /**
   * A factory method for creating a ConfigurationParameter object.
   * 
   * @param name
   *          the parameter name
   * @param parameterClass
   *          the parameter class
   * @param parameterDescription
   *          the parameter description
   * @param isMandatory
   *          whether the parameter is mandatory
   * @return the configuration parameter
   */
  public static ConfigurationParameter createPrimitiveParameter(String name,
          Class<?> parameterClass, String parameterDescription, boolean isMandatory) {
    String parameterClassName;
    if (parameterClass.isArray()) {
      parameterClassName = parameterClass.getComponentType().getName();
    } else {
      parameterClassName = parameterClass.getName();
    }

    String parameterType = JAVA_UIMA_TYPE_MAP.get(parameterClassName);
    if (parameterType == null) {
      // If we cannot map the type, we'll try to convert it to a String
      parameterType = ConfigurationParameter.TYPE_STRING;
    }
    return createPrimitiveParameter(name, parameterType, parameterDescription,
            parameterClass.isArray(), isMandatory);
  }

  /**
   * Convert a value so it can be injected into a UIMA component. UIMA only supports several
   * parameter types. If the value is not of these types, this method can be used to coerce the
   * value into a supported type (typically String). It is also used to convert primitive arrays to
   * object arrays when necessary.
   * 
   * @param param
   *          the configuration parameter.
   * @param aValue
   *          the parameter value.
   * @return the converted value.
   */
  protected static Object convertParameterValue(ConfigurationParameter param, Object aValue) {
    Object value = aValue;
    if (value.getClass().isArray()
            && value.getClass().getComponentType().getName().equals("boolean")) {
      value = ArrayUtils.toObject((boolean[]) value);
    } else if (value.getClass().isArray()
            && value.getClass().getComponentType().getName().equals("int")) {
      value = ArrayUtils.toObject((int[]) value);
    } else if (value.getClass().isArray()
            && value.getClass().getComponentType().getName().equals("float")) {
      value = ArrayUtils.toObject((float[]) value);
    } else {
      try {
        if (param.getType().equals(ConfigurationParameter.TYPE_STRING)) {
          SimpleTypeConverter converter = new SimpleTypeConverter();
          PropertyEditorUtil.registerUimaFITEditors(converter);
          if (value.getClass().isArray() || value instanceof Collection) {
            value = converter.convertIfNecessary(value, String[].class);
          } else {
            value = converter.convertIfNecessary(value, String.class);
          }
        }
      } catch (TypeMismatchException e) {
        throw new IllegalArgumentException(e.getMessage(), e);
      }
    }

    return value;
  }

  /**
   * A factory method for creating a ConfigurationParameter object.
   * 
   * @param name
   *          the parameter name
   * @param parameterType
   *          the parameter type
   * @param parameterDescription
   *          the parameter description
   * @param isMultiValued
   *          whether the parameter is multi-valued
   * @param isMandatory
   *          whether the parameter is mandatory
   * @return the configuration parameter
   */
  public static ConfigurationParameter createPrimitiveParameter(String name, String parameterType,
          String parameterDescription, boolean isMultiValued, boolean isMandatory) {
    ConfigurationParameter param = new ConfigurationParameter_impl();
    param.setName(name);
    param.setType(parameterType);
    param.setDescription(parameterDescription);
    param.setMultiValued(isMultiValued);
    param.setMandatory(isMandatory);
    return param;
  }

  /**
   * Analyze a component for parameters and default values, merge that with parameter values
   * specified, potentially adding extra parameters. Set the merged result into the provided
   * descriptor.
   * 
   * @param desc
   *          the descriptor into which to merge the parameters
   * @param componentClass
   *          the component class which will be analyzed for parameters. Must match the
   *          implementationName set in the descriptor.
   * @param configurationParameters
   *          additional parameter names
   * @param configurationValues
   *          additional parameters values
   */
  public static void setParameters(ResourceCreationSpecifier desc,
          Class<?> componentClass, ConfigurationParameter[] configurationParameters,
          Object[] configurationValues) {
    ConfigurationData reflectedConfigurationData = ConfigurationParameterFactory
            .createConfigurationData(componentClass);
    ResourceCreationSpecifierFactory.setConfigurationParameters(desc,
            reflectedConfigurationData.configurationParameters,
            reflectedConfigurationData.configurationValues);
    if (configurationParameters != null) {
      ResourceCreationSpecifierFactory.setConfigurationParameters(desc, configurationParameters,
              configurationValues);
    }
  }
  
  /**
   * This method converts configuration data provided as an array of objects and returns a
   * {@link ConfigurationData} object. This should only be used to prepare values supplied in a
   * factory method call for merging with existing parameter declarations, e.g. extracted from a
   * class using {@link #createConfigurationData(Class)}.
   * 
   * @param configurationData
   *          configuration parameters as (name, value) pairs, so there should always be an even
   *          number of parameters.
   * @return the configuration data
   */
  public static ConfigurationData createConfigurationData(Object... configurationData) {
    if (configurationData == null) {
      return new ConfigurationData(new ConfigurationParameter[0], new Object[0]);
    }

    ensureParametersComeInPairs(configurationData);

    int numberOfParameters = configurationData.length / 2;
    List<ConfigurationParameter> configurationParameters = new ArrayList<ConfigurationParameter>();
    List<Object> configurationValues = new ArrayList<Object>();

    for (int i = 0; i < numberOfParameters; i++) {
      String name = (String) configurationData[i * 2];
      Object value = configurationData[i * 2 + 1];

      if (value == null
              || ExternalResourceFactory.getExternalResourceParameterType(value) != ResourceValueType.NO_RESOURCE) {
        continue;
      }

      ConfigurationParameter param = ConfigurationParameterFactory.createPrimitiveParameter(name,
              value.getClass(), null, false);
      configurationParameters.add(param);
      configurationValues.add(ConfigurationParameterFactory.convertParameterValue(param, value));
    }
    return new ConfigurationData(
            configurationParameters.toArray(new ConfigurationParameter[configurationParameters
                    .size()]), configurationValues.toArray());
  }

  /**
   * This method creates configuration data for a given class definition using reflection and the
   * configuration parameter annotation
   * 
   * @param componentClass
   *          the class to analyze
   * @return the configuration settings extracted from the class
   */
  public static ConfigurationData createConfigurationData(Class<?> componentClass) {
    List<ConfigurationParameter> configurationParameters = new ArrayList<ConfigurationParameter>();
    List<Object> configurationValues = new ArrayList<Object>();

    for (Field field : ReflectionUtil.getFields(componentClass)) {
      if (ConfigurationParameterFactory.isConfigurationParameterField(field)) {
        configurationParameters.add(ConfigurationParameterFactory.createPrimitiveParameter(field));
        configurationValues.add(ConfigurationParameterFactory.getDefaultValue(field));
      }
    }

    return new ConfigurationData(
            configurationParameters.toArray(new ConfigurationParameter[configurationParameters
                    .size()]), configurationValues.toArray(new Object[configurationValues.size()]));
  }

  /**
   * A simple class for storing an array of configuration parameters along with an array of the
   * values that will fill in those configuration parameters
   */
  public static class ConfigurationData {
    public ConfigurationParameter[] configurationParameters;

    public Object[] configurationValues;

    /**
     * @param configurationParameters
     *          the configuration parameters
     * @param configurationValues
     *          the configuration parameter values
     */
    public ConfigurationData(ConfigurationParameter[] configurationParameters,
            Object[] configurationValues) {
      this.configurationParameters = configurationParameters;
      this.configurationValues = configurationValues;
    }

  }

  /**
   * This method adds configuration parameter information to the specifier given the provided
   * configuration data
   * 
   * @param specifier
   *          the specified to add the parameters to
   * @param configurationData
   *          should consist of name value pairs.
   */
  public static void addConfigurationParameters(ResourceCreationSpecifier specifier,
          Object... configurationData) {
    ConfigurationData cdata = ConfigurationParameterFactory
            .createConfigurationData(configurationData);
    ResourceCreationSpecifierFactory.setConfigurationParameters(specifier,
            cdata.configurationParameters, cdata.configurationValues);
  }

  /**
   * Provides a mechanism to add configuration parameter information to a specifier for the given
   * classes. This method may be useful in situations where a class definition has annotated
   * configuration parameters that you want to include in the given specifier.
   * 
   * @param specifier
   *          the specified to add the parameters to
   * @param dynamicallyLoadedClasses
   *          the classes to analyze and extract parameter information from
   */
  public static void addConfigurationParameters(ResourceCreationSpecifier specifier,
          List<Class<?>> dynamicallyLoadedClasses) {
    for (Class<?> dynamicallyLoadedClass : dynamicallyLoadedClasses) {
      ConfigurationData reflectedConfigurationData = ConfigurationParameterFactory
              .createConfigurationData(dynamicallyLoadedClass);
      ResourceCreationSpecifierFactory.setConfigurationParameters(specifier,
              reflectedConfigurationData.configurationParameters,
              reflectedConfigurationData.configurationValues);
    }
  }

  /**
   * Provides a mechanism to add configuration parameter information to a specifier for the given
   * classes. This method may be useful in situations where a class definition has annotated
   * configuration parameters that you want to include in the given specifier
   * 
   * @param specifier
   *          the specified to add the parameters to
   * @param dynamicallyLoadedClasses
   *          the classes to analyze and extract parameter information from
   */
  public static void addConfigurationParameters(ResourceCreationSpecifier specifier,
          Class<?>... dynamicallyLoadedClasses) {
    for (Class<?> dynamicallyLoadedClass : dynamicallyLoadedClasses) {
      ConfigurationData reflectedConfigurationData = ConfigurationParameterFactory
              .createConfigurationData(dynamicallyLoadedClass);
      ResourceCreationSpecifierFactory.setConfigurationParameters(specifier,
              reflectedConfigurationData.configurationParameters,
              reflectedConfigurationData.configurationValues);
    }
  }

  /**
   * Adds a single configuration parameter name value pair to a specifier
   * 
   * @param specifier
   *          the specifier to add the parameter setting to
   * @param name
   *          the name of the parameter
   * @param value
   *          the parameter value
   */
  public static void addConfigurationParameter(ResourceCreationSpecifier specifier, String name,
          Object value) {
    ConfigurationData cdata = ConfigurationParameterFactory.createConfigurationData(name, value);
    ResourceCreationSpecifierFactory.setConfigurationParameters(specifier,
            cdata.configurationParameters, cdata.configurationValues);

  }

  /**
   * Helper method to make sure configuration parameter lists have always pairs of name/values.
   * 
   * @param configurationData
   *          the configuration parameters.
   */
  static void ensureParametersComeInPairs(Object[] configurationData) {
    if (configurationData != null && configurationData.length % 2 != 0) {
      throw new IllegalArgumentException("Parameter arguments have to "
              + "come in key/value pairs, but found odd number of " + "arguments ["
              + configurationData.length + "]");
    }
  }

  /**
   * Fetches the parameter settings from the given resource specifier.
   * 
   * @param spec
   *          a resource specifier.
   * @return the parameter settings.
   */
  public static Map<String, Object> getParameterSettings(ResourceSpecifier spec) {
    Map<String, Object> settings = new HashMap<String, Object>();
    if (spec instanceof CustomResourceSpecifier) {
      for (Parameter p : ((CustomResourceSpecifier) spec).getParameters()) {
        settings.put(p.getName(), p.getValue());
      }
    } else if (spec instanceof PearSpecifier) {
      for (Parameter p : ((PearSpecifier) spec).getParameters()) {
        settings.put(p.getName(), p.getValue());
      }
    } else if (spec instanceof ResourceCreationSpecifier) {
      for (NameValuePair p : ((ResourceCreationSpecifier) spec).getMetaData()
              .getConfigurationParameterSettings().getParameterSettings()) {
        settings.put(p.getName(), p.getValue());
      }
    } else if (spec instanceof ConfigurableDataResourceSpecifier) {
      for (NameValuePair p : ((ResourceCreationSpecifier) spec).getMetaData()
              .getConfigurationParameterSettings().getParameterSettings()) {
        settings.put(p.getName(), p.getValue());
      }
    } else {
      throw new IllegalClassException("Unsupported resource specifier class [" + spec.getClass()
              + "]");
    }
    return settings;
  }

  /**
   * Sets the specified parameter in the given resource specifier. If the specified is a
   * {@link CustomResourceSpecifier} an exception is thrown if the parameter value not a String.
   * 
   * @param aSpec
   *          a resource specifier.
   * @param name
   *          the parameter name.
   * @param value
   *          the parameter value.
   * @throws IllegalClassException
   *           if the value is not of a supported type for the given specifier.
   */
  public static void setParameter(ResourceSpecifier aSpec, String name, Object value) {
    if (aSpec instanceof CustomResourceSpecifier) {
      if (!(value instanceof String || value == null)) {
        throw new IllegalClassException(String.class, value);
      }
      CustomResourceSpecifier spec = (CustomResourceSpecifier) aSpec;

      // If the parameter is already there, update it
      boolean found = false;
      for (Parameter p : spec.getParameters()) {
        if (p.getName().equals(name)) {
          p.setValue((String) value);
          found = true;
        }
      }

      // If the parameter is not there, add it
      if (!found) {
        Parameter[] params = new Parameter[spec.getParameters().length + 1];
        System.arraycopy(spec.getParameters(), 0, params, 0, spec.getParameters().length);
        params[params.length - 1] = new Parameter_impl();
        params[params.length - 1].setName(name);
        params[params.length - 1].setValue((String) value);
        spec.setParameters(params);
      }
    } else if (aSpec instanceof PearSpecifier) {
      PearSpecifier spec = (PearSpecifier) aSpec;

      // If the parameter is already there, update it
      boolean found = false;
      for (Parameter p : spec.getParameters()) {
        if (p.getName().equals(name)) {
          p.setValue((String) value);
          found = true;
        }
      }

      // If the parameter is not there, add it
      if (!found) {
        Parameter[] params = new Parameter[spec.getParameters().length + 1];
        System.arraycopy(spec.getParameters(), 0, params, 0, spec.getParameters().length);
        params[params.length - 1] = new Parameter_impl();
        params[params.length - 1].setName(name);
        params[params.length - 1].setValue((String) value);
        spec.setParameters(params);
      }
    } else if (aSpec instanceof ResourceCreationSpecifier) {
      ResourceMetaData md = ((ResourceCreationSpecifier) aSpec).getMetaData();

      ConfigurationParameter param = md.getConfigurationParameterDeclarations()
              .getConfigurationParameter(null, name);
      if (param == null) {
        throw new IllegalArgumentException("Cannot set undeclared parameter [" + name + "]");
      }

      md.getConfigurationParameterSettings().setParameterValue(name,
              convertParameterValue(param, value));
    } else if (aSpec instanceof ConfigurableDataResourceSpecifier) {
      ResourceMetaData md = ((ConfigurableDataResourceSpecifier) aSpec).getMetaData();

      ConfigurationParameter param = md.getConfigurationParameterDeclarations()
              .getConfigurationParameter(null, name);
      if (param == null) {
        throw new IllegalArgumentException("Cannot set undeclared parameter [" + name + "]");
      }

      md.getConfigurationParameterSettings().setParameterValue(name,
              convertParameterValue(param, value));
    } else {
      throw new IllegalClassException("Unsupported resource specifier class [" + aSpec.getClass()
              + "]");
    }
  }

  /**
   * Check if the given parameter can be set on the provided specifier. Some specifier types require
   * parameters to be declared before they can be set.
   * 
   * @param aSpec
   *          the specifier to test
   * @param name
   *          the parameter to be tested
   * @return if the parameter can be set
   */
  public static boolean canParameterBeSet(ResourceSpecifier aSpec, String name) {
    if (aSpec instanceof CustomResourceSpecifier) {
      return true;
    } else if (aSpec instanceof ResourceCreationSpecifier) {
      ResourceMetaData md = ((ResourceCreationSpecifier) aSpec).getMetaData();
      return md.getConfigurationParameterDeclarations().getConfigurationParameter(null, name) != null;
    } else if (aSpec instanceof ConfigurableDataResourceSpecifier) {
      ResourceMetaData md = ((ConfigurableDataResourceSpecifier) aSpec).getMetaData();
      return md.getConfigurationParameterDeclarations().getConfigurationParameter(null, name) != null;
    } else {
      return false;
    }
  }
}
