001package org.apache.commons.ssl.org.bouncycastle.asn1.x509.sigi;
002
003import java.util.Enumeration;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Choice;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1String;
011import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
012import org.apache.commons.ssl.org.bouncycastle.asn1.x500.DirectoryString;
013
014/**
015 * Structure for a name or pseudonym.
016 * 
017 * <pre>
018 *       NameOrPseudonym ::= CHOICE {
019 *            surAndGivenName SEQUENCE {
020 *              surName DirectoryString,
021 *              givenName SEQUENCE OF DirectoryString 
022 *         },
023 *            pseudonym DirectoryString 
024 *       }
025 * </pre>
026 * 
027 * @see org.bouncycastle.asn1.x509.sigi.PersonalData
028 * 
029 */
030public class NameOrPseudonym
031    extends ASN1Object
032    implements ASN1Choice
033{
034    private DirectoryString pseudonym;
035
036    private DirectoryString surname;
037
038    private ASN1Sequence givenName;
039
040    public static NameOrPseudonym getInstance(Object obj)
041    {
042        if (obj == null || obj instanceof NameOrPseudonym)
043        {
044            return (NameOrPseudonym)obj;
045        }
046
047        if (obj instanceof ASN1String)
048        {
049            return new NameOrPseudonym(DirectoryString.getInstance(obj));
050        }
051
052        if (obj instanceof ASN1Sequence)
053        {
054            return new NameOrPseudonym((ASN1Sequence)obj);
055        }
056
057        throw new IllegalArgumentException("illegal object in getInstance: "
058            + obj.getClass().getName());
059    }
060
061    /**
062     * Constructor from DirectoryString.
063     * <p>
064     * The sequence is of type NameOrPseudonym:
065     * <pre>
066     *       NameOrPseudonym ::= CHOICE {
067     *            surAndGivenName SEQUENCE {
068     *              surName DirectoryString,
069     *              givenName SEQUENCE OF DirectoryString
070     *         },
071     *            pseudonym DirectoryString
072     *       }
073     * </pre>
074     * @param pseudonym pseudonym value to use.
075     */
076    public NameOrPseudonym(DirectoryString pseudonym)
077    {
078        this.pseudonym = pseudonym;
079    }
080
081    /**
082     * Constructor from ASN1Sequence.
083     * <p>
084     * The sequence is of type NameOrPseudonym:
085     * <pre>
086     *       NameOrPseudonym ::= CHOICE {
087     *            surAndGivenName SEQUENCE {
088     *              surName DirectoryString,
089     *              givenName SEQUENCE OF DirectoryString
090     *         },
091     *            pseudonym DirectoryString
092     *       }
093     * </pre>
094     * </p>
095     * @param seq The ASN.1 sequence.
096     */
097    private NameOrPseudonym(ASN1Sequence seq)
098    {
099        if (seq.size() != 2)
100        {
101            throw new IllegalArgumentException("Bad sequence size: "
102                + seq.size());
103        }
104
105        if (!(seq.getObjectAt(0) instanceof ASN1String))
106        {
107            throw new IllegalArgumentException("Bad object encountered: "
108                + seq.getObjectAt(0).getClass());
109        }
110
111        surname = DirectoryString.getInstance(seq.getObjectAt(0));
112        givenName = ASN1Sequence.getInstance(seq.getObjectAt(1));
113    }
114
115    /**
116     * Constructor from a given details.
117     *
118     * @param pseudonym The pseudonym.
119     */
120    public NameOrPseudonym(String pseudonym)
121    {
122        this(new DirectoryString(pseudonym));
123    }
124
125    /**
126     * Constructor from a given details.
127     *
128     * @param surname   The surname.
129     * @param givenName A sequence of directory strings making up the givenName
130     */
131    public NameOrPseudonym(DirectoryString surname, ASN1Sequence givenName)
132    {
133        this.surname = surname;
134        this.givenName = givenName;
135    }
136
137    public DirectoryString getPseudonym()
138    {
139        return pseudonym;
140    }
141
142    public DirectoryString getSurname()
143    {
144        return surname;
145    }
146
147    public DirectoryString[] getGivenName()
148    {
149        DirectoryString[] items = new DirectoryString[givenName.size()];
150        int count = 0;
151        for (Enumeration e = givenName.getObjects(); e.hasMoreElements();)
152        {
153            items[count++] = DirectoryString.getInstance(e.nextElement());
154        }
155        return items;
156    }
157
158    /**
159     * Produce an object suitable for an ASN1OutputStream.
160     * <p>
161     * Returns:
162     * <pre>
163     *       NameOrPseudonym ::= CHOICE {
164     *            surAndGivenName SEQUENCE {
165     *              surName DirectoryString,
166     *              givenName SEQUENCE OF DirectoryString
167     *         },
168     *            pseudonym DirectoryString
169     *       }
170     * </pre>
171     *
172     * @return a DERObject
173     */
174    public ASN1Primitive toASN1Primitive()
175    {
176        if (pseudonym != null)
177        {
178            return pseudonym.toASN1Primitive();
179        }
180        else
181        {
182            ASN1EncodableVector vec1 = new ASN1EncodableVector();
183            vec1.add(surname);
184            vec1.add(givenName);
185            return new DERSequence(vec1);
186        }
187    }
188}