/*
 * 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.lang3.ArrayUtils;
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.getResourceParameterType(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 IllegalArgumentException("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 IllegalArgumentException
   *           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 IllegalArgumentException("Value must be a string");
      }
      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 IllegalArgumentException("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;
    }
  }
}
