// AttribInfo.java
// $Id: AttribInfo.java,v 1.1 1997/04/15 20:39:04 yhchu Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

// The source code is jointly developed by W3C and some of its members
// participating in the Digital Signature Initiative.  The authors are:
//    Mark Champine, HP, <champine@apollo.hp.com>
//    Yang-hua Chu, MIT/W3C, <yhchu@w3.org>
//    Vasanthan Dasan, Sun, <vasanthan.dasan@central.sun.com>
//    Peter Lipp, University of Technology, Graz <plipp@iaik.tu-graz.ac.at>
//    Andreas Sterbenz, U. of Technology, Graz <sterbenz@iaik.tu-graz.ac.at>

package w3c.www.dsig;

import java.util.*;

/**
 * DSig SigBlock's Attribution info class.
 * <P>
 * In the DSig SigBlock the attribution info is a list of certificates intended
 * to help the receiver of the SigBlock to verify the signatures (by increasing
 * his trust into the signer). This class implements the attribinfo
 * as a vector of SigCert objects. Methods are provided to add, remove
 * certs, get a specific SigCert, etc.
 * <P>
 * @version 1.0beta (last modified 18-December-1997)
 * @author Andreas Sterbenz
 */
public class AttribInfo {
  /**
   * The magic string identifying an attribution info, <TT>AttribInfo</TT>.
   */
  public static final String _ATTRIBINFO_ID = "AttribInfo";
  /**
   * The Vector holding the SigCert certificates of this attribinfo.
   */
  private Vector certs;

  /**
   * Creates an empty AttribInfo.
   */
  public AttribInfo()
  {
    this(null);
  }

  /**
   * Creates an AttribInfo from the specified list of certificates.
   */
  public AttribInfo(SigCert[] certs)
  {
    if( certs == null )
    {
      this.certs = new Vector();
    } else {
      this.certs = new Vector(certs.length);
      for( int i=0; i<certs.length; i++ ) {
        this.certs.addElement(certs[i]);
      }
    }
  }

  /**
   * Parse method for use by the parser.
   * @exception DSigException if the data cannot be parsed correctly.
   */
  void parse(Vector data)
    throws DSigException
  {
    String id = (String)data.elementAt(0);
    if (! id.equals(_ATTRIBINFO_ID))
      throw new DSigException (this, id, _ATTRIBINFO_ID, "bad AttribInfo identifier");
    for (int i=1; i<data.size(); i++) {
      SigCert cert = new SigCert();
      cert.parse((Vector) data.elementAt(i));
      addCert(cert);
    }
  }

  /**
   * Find out if the given cert is contained in this AttribInfo. Return true
   * if it is, false otherwise.
   */
  public boolean containsCert(SigCert cert)
  {
    return certs.contains(cert);
  }

  /**
   * Adds the specified certificate to this AttribInfo. Returns true if
   * added, false otherwise (i.e. already present)
   */
  public boolean addCert(SigCert cert)
  {
    if( containsCert(cert) ) {
      return false;
    } else {
      certs.addElement(cert);
      return true;
    }
  }

  /**
   * Add all the certificates in the given certificate array to this
   * AttribInfo.
   */
  public void addCerts(SigCert[] certArray)
  {
    for( int i=0; i<certArray.length; i++ ) {
      addCert(certArray[i]);
    }
  }

  /**
   * Removes the first occurence of the specified certificate object from the
   * list of certificates.
   * @return true if found, false otherwise.
   */
  public boolean removeCert(SigCert cert)
  {
    return certs.removeElement(cert);
  }

  /**
   * Return the certificate at position index in this AttribInfo.
   * @exception ArrayIndexOutOfBoundsException if the index is not valid.
   */
  public SigCert getCertAt(int index) throws ArrayIndexOutOfBoundsException
  {
    return (SigCert)certs.elementAt(index);
  }

  /**
   * Return an enumeration of all the SigCert certificates
   * in this attribinfo.
   */
  public Enumeration certificates()
  {
    return certs.elements();
  }

  /**
   * Returns the number of certificates in this AttribInfo.
   */
  public int size()
  {
    return certs.size();
  }

  /**
   * Internal use only.
   */
  Vector toVector()
  {
    Vector v = new Vector();
    v.addElement(_ATTRIBINFO_ID);
    for( int i=0; i<certs.size(); i++ )
      v.addElement(((SigCert)certs.elementAt(i)).toVector());
    return v;
  }

  /**
   * Returns an S-Expression string representation of this AttribInfo
   * object.
   */
  public String toString()
  {
    return DSigUtil.toString(toVector());
  }
//   public String toString()
//   {
//     return PICSStream.toString(toVector());
//   }
}
