001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.geronimo.util.asn1; 020 021 import java.io.IOException; 022 import java.util.Enumeration; 023 import java.util.Vector; 024 025 public abstract class ASN1Sequence 026 extends DERObject 027 { 028 private Vector seq = new Vector(); 029 030 /** 031 * return an ASN1Sequence from the given object. 032 * 033 * @param obj the object we want converted. 034 * @exception IllegalArgumentException if the object cannot be converted. 035 */ 036 public static ASN1Sequence getInstance( 037 Object obj) 038 { 039 if (obj == null || obj instanceof ASN1Sequence) 040 { 041 return (ASN1Sequence)obj; 042 } 043 044 throw new IllegalArgumentException("unknown object in getInstance"); 045 } 046 047 /** 048 * Return an ASN1 sequence from a tagged object. There is a special 049 * case here, if an object appears to have been explicitly tagged on 050 * reading but we were expecting it to be implictly tagged in the 051 * normal course of events it indicates that we lost the surrounding 052 * sequence - so we need to add it back (this will happen if the tagged 053 * object is a sequence that contains other sequences). If you are 054 * dealing with implicitly tagged sequences you really <b>should</b> 055 * be using this method. 056 * 057 * @param obj the tagged object. 058 * @param explicit true if the object is meant to be explicitly tagged, 059 * false otherwise. 060 * @exception IllegalArgumentException if the tagged object cannot 061 * be converted. 062 */ 063 public static ASN1Sequence getInstance( 064 ASN1TaggedObject obj, 065 boolean explicit) 066 { 067 if (explicit) 068 { 069 if (!obj.isExplicit()) 070 { 071 throw new IllegalArgumentException("object implicit - explicit expected."); 072 } 073 074 return (ASN1Sequence)obj.getObject(); 075 } 076 else 077 { 078 // 079 // constructed object which appears to be explicitly tagged 080 // when it should be implicit means we have to add the 081 // surrounding sequence. 082 // 083 if (obj.isExplicit()) 084 { 085 if (obj instanceof BERTaggedObject) 086 { 087 return new BERSequence(obj.getObject()); 088 } 089 else 090 { 091 return new DERSequence(obj.getObject()); 092 } 093 } 094 else 095 { 096 if (obj.getObject() instanceof ASN1Sequence) 097 { 098 return (ASN1Sequence)obj.getObject(); 099 } 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 }