1package org.bouncycastle.asn1.cms; 2 3import java.util.Enumeration; 4import java.util.Hashtable; 5import java.util.Vector; 6 7import org.bouncycastle.asn1.ASN1Encodable; 8import org.bouncycastle.asn1.ASN1EncodableVector; 9import org.bouncycastle.asn1.ASN1ObjectIdentifier; 10import org.bouncycastle.asn1.ASN1Set; 11import org.bouncycastle.asn1.DERSet; 12 13/** 14 * This is helper tool to construct {@link Attributes} sets. 15 */ 16public class AttributeTable 17{ 18 private Hashtable attributes = new Hashtable(); 19 20 public AttributeTable( 21 Hashtable attrs) 22 { 23 attributes = copyTable(attrs); 24 } 25 26 public AttributeTable( 27 ASN1EncodableVector v) 28 { 29 for (int i = 0; i != v.size(); i++) 30 { 31 Attribute a = Attribute.getInstance(v.get(i)); 32 33 addAttribute(a.getAttrType(), a); 34 } 35 } 36 37 public AttributeTable( 38 ASN1Set s) 39 { 40 for (int i = 0; i != s.size(); i++) 41 { 42 Attribute a = Attribute.getInstance(s.getObjectAt(i)); 43 44 addAttribute(a.getAttrType(), a); 45 } 46 } 47 48 public AttributeTable( 49 Attribute attr) 50 { 51 addAttribute(attr.getAttrType(), attr); 52 } 53 54 public AttributeTable( 55 Attributes attrs) 56 { 57 this(ASN1Set.getInstance(attrs.toASN1Primitive())); 58 } 59 60 private void addAttribute( 61 ASN1ObjectIdentifier oid, 62 Attribute a) 63 { 64 Object value = attributes.get(oid); 65 66 if (value == null) 67 { 68 attributes.put(oid, a); 69 } 70 else 71 { 72 Vector v; 73 74 if (value instanceof Attribute) 75 { 76 v = new Vector(); 77 78 v.addElement(value); 79 v.addElement(a); 80 } 81 else 82 { 83 v = (Vector)value; 84 85 v.addElement(a); 86 } 87 88 attributes.put(oid, v); 89 } 90 } 91 92 /** 93 * Return the first attribute matching the OBJECT IDENTIFIER oid. 94 * 95 * @param oid type of attribute required. 96 * @return first attribute found of type oid. 97 */ 98 public Attribute get( 99 ASN1ObjectIdentifier oid) 100 { 101 Object value = attributes.get(oid); 102 103 if (value instanceof Vector) 104 { 105 return (Attribute)((Vector)value).elementAt(0); 106 } 107 108 return (Attribute)value; 109 } 110 111 /** 112 * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be 113 * empty if there are no attributes of the required type present. 114 * 115 * @param oid type of attribute required. 116 * @return a vector of all the attributes found of type oid. 117 */ 118 public ASN1EncodableVector getAll( 119 ASN1ObjectIdentifier oid) 120 { 121 ASN1EncodableVector v = new ASN1EncodableVector(); 122 123 Object value = attributes.get(oid); 124 125 if (value instanceof Vector) 126 { 127 Enumeration e = ((Vector)value).elements(); 128 129 while (e.hasMoreElements()) 130 { 131 v.add((Attribute)e.nextElement()); 132 } 133 } 134 else if (value != null) 135 { 136 v.add((Attribute)value); 137 } 138 139 return v; 140 } 141 142 public int size() 143 { 144 int size = 0; 145 146 for (Enumeration en = attributes.elements(); en.hasMoreElements();) 147 { 148 Object o = en.nextElement(); 149 150 if (o instanceof Vector) 151 { 152 size += ((Vector)o).size(); 153 } 154 else 155 { 156 size++; 157 } 158 } 159 160 return size; 161 } 162 163 public Hashtable toHashtable() 164 { 165 return copyTable(attributes); 166 } 167 168 public ASN1EncodableVector toASN1EncodableVector() 169 { 170 ASN1EncodableVector v = new ASN1EncodableVector(); 171 Enumeration e = attributes.elements(); 172 173 while (e.hasMoreElements()) 174 { 175 Object value = e.nextElement(); 176 177 if (value instanceof Vector) 178 { 179 Enumeration en = ((Vector)value).elements(); 180 181 while (en.hasMoreElements()) 182 { 183 v.add(Attribute.getInstance(en.nextElement())); 184 } 185 } 186 else 187 { 188 v.add(Attribute.getInstance(value)); 189 } 190 } 191 192 return v; 193 } 194 195 public Attributes toASN1Structure() 196 { 197 return new Attributes(this.toASN1EncodableVector()); 198 } 199 200 private Hashtable copyTable( 201 Hashtable in) 202 { 203 Hashtable out = new Hashtable(); 204 Enumeration e = in.keys(); 205 206 while (e.hasMoreElements()) 207 { 208 Object key = e.nextElement(); 209 210 out.put(key, in.get(key)); 211 } 212 213 return out; 214 } 215 216 /** 217 * Return a new table with the passed in attribute added. 218 * 219 * @param attrType the type of the attribute to add. 220 * @param attrValue the value corresponding to the attribute (will be wrapped in a SET). 221 * @return a new table with the extra attribute in it. 222 */ 223 public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) 224 { 225 AttributeTable newTable = new AttributeTable(attributes); 226 227 newTable.addAttribute(attrType, new Attribute(attrType, new DERSet(attrValue))); 228 229 return newTable; 230 } 231 232 public AttributeTable remove(ASN1ObjectIdentifier attrType) 233 { 234 AttributeTable newTable = new AttributeTable(attributes); 235 236 newTable.attributes.remove(attrType); 237 238 return newTable; 239 } 240} 241