1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.bouncycastle.asn1.x509;
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
396996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughesimport java.util.ArrayList;
496996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughesimport java.util.BitSet;
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.bouncycastle.asn1.DERObjectIdentifier;
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-note
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// This class was extracted from X509Name as a way to keep the element
996996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes// list in a more controlled fashion.
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-note
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * List of elements of an X509 name. Each element has a key, a value, and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an "added" flag.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class X509NameElementList {
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; key #0 */
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DERObjectIdentifier key0;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; key #1 */
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DERObjectIdentifier key1;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; key #2 */
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DERObjectIdentifier key2;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; key #3 */
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private DERObjectIdentifier key3;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; value #0 */
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String value0;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; value #1 */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String value1;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; value #2 */
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String value2;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** null-ok; value #3 */
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String value3;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * null-ok; array of additional keys and values, alternating
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * key then value, etc.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
4596996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes    private ArrayList<Object> rest;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4796996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes    /** bit vector for all the "added" bits */
4896996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes    private BitSet added = new BitSet();
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** &gt;= 0; number of elements in the list */
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int size;
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Note: Default public constructor.
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an element. The "added" flag is set to false for the element.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key non-null; the key
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param value non-null; the value
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void add(DERObjectIdentifier key, String value) {
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        add(key, value, false);
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an element.
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key non-null; the key
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param value non-null; the value
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param added the added bit
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void add(DERObjectIdentifier key, String value, boolean added) {
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (key == null) {
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("key == null");
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (value == null) {
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("value == null");
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = size;
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (sz) {
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0: {
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                key0 = key;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                value0 = value;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: {
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                key1 = key;
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                value1 = value;
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: {
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                key2 = key;
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                value2 = value;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: {
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                key3 = key;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                value3 = value;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 4: {
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Do initial allocation of rest.
10696996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes                rest = new ArrayList<Object>();
10796996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes                // Fall through...
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default: {
11096996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes                rest.add(key);
11196996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes                rest.add(value);
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (added) {
11796996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes            this.added.set(sz);
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size = sz + 1;
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the "added" flag on the most recently added element.
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setLastAddedFlag() {
12796996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes        added.set(size - 1);
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the number of elements in this instance.
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int size() {
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return size;
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the nth key.
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param n index
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the nth key
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public DERObjectIdentifier getKey(int n) {
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((n < 0) || (n >= size)) {
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IndexOutOfBoundsException(Integer.toString(n));
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (n) {
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0: return key0;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: return key1;
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: return key2;
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: return key3;
15396996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes            default: return (DERObjectIdentifier) rest.get((n - 4) * 2);
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the nth value.
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param n index
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the nth value
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getValue(int n) {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((n < 0) || (n >= size)) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IndexOutOfBoundsException(Integer.toString(n));
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (n) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0: return value0;
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: return value1;
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: return value2;
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3: return value3;
17396996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes            default: return (String) rest.get(((n - 4) * 2) + 1);
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the nth added flag bit.
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param n index
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the nth added flag bit
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean getAdded(int n) {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((n < 0) || (n >= size)) {
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IndexOutOfBoundsException(Integer.toString(n));
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18896996494d70be1e9e95cb62f122b9b79555d53d8Elliott Hughes        return added.get(n);
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs and returns a new instance which consists of the
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * elements of this one in reverse order
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return non-null; the reversed instance
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public X509NameElementList reverse() {
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        X509NameElementList result = new X509NameElementList();
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = size - 1; i >= 0; i--) {
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result.add(getKey(i), getValue(i), getAdded(i));
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
207