001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.util.asn1; 019 020 import java.io.IOException; 021 import java.util.Enumeration; 022 import java.util.Vector; 023 024 public abstract class ASN1Sequence 025 extends DERObject 026 { 027 private Vector seq = new Vector(); 028 029 /** 030 * return an ASN1Sequence from the given object. 031 * 032 * @param obj the object we want converted. 033 * @exception IllegalArgumentException if the object cannot be converted. 034 */ 035 public static ASN1Sequence getInstance( 036 Object obj) 037 { 038 if (obj == null || obj instanceof ASN1Sequence) 039 { 040 return (ASN1Sequence)obj; 041 } 042 043 throw new IllegalArgumentException("unknown object in getInstance"); 044 } 045 046 /** 047 * Return an ASN1 sequence from a tagged object. There is a special 048 * case here, if an object appears to have been explicitly tagged on 049 * reading but we were expecting it to be implictly tagged in the 050 * normal course of events it indicates that we lost the surrounding 051 * sequence - so we need to add it back (this will happen if the tagged 052 * object is a sequence that contains other sequences). If you are 053 * dealing with implicitly tagged sequences you really <b>should</b> 054 * be using this method. 055 * 056 * @param obj the tagged object. 057 * @param explicit true if the object is meant to be explicitly tagged, 058 * false otherwise. 059 * @exception IllegalArgumentException if the tagged object cannot 060 * be converted. 061 */ 062 public static ASN1Sequence getInstance( 063 ASN1TaggedObject obj, 064 boolean explicit) 065 { 066 if (explicit) 067 { 068 if (!obj.isExplicit()) 069 { 070 throw new IllegalArgumentException("object implicit - explicit expected."); 071 } 072 073 return (ASN1Sequence)obj.getObject(); 074 } 075 else 076 { 077 // 078 // constructed object which appears to be explicitly tagged 079 // when it should be implicit means we have to add the 080 // surrounding sequence. 081 // 082 if (obj.isExplicit()) 083 { 084 if (obj instanceof BERTaggedObject) 085 { 086 return new BERSequence(obj.getObject()); 087 } 088 else 089 { 090 return new DERSequence(obj.getObject()); 091 } 092 } 093 else 094 { 095 if (obj.getObject() instanceof ASN1Sequence) 096 { 097 return (ASN1Sequence)obj.getObject(); 098 } 099 } 100 } 101 102 throw new IllegalArgumentException( 103 "unknown object in getInstanceFromTagged"); 104 } 105 106 public Enumeration getObjects() 107 { 108 return seq.elements(); 109 } 110 111 /** 112 * return the object at the sequence postion indicated by index. 113 * 114 * @param index the sequence number (starting at zero) of the object 115 * @return the object at the sequence postion indicated by index. 116 */ 117 public DEREncodable getObjectAt( 118 int index) 119 { 120 return (DEREncodable)seq.elementAt(index); 121 } 122 123 /** 124 * return the number of objects in this sequence. 125 * 126 * @return the number of objects in this sequence. 127 */ 128 public int size() 129 { 130 return seq.size(); 131 } 132 133 public int hashCode() 134 { 135 Enumeration e = this.getObjects(); 136 int hashCode = 0; 137 138 while (e.hasMoreElements()) 139 { 140 Object o = e.nextElement(); 141 142 if (o != null) 143 { 144 hashCode ^= o.hashCode(); 145 } 146 } 147 148 return hashCode; 149 } 150 151 public boolean equals( 152 Object o) 153 { 154 if (o == null || !(o instanceof ASN1Sequence)) 155 { 156 return false; 157 } 158 159 ASN1Sequence other = (ASN1Sequence)o; 160 161 if (this.size() != other.size()) 162 { 163 return false; 164 } 165 166 Enumeration s1 = this.getObjects(); 167 Enumeration s2 = other.getObjects(); 168 169 while (s1.hasMoreElements()) 170 { 171 Object o1 = s1.nextElement(); 172 Object o2 = s2.nextElement(); 173 174 if (o1 != null && o2 != null) 175 { 176 if (!o1.equals(o2)) 177 { 178 return false; 179 } 180 } 181 else if (o1 == null && o2 == null) 182 { 183 continue; 184 } 185 else 186 { 187 return false; 188 } 189 } 190 191 return true; 192 } 193 194 protected void addObject( 195 DEREncodable obj) 196 { 197 seq.addElement(obj); 198 } 199 200 abstract void encode(DEROutputStream out) 201 throws IOException; 202 }