/* CertStore -- stores and retrieves certificates.
   Copyright (C) 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.cert;

import gnu.java.lang.CPStringBuilder;

import gnu.java.security.Engine;

import java.lang.reflect.InvocationTargetException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
import java.util.Collection;

/**
 * A CertStore is a read-only repository for certificates and
 * certificate revocation lists.
 *
 * @since 1.4
 */
public class CertStore
{

  // Constants and fields.
  // ------------------------------------------------------------------------

  /** Service name for CertStore. */
  private static final String CERT_STORE = "CertStore";

  /** The underlying implementation. */
  private CertStoreSpi storeSpi;

  /** This implementation's provider. */
  private Provider provider;

  /** The name of this key store type. */
  private String type;

  /** The parameters used to initialize this instance, if any. */
  private CertStoreParameters params;

  // Constructor.
  // ------------------------------------------------------------------------

  /**
   * Create a new CertStore.
   *
   * @param storeSpi The underlying implementation.
   * @param provider The provider of this implementation.
   * @param type     The type of CertStore this class represents.
   * @param params   The parameters used to initialize this instance, if any.
   */
  protected CertStore(CertStoreSpi storeSpi, Provider provider, String type,
                      CertStoreParameters params)
  {
    this.storeSpi = storeSpi;
    this.provider = provider;
    this.type = type;
    this.params = params;
  }

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

  /**
   * Returns the default certificate store type.
   *
   * <p>This value can be set at run-time via the security property
   * "certstore.type"; if not specified than the default type will be
   * "LDAP".
   *
   * @return The default CertStore type.
   */
  public static final synchronized String getDefaultType()
  {
    String type = null;
    type = (String) java.security.AccessController.doPrivileged(
      new PrivilegedAction() {
        public Object run() {
          return Security.getProperty("certstore.type");
        }
      }
    );
    if (type == null)
      type = "LDAP";
    return type;
  }

  /**
   * Returns an instance of the given certificate store type from the first
   * installed provider.
   * 
   * @param type The type of <code>CertStore</code> to create.
   * @param params The parameters to initialize this cert store with.
   * @return The new instance.
   * @throws InvalidAlgorithmParameterException If the instance rejects the
   *           specified parameters.
   * @throws NoSuchAlgorithmException If no installed provider implements the
   *           specified CertStore.
   * @throws IllegalArgumentException if <code>type</code> is
   *           <code>null</code> or is an empty string.
   */
  public static CertStore getInstance(String type, CertStoreParameters params)
    throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
  {
    Provider[] p = Security.getProviders();
    NoSuchAlgorithmException lastException = null;
    for (int i = 0; i < p.length; i++)
      try
        {
          return getInstance(type, params, p[i]);
        }
      catch (NoSuchAlgorithmException x)
        {
          lastException = x;
        }
    if (lastException != null)
      throw lastException;
    throw new NoSuchAlgorithmException(type);
  }

  /**
   * Returns an instance of the given certificate store type from a named
   * provider.
   * 
   * @param type The type of <code>CertStore</code> to create.
   * @param params The parameters to initialize this cert store with.
   * @param provider The name of the provider to use.
   * @return The new instance.
   * @throws InvalidAlgorithmParameterException If the instance rejects the
   *           specified parameters.
   * @throws NoSuchAlgorithmException If the specified provider does not
   *           implement the specified CertStore.
   * @throws NoSuchProviderException If no provider named <i>provider</i> is
   *           installed.
   * @throws IllegalArgumentException if either <code>type</code> or
   *           <code>provider</code> is <code>null</code>, or if
   *           <code>type</code> is an empty string.
   */
  public static CertStore getInstance(String type, CertStoreParameters params,
                                      String provider)
    throws InvalidAlgorithmParameterException, NoSuchAlgorithmException,
           NoSuchProviderException
  {
    if (provider == null)
      throw new IllegalArgumentException("provider MUST NOT be null");
    Provider p = Security.getProvider(provider);
    if (p == null)
      throw new NoSuchProviderException(provider);
    return getInstance(type, params, p);
  }

  /**
   * Returns an instance of the given certificate store type from a given
   * provider.
   *
   * @param type The type of <code>CertStore</code> to create.
   * @param params   The parameters to initialize this cert store with.
   * @param provider The provider to use.
   * @return The new instance.
   * @throws InvalidAlgorithmParameterException If the instance rejects
   *         the specified parameters.
   * @throws NoSuchAlgorithmException If the specified provider does not
   *         implement the specified CertStore.
   * @throws IllegalArgumentException if either <code>type</code> or
   *           <code>provider</code> is <code>null</code>, or if
   *           <code>type</code> is an empty string.
   */
  public static CertStore getInstance(String type, CertStoreParameters params,
                                      Provider provider)
      throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
  {
    CPStringBuilder sb = new CPStringBuilder("CertStore of type [")
        .append(type).append("] from provider[")
        .append(provider).append("] could not be created");
    Throwable cause;
    try
      {
        Object[] args = new Object[] { params };
        Object spi = Engine.getInstance(CERT_STORE, type, provider, args);
        return new CertStore((CertStoreSpi) spi, provider, type, params);
      }
    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 type of certificate store this instance represents.
   *
   * @return The CertStore type.
   */
  public final String getType()
  {
    return type;
  }

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

  /**
   * Get the parameters this instance was created with, if any. The
   * parameters will be cloned before they are returned.
   *
   * @return The parameters, or null.
   */
  public final CertStoreParameters getCertStoreParameters()
  {
    return params != null ? (CertStoreParameters) params.clone() : null;
  }

  /**
   * Get a collection of certificates from this CertStore, optionally
   * filtered by the specified CertSelector. The Collection returned may
   * be empty, but will never be null.
   *
   * <p>Implementations may not allow a null argument, even if no
   * filtering is desired.
   *
   * @param selector The certificate selector.
   * @return The collection of certificates.
   * @throws CertStoreException If the certificates cannot be retrieved.
   */
  public final Collection<? extends Certificate> getCertificates(CertSelector selector)
    throws CertStoreException
  {
    return storeSpi.engineGetCertificates(selector);
  }

  /**
   * Get a collection of certificate revocation lists from this CertStore,
   * optionally filtered by the specified CRLSelector. The Collection
   * returned may be empty, but will never be null.
   *
   * <p>Implementations may not allow a null argument, even if no
   * filtering is desired.
   *
   * @param selector The certificate selector.
   * @return The collection of certificate revocation lists.
   * @throws CertStoreException If the CRLs cannot be retrieved.
   */
  public final Collection<? extends CRL> getCRLs(CRLSelector selector)
    throws CertStoreException
  {
    return storeSpi.engineGetCRLs(selector);
  }
}
