View Javadoc

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              // constructed object which appears to be explicitly tagged
80              // when it should be implicit means we have to add the
81              // surrounding sequence.
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 }