/* CertificateFactory.java -- Certificate Factory Class
   Copyright (C) 1999, 2002, 2003 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.cert;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;

import java.io.InputStream;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import gnu.java.security.Engine;

/**
 * This class implements the CertificateFactory class interface used to
 * generate certificates, certificate revocation lists (CRLs), and certificate
 * paths objects from their encoded forms.
 *
 * @author Mark Benvenuto
 * @author Casey Marshall
 * @since JDK 1.2
 * @status Fully compatible with JDK 1.4.
 */
public class CertificateFactory
{

  /** The service name for certificate factories. */
  private static final String CERTIFICATE_FACTORY = "CertificateFactory";

  private CertificateFactorySpi certFacSpi;
  private Provider provider;
  private String type;

  /**
   * Creates an instance of CertificateFactory.
   *
   * @param certFacSpi The underlying CertificateFactory engine.
   * @param provider   The provider of this implementation.
   * @param type       The type of Certificate this factory creates.
   */
  protected CertificateFactory(CertificateFactorySpi certFacSpi,
                               Provider provider, String type)
  {
    this.certFacSpi = certFacSpi;
    this.provider = provider;
    this.type = type;
  }

// Class methods.
  // ------------------------------------------------------------------------

  /** 
   * Gets an instance of the CertificateFactory class representing
   * the specified certificate factory. If the type is not 
   * found then, it throws CertificateException.
   *
   * @param type     The type of certificate factory to create.
   * @return a CertificateFactory repesenting the desired type
   * @throws CertificateException If the type of certificate is not
   *    implemented by any installed provider.
   */
  public static final CertificateFactory getInstance(String type)
    throws CertificateException
  {
    Provider[] p = Security.getProviders();

    for (int i = 0; i < p.length; i++)
      {
        try
          {
            return getInstance(type, p[i]);
          }
        catch (CertificateException ignored)
          {
          }
      }

    throw new CertificateException(type);
  }

  /** 
   * Gets an instance of the CertificateFactory class representing
   * the specified certificate factory from the specified provider. 
   * If the type is not found then, it throws {@link CertificateException}. 
   * If the provider is not found, then it throws 
   * {@link java.security.NoSuchProviderException}.
   *
   * @param type     The type of certificate factory to create.
   * @param provider The name of the provider from which to get the
   *        implementation.
   * @return A CertificateFactory for the desired type.
   * @throws CertificateException If the type of certificate is not
   *         implemented by the named provider.
   * @throws NoSuchProviderException If the named provider is not installed.
   */
  public static final CertificateFactory getInstance(String type,
                                                     String provider) 
    throws CertificateException, NoSuchProviderException
  {
    Provider p = Security.getProvider(provider);
    if( p == null)
      throw new NoSuchProviderException();

    return getInstance(type, p);
  }

  /**
   * Get a certificate factory for the given certificate type from the
   * given provider.
   *
   * @param type     The type of certificate factory to create.
   * @param provider The provider from which to get the implementation.
   * @return A CertificateFactory for the desired type.
   * @throws CertificateException If the type of certificate is not
   *         implemented by the provider.
   * @throws IllegalArgumentException If the provider is null.
   */
  public static final CertificateFactory getInstance(String type,
                                                     Provider provider)
    throws CertificateException
  {
    if (provider == null)
      throw new IllegalArgumentException("null provider");

    try
      {
        return new CertificateFactory((CertificateFactorySpi)
          Engine.getInstance(CERTIFICATE_FACTORY, type, provider),
          provider, type);
      }
    catch (ClassCastException cce)
      {
        throw new CertificateException(type);
      }
    catch (java.lang.reflect.InvocationTargetException ite)
      {
        throw new CertificateException(type);
      }
    catch (NoSuchAlgorithmException nsae)
      {
        throw new CertificateException(nsae.getMessage());
      }
  }

// Instance methods.
  // ------------------------------------------------------------------------

  /**
   * Gets the provider of this implementation.
   *
   * @return The provider of this implementation.
   */
  public final Provider getProvider()
  {
    return provider;
  }

  /**
   * Returns the type of the certificate this factory creates.
   *
   * @return A string with the type of certificate
   */
  public final String getType()
  {
    return type;
  }

