1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package org.apache.geronimo.util.asn1;
20
21 import java.io.IOException;
22 import java.util.Enumeration;
23 import java.util.Vector;
24
25 public abstract class ASN1Sequence
26 extends DERObject
27 {
28 private Vector seq = new Vector();
29
30 /**
31 * return an ASN1Sequence from the given object.
32 *
33 * @param obj the object we want converted.
34 * @exception IllegalArgumentException if the object cannot be converted.
35 */
36 public static ASN1Sequence getInstance(
37 Object obj)
38 {
39 if (obj == null || obj instanceof ASN1Sequence)
40 {
41 return (ASN1Sequence)obj;
42 }
43
44 throw new IllegalArgumentException("unknown object in getInstance");
45 }
46
47 /**
48 * Return an ASN1 sequence from a tagged object. There is a special
49 * case here, if an object appears to have been explicitly tagged on
50 * reading but we were expecting it to be implictly tagged in the
51 * normal course of events it indicates that we lost the surrounding
52 * sequence - so we need to add it back (this will happen if the tagged
53 * object is a sequence that contains other sequences). If you are
54 * dealing with implicitly tagged sequences you really <b>should</b>
55 * be using this method.
56 *
57 * @param obj the tagged object.
58 * @param explicit true if the object is meant to be explicitly tagged,
59 * false otherwise.
60 * @exception IllegalArgumentException if the tagged object cannot
61 * be converted.
62 */
63 public static ASN1Sequence getInstance(
64 ASN1TaggedObject obj,
65 boolean explicit)
66 {
67 if (explicit)
68 {
69 if (!obj.isExplicit())
70 {
71 throw new IllegalArgumentException("object implicit - explicit expected.");
72 }
73
74 return (ASN1Sequence)obj.getObject();
75 }
76 else
77 {
78
79
80
81
82
83 if (obj.isExplicit())
84 {
85 if (obj instanceof BERTaggedObject)
86 {
87 return new BERSequence(obj.getObject());
88 }
89 else
90 {
91 return new DERSequence(obj.getObject());
92 }
93 }
94 else
95 {
96 if (obj.getObject() instanceof ASN1Sequence)
97 {
98 return (ASN1Sequence)obj.getObject();
99 }
100 }
101 }
102
103 throw new IllegalArgumentException(
104 "unknown object in getInstanceFromTagged");
105 }
106
107 public Enumeration getObjects()
108 {
109 return seq.elements();
110 }
111
112 /**
113 * return the object at the sequence postion indicated by index.
114 *
115 * @param index the sequence number (starting at zero) of the object
116 * @return the object at the sequence postion indicated by index.
117 */
118 public DEREncodable getObjectAt(
119 int index)
120 {
121 return (DEREncodable)seq.elementAt(index);
122 }
123
124 /**
125 * return the number of objects in this sequence.
126 *
127 * @return the number of objects in this sequence.
128 */
129 public int size()
130 {
131 return seq.size();
132 }
133
134 public int hashCode()
135 {
136 Enumeration e = this.getObjects();
137 int hashCode = 0;
138
139 while (e.hasMoreElements())
140 {
141 Object o = e.nextElement();
142
143 if (o != null)
144 {
145 hashCode ^= o.hashCode();
146 }
147 }
148
149 return hashCode;
150 }
151
152 public boolean equals(
153 Object o)
154 {
155 if (o == null || !(o instanceof ASN1Sequence))
156 {
157 return false;
158 }
159
160 ASN1Sequence other = (ASN1Sequence)o;
161
162 if (this.size() != other.size())
163 {
164 return false;
165 }
166
167 Enumeration s1 = this.getObjects();
168 Enumeration s2 = other.getObjects();
169
170 while (s1.hasMoreElements())
171 {
172 Object o1 = s1.nextElement();
173 Object o2 = s2.nextElement();
174
175 if (o1 != null && o2 != null)
176 {
177 if (!o1.equals(o2))
178 {
179 return false;
180 }
181 }
182 else if (o1 == null && o2 == null)
183 {
184 continue;
185 }
186 else
187 {
188 return false;
189 }
190 }
191
192 return true;
193 }
194
195 protected void addObject(
196 DEREncodable obj)
197 {
198 seq.addElement(obj);
199 }
200
201 abstract void encode(DEROutputStream out)
202 throws IOException;
203 }