001package org.apache.commons.ssl.org.bouncycastle.asn1.x509;
002
003import java.util.Enumeration;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
008import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
009
010/**
011 * Target information extension for attributes certificates according to RFC
012 * 3281.
013 * 
014 * <pre>
015 *           SEQUENCE OF Targets
016 * </pre>
017 * 
018 */
019public class TargetInformation
020    extends ASN1Object
021{
022    private ASN1Sequence targets;
023
024    /**
025     * Creates an instance of a TargetInformation from the given object.
026     * <p>
027     * <code>obj</code> can be a TargetInformation or a {@link ASN1Sequence}
028     * 
029     * @param obj The object.
030     * @return A TargetInformation instance.
031     * @throws IllegalArgumentException if the given object cannot be
032     *             interpreted as TargetInformation.
033     */
034    public static TargetInformation getInstance(Object obj)
035    {
036        if (obj instanceof TargetInformation)
037        {
038            return (TargetInformation)obj;
039        }
040        else if (obj != null)
041        {
042            return new TargetInformation(ASN1Sequence.getInstance(obj));
043        }
044
045        return null;
046    }
047
048    /**
049     * Constructor from a ASN1Sequence.
050     * 
051     * @param seq The ASN1Sequence.
052     * @throws IllegalArgumentException if the sequence does not contain
053     *             correctly encoded Targets elements.
054     */
055    private TargetInformation(ASN1Sequence seq)
056    {
057        targets = seq;
058    }
059
060    /**
061     * Returns the targets in this target information extension.
062     * 
063     * @return Returns the targets.
064     */
065    public Targets[] getTargetsObjects()
066    {
067        Targets[] copy = new Targets[targets.size()];
068        int count = 0;
069        for (Enumeration e = targets.getObjects(); e.hasMoreElements();)
070        {
071            copy[count++] = Targets.getInstance(e.nextElement());
072        }
073        return copy;
074    }
075
076    /**
077     * Constructs a target information from a single targets element. 
078     * According to RFC 3281 only one targets element must be produced.
079     * 
080     * @param targets A Targets instance.
081     */
082    public TargetInformation(Targets targets)
083    {
084        this.targets = new DERSequence(targets);
085    }
086
087    /**
088     * According to RFC 3281 only one targets element must be produced. If
089     * multiple targets are given they must be merged in
090     * into one targets element.
091     *
092     * @param targets An array with {@link Targets}.
093     */
094    public TargetInformation(Target[] targets)
095    {
096        this(new Targets(targets));
097    }
098
099    /**
100     * Produce an object suitable for an ASN1OutputStream.
101     * 
102     * Returns:
103     * 
104     * <pre>
105     *          SEQUENCE OF Targets
106     * </pre>
107     * 
108     * <p>
109     * According to RFC 3281 only one targets element must be produced. If
110     * multiple targets are given in the constructor they are merged into one
111     * targets element. If this was produced from a
112     * {@link org.bouncycastle.asn1.ASN1Sequence} the encoding is kept.
113     * 
114     * @return a ASN1Primitive
115     */
116    public ASN1Primitive toASN1Primitive()
117    {
118        return targets;
119    }
120}