/* PKIXCertPathValidatorResult.java -- PKIX cert path builder result
   Copyright (C) 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.PublicKey;

/**
 * Results returned by the {@link
 * CertPathValidator#validate(java.security.cert.CertPath,java.security.cert.CertPathParameters)}
 * method for PKIX {@link CertPathValidator}s.
 *
 * @see CertPathValidator
 */
public class PKIXCertPathValidatorResult implements CertPathValidatorResult
{

  // Fields.
  // ------------------------------------------------------------------------

  /** The trust anchor. */
  private final TrustAnchor trustAnchor;

  /** The root node of the policy tree. */
  private final PolicyNode policyTree;

  /** The subject's public key. */
  private final PublicKey subjectPublicKey;

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

  /**
   * Creates a new PKIXCertPathValidatorResult.
   *
   * @param trustAnchor      The trust anchor.
   * @param policyTree       The root node of the policy tree.
   * @param subjectPublicKey The public key.
   * @throws NullPointerException If either <i>trustAnchor</i> or
   *         <i>subjectPublicKey</i> is null.
   */
  public PKIXCertPathValidatorResult(TrustAnchor trustAnchor,
                                     PolicyNode policyTree,
                                     PublicKey subjectPublicKey)
  {
    if (trustAnchor == null || subjectPublicKey == null)
      throw new NullPointerException();
    this.trustAnchor = trustAnchor;
    this.policyTree = policyTree;
    this.subjectPublicKey = subjectPublicKey;
  }

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

  /**
   * Returns the trust anchor.
   *
   * @return The trust anchor.
   */
  public TrustAnchor getTrustAnchor()
  {
    return trustAnchor;
  }

  /**
   * Returns the root node of the policy tree.
   *
   * @return The root node of the policy tree.
   */
  public PolicyNode getPolicyTree()
  {
    return policyTree;
  }

  /**
   * Returns the subject public key.
   *
   * @return The subject public key.
   */
  public PublicKey getPublicKey()
  {
    return subjectPublicKey;
  }

  /**
   * Returns a copy of this object.
   *
   * @return The copy.
   */
  public Object clone()
  {
    return new PKIXCertPathValidatorResult(trustAnchor, policyTree,
                                           subjectPublicKey);
  }

  /**
   * Returns a printable string representation of this result.
   *
   * @return A printable string representation of this result.
   */
  public String toString()
  {
    return "[ Trust Anchor=" + trustAnchor + "; Policy Tree="
      + policyTree + "; Subject Public Key=" + subjectPublicKey + " ]";
  }
}
