KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > util > asn1 > ASN1Set


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.util.asn1;
19
20 import java.io.ByteArrayOutputStream JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.Vector JavaDoc;
24
25 abstract public class ASN1Set
26     extends DERObject
27 {
28     protected Vector JavaDoc set = new Vector JavaDoc();
29
30     /**
31      * return an ASN1Set 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 ASN1Set getInstance(
37         Object JavaDoc obj)
38     {
39         if (obj == null || obj instanceof ASN1Set)
40         {
41             return (ASN1Set)obj;
42         }
43
44         throw new IllegalArgumentException JavaDoc("unknown object in getInstance");
45     }
46
47     /**
48      * Return an ASN1 set 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      * set - 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 sets 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 ASN1Set getInstance(
64         ASN1TaggedObject obj,
65         boolean explicit)
66     {
67         if (explicit)
68         {
69             if (!obj.isExplicit())
70             {
71                 throw new IllegalArgumentException JavaDoc("object implicit - explicit expected.");
72             }
73
74             return (ASN1Set)obj.getObject();
75         }
76         else
77         {
78             //
79
// constructed object which appears to be explicitly tagged
80
// and it's really implicit means we have to add the
81
// surrounding sequence.
82
//
83
if (obj.isExplicit())
84             {
85                 ASN1Set set = new DERSet(obj.getObject());
86
87                 return set;
88             }
89             else
90             {
91                 if (obj.getObject() instanceof ASN1Set)
92                 {
93                     return (ASN1Set)obj.getObject();
94                 }
95
96                 //
97
// in this case the parser returns a sequence, convert it
98
// into a set.
99
//
100
ASN1EncodableVector v = new ASN1EncodableVector();
101
102                 if (obj.getObject() instanceof ASN1Sequence)
103                 {
104                     ASN1Sequence s = (ASN1Sequence)obj.getObject();
105                     Enumeration JavaDoc e = s.getObjects();
106
107                     while (e.hasMoreElements())
108                     {
109                         v.add((DEREncodable)e.nextElement());
110                     }
111
112                     return new DERSet(v, false);
113                 }
114             }
115         }
116
117         throw new IllegalArgumentException JavaDoc(
118                     "unknown object in getInstanceFromTagged");
119     }
120
121     public ASN1Set()
122     {
123     }
124
125     public Enumeration JavaDoc getObjects()
126     {
127         return set.elements();
128     }
129
130     /**
131      * return the object at the set postion indicated by index.
132      *
133      * @param index the set number (starting at zero) of the object
134      * @return the object at the set postion indicated by index.
135      */

136     public DEREncodable getObjectAt(
137         int index)
138     {
139         return (DEREncodable)set.elementAt(index);
140     }
141
142     /**
143      * return the number of objects in this set.
144      *
145      * @return the number of objects in this set.
146      */

147     public int size()
148     {
149         return set.size();
150     }
151
152     public int hashCode()
153     {
154         Enumeration JavaDoc e = this.getObjects();
155         int hashCode = 0;
156
157         while (e.hasMoreElements())
158         {
159             hashCode ^= e.nextElement().hashCode();
160         }
161
162         return hashCode;
163     }
164
165     public boolean equals(
166         Object JavaDoc o)
167     {
168         if (o == null || !(o instanceof ASN1Set))
169         {
170             return false;
171         }
172
173         ASN1Set other = (ASN1Set)o;
174
175         if (this.size() != other.size())
176         {
177             return false;
178         }
179
180         Enumeration JavaDoc s1 = this.getObjects();
181         Enumeration JavaDoc s2 = other.getObjects();
182
183         while (s1.hasMoreElements())
184         {
185             if (!s1.nextElement().equals(s2.nextElement()))
186             {
187                 return false;
188             }
189         }
190
191         return true;
192     }
193
194     /**
195      * return true if a <= b (arrays are assumed padded with zeros).
196      */

197     private boolean lessThanOrEqual(
198          byte[] a,
199          byte[] b)
200     {
201          if (a.length <= b.length)
202          {
203              for (int i = 0; i != a.length; i++)
204              {
205                  int l = a[i] & 0xff;
206                  int r = b[i] & 0xff;
207
208                  if (r > l)
209                  {
210                      return true;
211                  }
212                  else if (l > r)
213                  {
214                      return false;
215                  }
216              }
217
218              return true;
219          }
220          else
221          {
222              for (int i = 0; i != b.length; i++)
223              {
224                  int l = a[i] & 0xff;
225                  int r = b[i] & 0xff;
226
227                  if (r > l)
228                  {
229                      return true;
230                  }
231                  else if (l > r)
232                  {
233                      return false;
234                  }
235              }
236
237              return false;
238          }
239     }
240
241     private byte[] getEncoded(
242         DEREncodable obj)
243     {
244         ByteArrayOutputStream JavaDoc bOut = new ByteArrayOutputStream JavaDoc();
245         ASN1OutputStream aOut = new ASN1OutputStream(bOut);
246
247         try
248         {
249             aOut.writeObject(obj);
250         }
251         catch (IOException JavaDoc e)
252         {
253             throw new IllegalArgumentException JavaDoc("cannot encode object added to SET");
254         }
255
256         return bOut.toByteArray();
257     }
258
259     protected void sort()
260     {
261         if (set.size() > 1)
262         {
263             boolean swapped = true;
264
265             while (swapped)
266             {
267                 int index = 0;
268                 byte[] a = getEncoded((DEREncodable)set.elementAt(0));
269
270                 swapped = false;
271
272                 while (index != set.size() - 1)
273                 {
274                     byte[] b = getEncoded((DEREncodable)set.elementAt(index + 1));
275
276                     if (lessThanOrEqual(a, b))
277                     {
278                         a = b;
279                     }
280                     else
281                     {
282                         Object JavaDoc o = set.elementAt(index);
283
284                         set.setElementAt(set.elementAt(index + 1), index);
285                         set.setElementAt(o, index + 1);
286
287                         swapped = true;
288                     }
289
290                     index++;
291                 }
292             }
293         }
294     }
295
296     protected void addObject(
297         DEREncodable obj)
298     {
299         set.addElement(obj);
300     }
301
302     abstract void encode(DEROutputStream out)
303             throws IOException JavaDoc;
304 }
305
Popular Tags