/* AlgorithmParameters.java --- Algorithm Parameters Implementation Class
   Copyright (C) 1999, 2003, 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.security;

import gnu.java.lang.CPStringBuilder;

import gnu.java.security.Engine;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;

/**
 * <code>AlgorithmParameters</code> is an Algorithm Parameters class which
 * provides an interface through which the user can manage the parameters of an
 * Algorithm.
 *
 * @author Mark Benvenuto
 * @since 1.2
 * @see AlgorithmParameterSpec
 * @see java.security.spec.DSAParameterSpec
 * @see KeyPairGenerator
 */
public class AlgorithmParameters
{
  /** Service name for algorithm parameters. */
  private static final String ALGORITHM_PARAMETERS = "AlgorithmParameters";

  private AlgorithmParametersSpi paramSpi;
  private Provider provider;
  private String algorithm;

  /**
   * Constructs a new instance of <code>AlgorithmParameters</code>.
   * 
   * @param paramSpi
   *          the engine to use.
   * @param provider
   *          the provider to use.
   * @param algorithm
   *          the algorithm to use.
   */
  protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
                                Provider provider, String algorithm)
  {
    this.paramSpi = paramSpi;
    this.provider = provider;
    this.algorithm = algorithm;
  }

  /** @return A string with the name of the algorithm used. */
  public final String getAlgorithm()
  {
    return algorithm;
  }

  /**
   * Returns a new instance of <code>AlgorithmParameters</code> representing
   * the specified algorithm parameters.
   * <p>
   * The returned <code>AlgorithmParameters</code> must still be initialized
   * with an <code>init()</code> method.
   * 
   * @param algorithm the algorithm to use.
   * @return the new instance repesenting the desired algorithm.
   * @throws NoSuchAlgorithmException if the algorithm is not implemented by any
   *           provider.
   * @throws IllegalArgumentException if <code>algorithm</code> is
   *           <code>null</code> or is an empty string.
   */
  public static AlgorithmParameters getInstance(String algorithm)
      throws NoSuchAlgorithmException
  {
    Provider[] p = Security.getProviders();
    NoSuchAlgorithmException lastException = null;
    for (int i = 0; i < p.length; i++)
      try
        {
          return getInstance(algorithm, p[i]);
        }
      catch (NoSuchAlgorithmException x)
        {
          lastException = x;
        }
    if (lastException != null)
      throw lastException;
    throw new NoSuchAlgorithmException(algorithm);
  }

  /**
   * Returns a new instance of <code>AlgorithmParameters</code> representing
   * the specified algorithm parameters from a named provider.
   * <p>
   * The returned <code>AlgorithmParameters</code> must still be intialized
   * with an <code>init()</code> method.
   * </p>
   * 
   * @param algorithm the algorithm to use.
   * @param provider the name of the {@link Provider} to use.
   * @return the new instance repesenting the desired algorithm.
   * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
   *           named provider.
   * @throws NoSuchProviderException if the named provider was not found.
   * @throws IllegalArgumentException if either <code>algorithm</code> or
   *           <code>provider</code> is <code>null</code> or empty.
   */
  public static AlgorithmParameters getInstance(String algorithm,
                                                String provider)
      throws NoSuchAlgorithmException, NoSuchProviderException
  {
    if (provider == null)
      throw new IllegalArgumentException("provider MUST NOT be null");
    provider = provider.trim();
    if (provider.length() == 0)
      throw new IllegalArgumentException("provider MUST NOT be empty");
    Provider p = Security.getProvider(provider);
    if (p == null)
      throw new NoSuchProviderException(provider);
    return getInstance(algorithm, p);
  }

  /**
   * Returns a new instance of <code>AlgorithmParameters</code> representing
   * the specified algorithm parameters from the specified {@link Provider}.
   * <p>
   * The returned <code>AlgorithmParameters</code> must still be intialized
   * with an <code>init()</code> method.
   * 
   * @param algorithm the algorithm to use.
   * @param provider the {@link Provider} to use.
   * @return the new instance repesenting the desired algorithm.
   * @throws NoSuchAlgorithmException if the algorithm is not implemented by the
   *           {@link Provider}.
   * @throws IllegalArgumentException if either <code>algorithm</code> or
   *           <code>provider</code> is <code>null</code>, or if
   *           <code>algorithm</code> is an empty string.
   * @since 1.4
   */
  public static AlgorithmParameters getInstance(String algorithm,
                                                Provider provider)
      throws NoSuchAlgorithmException
  {
    CPStringBuilder sb = new CPStringBuilder("AlgorithmParameters for algorithm [")
        .append(algorithm).append("] from provider[")
        .append(provider).append("] could not be created");
    Throwable cause;
    try
      {
        Object spi = Engine.getInstance(ALGORITHM_PARAMETERS, algorithm, provider);
        return new AlgorithmParameters((AlgorithmParametersSpi) spi,
                                       provider,
                                       algorithm);
      }
    catch (InvocationTargetException x)
      {
        cause = x.getCause();
        if (cause instanceof NoSuchAlgorithmException)
          throw (NoSuchAlgorithmException) cause;
        if (cause == null)
          cause = x;
      }
    catch (ClassCastException x)
      {
        cause = x;
      }
    NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
    x.initCause(cause);
    throw x;
  }

  /** @return the provider of this parameter object. */
  public final Provider getProvider()
  {
    return provider;
  }

  /**
   * Initializes the engine with the specified {@link AlgorithmParameterSpec}.
   * 
   * @param paramSpec
   *          A {@link AlgorithmParameterSpec} to use.
   * @throws InvalidParameterSpecException
   *           if <code>paramSpec</code> is invalid.
   */
  public final void init(AlgorithmParameterSpec paramSpec)
    throws InvalidParameterSpecException
  {
    paramSpi.engineInit(paramSpec);
  }

  /**
   * Initializes the engine with the specified parameters stored in the byte
   * array and decodes them according to the ASN.1 specification. If the ASN.1
   * specification exists then it succeeds otherwise an {@link IOException} is
   * thrown.
   * 
   * @param params
   *          the parameters to use.
   * @throws IOException
   *           if a decoding error occurs.
   */
  public final void init(byte[]params) throws IOException
  {
    paramSpi.engineInit(params);
  }

  /**
   * Initializes the engine with the specified parameters stored in the byte
   * array and decodes them according to the specified decoding specification.
   * If <code>format</code> is <code>null</code>, then this method decodes the
   * byte array using the ASN.1 specification if it exists, otherwise it throws
   * an {@link IOException}.
   * 
   * @param params
   *          the parameters to use.
   * @param format
   *          the name of decoding format to use.
   * @throws IOException
   *           if a decoding error occurs.
   */
  public final void init(byte[]params, String format) throws IOException
  {
    paramSpi.engineInit(params, format);
  }

  /**
   * Returns a new instance of <code>AlgorithmParameters</code> as a
   * designated parameter specification {@link Class}.
   * 
   * @param paramSpec
   *          the {@link Class} to use.
   * @return the parameter specification.
   * @throws InvalidParameterSpecException
   *           if <code>paramSpec</code> is invalid.
   */
  public final <T extends AlgorithmParameterSpec>
  T getParameterSpec(Class<T> paramSpec)
    throws InvalidParameterSpecException
  {
    return paramSpi.engineGetParameterSpec(paramSpec);
  }

  /**
   * Returns the parameters in the default encoding format. The primary encoding
   * format is ASN.1 if it exists for the specified type.
   * 
   * @return byte array representing the parameters.
   */
  public final byte[] getEncoded() throws IOException
  {
    return paramSpi.engineGetEncoded();
  }

  /**
   * Returns the parameters in the specified encoding format. If
   * <code>format</code> is <code>null</code> then the ASN.1 encoding
   * format is used if it exists for the specified type.
   * 
   * @param format
   *          the name of the encoding format to use.
   * @return the parameters encoded using the specified encoding scheme.
   * @throws IOException
   *           if an encoding exception occurs, or if this parameter object has
   *           not been initialized.
   */
  public final byte[] getEncoded(String format) throws IOException
  {
    return paramSpi.engineGetEncoded(format);
  }

  /**
   * Returns a string representation of the encoded form.
   * 
   * @return a string representation of the encoded form.
   */
  public final String toString()
  {
    return paramSpi.engineToString();
  }
}
