/* 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.security.Engine;

import java.io.IOException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;

/**
 * <p>This class is used as an opaque representation of cryptographic
 * parameters.</p>
 *
 * <p>An <code>AlgorithmParameters</code> object for managing the parameters
 * for a particular algorithm can be obtained by calling one of the
 * <code>getInstance()</code> factory methods (static methods that return
 * instances of a given class).</p>
 *
 * <p>There are two ways to request such an implementation: by specifying
 * either just an algorithm name, or both an algorithm name and a package
 * provider.</p>
 *
 * <ul>
 *    <li>If just an algorithm name is specified, the system will determine if
 *    there is an AlgorithmParameters implementation for the algorithm requested
 *    available in the environment, and if there is more than one, if there is
 *    a preferred one.</li>
 *    <li>If both an algorithm name and a package provider are specified, the
 *    system will determine if there is an implementation in the package
 *    requested, and throw an exception if there is not.</li>
 * </ul>
 *
 * <p>Once an <code>AlgorithmParameters</code> object is returned, it must be
 * initialized via a call to <code>init()</code>, using an appropriate
 * parameter specification or parameter encoding.</p>
 *
 * <p>A transparent parameter specification is obtained from an
 * <code>AlgorithmParameters</code> object via a call to
 * <code>getParameterSpec()</code>, and a byte encoding of the parameters is
 * obtained via a call to <code>getEncoded()</code>.</p>
 *
 * @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;

  /**
   * Creates an <code>AlgorithmParameters</code> object.
   *
   * @param paramSpi the delegate.
   * @param provider the provider.
   * @param algorithm the algorithm.
   */
  protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
                                Provider provider, String algorithm)
  {
    this.paramSpi = paramSpi;
    this.provider = provider;
    this.algorithm = algorithm;
  }

  /**
   * Returns the name of the algorithm associated with this parameter object.
   *
   * @return the algorithm name.
   */
  public final String getAlgorithm()
  {
    return algorithm;
  }

  /**
   * <p>Generates a parameter object for the specified algorithm.</p>
   *
   * <p>If the default provider package provides an implementation of the
   * requested algorithm, an instance of <code>AlgorithmParameters</code>
   * containing that implementation is returned. If the algorithm is not
   * available in the default package, other packages are searched.</p>
   *
   * <p>The returned parameter object must be initialized via a call to
   * <code>init()</code>, using an appropriate parameter specification or
   * parameter encoding.</p>
   *
   * @param algorithm the name of the algorithm requested.
   * @return the new parameter object.
   * @throws NoSuchAlgorithmException if the algorithm is not available in the
   * environment.
   */
  public static AlgorithmParameters getInstance(String algorithm)
    throws NoSuchAlgorithmException
  {
    Provider[] p = Security.getProviders();

    for (int i = 0; i < p.length; i++)
      try
        {
          return getInstance(algorithm, p[i]);
        }
      catch (NoSuchAlgorithmException e)
	{
	  // Ignore this.
	}

    throw new NoSuchAlgorithmException(algorithm);
  }

  /**
   * <p>Generates a parameter object for the specified algorithm, as supplied
   * by the specified provider, if such an algorithm is available from the
   * provider.</p>
   *
   * <p>The returned parameter object must be initialized via a call to
   * <code>init()</code>, using an appropriate parameter specification or
   * parameter encoding.</p>
   *
   * @param algorithm the name of the algorithm requested.
   * @param provider the name of the provider.
   * @return the new parameter object.
   * @throws NoSuchAlgorithmException if the algorithm is not available in the
   * package supplied by the requested provider.
   * @throws NoSuchProviderException if the provider is not available in the
   * environment.
   * @throws IllegalArgumentException if the provider name is null or empty.
   * @see Provider
   */
  public static AlgorithmParameters getInstance(String algorithm, String provider)
    throws NoSuchAlgorithmException, NoSuchProviderException
  {
    if (provider == null || provider.length() == 0)
      throw new IllegalArgumentException("Illegal provider");
    
    Provider p = Security.getProvider(provider);
    if (p == null)
      throw new NoSuchProviderException(provider);

    return getInstance(algorithm, p);
  }

  /**
   * Generates an <code>AlgorithmParameterGenerator</code> object for the
   * requested algorithm, as supplied from the specified provider, if such a
   * parameter generator is available from the provider. Note: the
   * <code>provider</code> doesn't have to be registered.
   *
   * @param algorithm the string name of the algorithm.
   * @param provider the provider.
   * @return the new <code>AlgorithmParameterGenerator</code> object.
   * @throws NoSuchAlgorithmException if the <code>algorithm</code> is not
   * available from the <code>provider</code>.
   * @throws IllegalArgumentException if the <code>provider</code> is
   * <code>null</code>.
   * @since 1.4
   */
  public static AlgorithmParameters getInstance(String algorithm,
                                                Provider provider)
    throws NoSuchAlgorithmException
  {
    if (provider == null)
      throw new IllegalArgumentException("Illegal provider");

    try
      {
	return new AlgorithmParameters((AlgorithmParametersSpi)
	  Engine.getInstance(ALGORITHM_PARAMETERS, algorithm, provider),
	  provider, algorithm);
      }
    catch (java.lang.reflect.InvocationTargetException ite)
      {
	throw new NoSuchAlgorithmException(algorithm);
      }
    catch (ClassCastException cce)
      {
	throw new NoSuchAlgorithmException(algorithm);
      }
  }

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

  /**
   * Initializes this parameter object using the parameters specified in
   * <code>paramSpec</code>.
   *
   * @param paramSpec the parameter specification.
   * @throws InvalidParameterSpecException if the given parameter specification
   * is inappropriate for the initialization of this parameter object, or if
   * this parameter object has already been initialized.
   */
  public final void init(AlgorithmParameterSpec paramSpec)
    throws InvalidParameterSpecException
  {
    paramSpi.engineInit(paramSpec);
  }

  /**
   * Imports the specified parameters and decodes them according to the primary
   * decoding format for parameters. The primary decoding format for parameters
   * is ASN.1, if an ASN.1 specification for this type of parameters exists.
   *
   * @param params the encoded parameters.
   * @throws IOException on decoding errors, or if this parameter object has
   * already been initialized.
   */
  public final void init(byte[]params) throws IOException
  {
    paramSpi.engineInit(params);
  }

  /**
   * Imports the parameters from params and decodes them according to the
   * specified decoding scheme. If <code>format</code> is <code>null</code>,
   * the primary decoding format for parameters is used. The primary decoding
   * format is ASN.1, if an ASN.1 specification for these parameters exists.
   *
   * @param params the encoded parameters.
   * @param format the name of the decoding scheme.
   * @throws IOException on decoding errors, or if this parameter object has
   * already been initialized.
   */
  public final void init(byte[]params, String format) throws IOException
  {
    paramSpi.engineInit(params, format);
  }

  /**
   * Returns a (transparent) specification of this parameter object.
   * <code>paramSpec</code> identifies the specification class in which the
   * parameters should be returned. It could, for example, be
   * <code>DSAParameterSpec.class</code>, to indicate that the parameters should
   * be returned in an instance of the {@link java.security.spec.DSAParameterSpec}
   * class.
   *
   * @param paramSpec the specification class in which the parameters should be
   * returned.
   * @return the parameter specification.
   * @throws InvalidParameterSpecException if the requested parameter
   * specification is inappropriate for this parameter object, or if this
   * parameter object has not been initialized.
   */
  public final AlgorithmParameterSpec getParameterSpec(Class paramSpec)
    throws InvalidParameterSpecException
  {
    return paramSpi.engineGetParameterSpec(paramSpec);
  }

  /**
   * Returns the parameters in their primary encoding format. The primary
   * encoding format for parameters is ASN.1, if an ASN.1 specification for
   * this type of parameters exists.
   *
   * @return the parameters encoded using their primary encoding format.
   * @throws IOException on encoding errors, or if this parameter object has not
   * been initialized.
   */
  public final byte[] getEncoded() throws IOException
  {
    return paramSpi.engineGetEncoded();
  }

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

  /**
   * Returns a formatted string describing the parameters.
   *
   * @return a formatted string describing the parameters, or <code>null</code>
   * if this parameter object has not been initialized.
   */
  public final String toString()
  {
    return paramSpi.engineToString();
  }
}