  /**
   * Generates a Certificate from the encoded data read
   * from an InputStream.
   *
   * <p>The input stream must contain only one certificate.
   *
   * <p>If there exists a specialized certificate class for the
   * certificate format handled by the certificate factory
   * then the return Ceritificate should be a typecast of it.
   * Ex: A X.509 CertificateFactory should return X509Certificate.
   *
   * <p>For X.509 certificates, the certificate in inStream must be
   * DER encoded and supplied in binary or printable (Base64) 
   * encoding. If the certificate is in Base64 encoding, it must be 
   * bounded by -----BEGINCERTIFICATE-----, and 
   * -----END CERTIFICATE-----. 
   *
   * @param inStream An input stream containing the certificate data.
   * @return A certificate initialized from the decoded InputStream data.
   * @throws CertificateException If an error occurs decoding the
   *   certificate.
   */
  public final Certificate generateCertificate(InputStream inStream)
    throws CertificateException
  {
    return certFacSpi.engineGenerateCertificate(inStream);
  }

  /**
   * Returns a collection of certificates that were read from the 
   * input stream. It may be empty, have only one, or have 
   * multiple certificates.
   *
   * For a X.509 certificate factory, the stream may contain a
   * single DER encoded certificate or a PKCS#7 certificate 
   * chain. This is a PKCS#7 <I>SignedData</I> object with the 
   * most significant field being <I>certificates</I>. If no 
   * CRLs are present, then an empty collection is returned.
	 *
   * @param inStream An input stream containing the certificate data.
   * @return A collection of certificates initialized from the decoded
   *   InputStream data.
   * @throws CertificateException If an error occurs decoding the
   *   certificates.
   */
  public final Collection generateCertificates(InputStream inStream)
    throws CertificateException
  {
    return certFacSpi.engineGenerateCertificates(inStream);
  }

  /**
   * Generates a CRL based on the encoded data read
   * from the InputStream.
   *
   * <p>The input stream must contain only one CRL.
   *
   * <p>If there exists a specialized CRL class for the
   * CRL format handled by the certificate factory
   * then the return CRL should be a typecast of it.
   * Ex: A X.509 CertificateFactory should return X509CRL.
   *
   * @param inStream An input stream containing the CRL data.
   * @return A CRL initialized from the decoded InputStream data.
   * @throws CRLException If an error occurs decoding the CRL.
   */
  public final CRL generateCRL(InputStream inStream)
    throws CRLException
  {
    return certFacSpi.engineGenerateCRL(inStream);
  }

  /**
   * <p>Generates CRLs based on the encoded data read
   * from the InputStream.
   *
   * <p>For a X.509 certificate factory, the stream may contain a
   * single DER encoded CRL or a PKCS#7 CRL set. This is a 
   * PKCS#7 <I>SignedData</I> object with the most significant 
   * field being <I>crls</I>. If no CRLs are present, then an
   * empty collection is returned.
   *
   * @param inStream an input stream containing the CRLs.
   * @return a collection of CRLs initialized from the decoded
   *    InputStream data.
   * @throws CRLException If an error occurs decoding the CRLs.
   */
  public final Collection generateCRLs(InputStream inStream)
    throws CRLException
  {
    return certFacSpi.engineGenerateCRLs( inStream );
  }

  /**
   * Generate a {@link CertPath} and initialize it with data parsed from
   * the input stream. The default encoding of this factory is used.
   *
   * @param inStream The InputStream containing the CertPath data.
   * @return A CertPath initialized from the input stream data.
   * @throws CertificateException If an error occurs decoding the
   * CertPath.
   */
  public final CertPath generateCertPath(InputStream inStream)
    throws CertificateException
  {
    return certFacSpi.engineGenerateCertPath(inStream);
  }

  /**
   * Generate a {@link CertPath} and initialize it with data parsed from
   * the input stream, using the specified encoding.
   *
   * @param inStream The InputStream containing the CertPath data.
   * @param encoding The encoding of the InputStream data.
   * @return A CertPath initialized from the input stream data.
   * @throws CertificateException If an error occurs decoding the
   *   CertPath.
   */
  public final CertPath generateCertPath(InputStream inStream, String encoding)
    throws CertificateException
  {
    return certFacSpi.engineGenerateCertPath(inStream, encoding);
  }

  /**
   * Generate a {@link CertPath} and initialize it with the certificates
   * in the {@link java.util.List} argument.
   *
   * @param certificates The list of certificates with which to create
   *   the CertPath.
   * @return A CertPath initialized from the certificates.
   * @throws CertificateException If an error occurs generating the
   *   CertPath.
   */
  public final CertPath generateCertPath(List certificates)
    throws CertificateException
  {
    return certFacSpi.engineGenerateCertPath(certificates);
  }

  /**
   * Returns an Iterator of CertPath encodings supported by this
   * factory, with the default encoding first. The returned Iterator
   * cannot be modified.
   *
   * @return The Iterator of supported encodings.
   */
  public final Iterator getCertPathEncodings()
  {
    return certFacSpi.engineGetCertPathEncodings();
  }
} // class CertificateFactory
