001 /* BasicAttribute.java -- 002 Copyright (C) 2000, 2001, 2004, 2006 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.naming.directory; 040 041 import java.io.IOException; 042 import java.io.ObjectInputStream; 043 import java.io.ObjectOutputStream; 044 import java.util.NoSuchElementException; 045 import java.util.Vector; 046 047 import javax.naming.NamingEnumeration; 048 import javax.naming.NamingException; 049 import javax.naming.OperationNotSupportedException; 050 051 /** 052 * @author Tom Tromey (tromey@redhat.com) 053 * @date June 20, 2001 054 * @since 1.3 055 */ 056 public class BasicAttribute implements Attribute 057 { 058 private static final long serialVersionUID = 6743528196119291326L; 059 060 /** The ID of this attribute. */ 061 protected String attrID; 062 /** True if this attribute's values are ordered. */ 063 protected boolean ordered; 064 /** Values for this attribute. */ 065 protected transient Vector<Object> values; 066 067 // Used by cloning. 068 private BasicAttribute () 069 { 070 } 071 072 public BasicAttribute (String id) 073 { 074 this (id, false); 075 } 076 077 public BasicAttribute (String id, boolean ordered) 078 { 079 attrID = id; 080 this.ordered = ordered; 081 values = new Vector<Object> (); 082 } 083 084 public BasicAttribute (String id, Object value) 085 { 086 this (id, value, false); 087 } 088 089 public BasicAttribute (String id, Object value, boolean ordered) 090 { 091 attrID = id; 092 this.ordered = ordered; 093 values = new Vector<Object> (); 094 values.add (value); 095 } 096 097 public void add (int index, Object val) 098 { 099 if (! ordered && contains (val)) 100 throw new IllegalStateException ("value already in attribute"); 101 values.add (index, val); 102 } 103 104 public boolean add (Object val) 105 { 106 if (! ordered && contains (val)) 107 throw new IllegalStateException ("value already in attribute"); 108 return values.add (val); 109 } 110 111 public void clear () 112 { 113 values.clear (); 114 } 115 116 public Object clone () 117 { 118 BasicAttribute c = new BasicAttribute (); 119 c.attrID = attrID; 120 c.ordered = ordered; 121 c.values = (Vector<Object>) values.clone (); 122 return c; 123 } 124 125 public boolean contains (Object val) 126 { 127 for (int i = 0; i < values.size (); ++i) 128 { 129 if (equals (val, values.get (i))) 130 return true; 131 } 132 133 return false; 134 } 135 136 public boolean equals (Object obj) 137 { 138 if (! (obj instanceof BasicAttribute)) 139 return false; 140 BasicAttribute b = (BasicAttribute) obj; 141 142 if (ordered != b.ordered 143 || ! attrID.equals (b.attrID) 144 || values.size () != b.values.size ()) 145 return false; 146 147 for (int i = 0; i < values.size (); ++i) 148 { 149 boolean ok = false; 150 if (ordered) 151 ok = equals (values.get (i), b.values.get (i)); 152 else 153 { 154 for (int j = 0; j < b.values.size (); ++j) 155 { 156 if (equals (values.get (i), b.values.get (j))) 157 { 158 ok = true; 159 break; 160 } 161 } 162 } 163 164 if (! ok) 165 return false; 166 } 167 168 return true; 169 } 170 171 public Object get () 172 throws NamingException 173 { 174 if (values.size () == 0) 175 throw new NoSuchElementException ("no values"); 176 return get (0); 177 } 178 179 public Object get (int index) 180 throws NamingException 181 { 182 return values.get (index); 183 } 184 185 public NamingEnumeration<?> getAll () 186 throws NamingException 187 { 188 return new BasicAttributeEnumeration (); 189 } 190 191 public DirContext getAttributeDefinition () 192 throws OperationNotSupportedException, NamingException 193 { 194 throw new OperationNotSupportedException (); 195 } 196 197 public DirContext getAttributeSyntaxDefinition () 198 throws OperationNotSupportedException, NamingException 199 { 200 throw new OperationNotSupportedException (); 201 } 202 203 public String getID () 204 { 205 return attrID; 206 } 207 208 public int hashCode () 209 { 210 int val = attrID.hashCode (); 211 for (int i = 0; i < values.size (); ++i) 212 { 213 Object o = values.get (i); 214 if (o == null) 215 { 216 // Nothing. 217 } 218 else if (o instanceof Object[]) 219 { 220 Object[] a = (Object[]) o; 221 for (int j = 0; j < a.length; ++j) 222 val += a[j].hashCode (); 223 } 224 else 225 val += o.hashCode (); 226 } 227 228 return val; 229 } 230 231 public boolean isOrdered () 232 { 233 return ordered; 234 } 235 236 public Object remove (int index) 237 { 238 return values.remove (index); 239 } 240 241 public boolean remove (Object val) 242 { 243 for (int i = 0; i < values.size (); ++i) 244 { 245 if (equals (val, values.get (i))) 246 { 247 values.remove (i); 248 return true; 249 } 250 } 251 252 return false; 253 } 254 255 public Object set (int index, Object val) 256 { 257 if (! ordered && contains (val)) 258 throw new IllegalStateException ("value already in attribute"); 259 return values.set (index, val); 260 } 261 262 public int size () 263 { 264 return values.size (); 265 } 266 267 public String toString () 268 { 269 String r = attrID; 270 for (int i = 0; i < values.size (); ++i) 271 r += ";" + values.get (i).toString (); 272 return r; 273 } 274 275 // This is used for testing equality of two Objects according to our 276 // local rules. 277 private boolean equals (Object one, Object two) 278 { 279 if (one == null) 280 return two == null; 281 282 if (one instanceof Object[]) 283 { 284 if (! (two instanceof Object[])) 285 return false; 286 287 Object[] aone = (Object[]) one; 288 Object[] atwo = (Object[]) two; 289 290 if (aone.length != atwo.length) 291 return false; 292 293 for (int i = 0; i < aone.length; ++i) 294 { 295 if (! aone[i].equals (atwo[i])) 296 return false; 297 } 298 299 return true; 300 } 301 302 return one.equals (two); 303 } 304 305 private void readObject(ObjectInputStream s) 306 throws IOException, ClassNotFoundException 307 { 308 s.defaultReadObject(); 309 int size = s.readInt(); 310 values = new Vector<Object>(size); 311 for (int i=0; i < size; i++) 312 values.add(s.readObject()); 313 } 314 315 private void writeObject(ObjectOutputStream s) throws IOException 316 { 317 s.defaultWriteObject(); 318 s.writeInt(values.size()); 319 for (int i=0; i < values.size(); i++) 320 s.writeObject(values.get(i)); 321 } 322 323 // Used when enumerating this attribute. 324 private class BasicAttributeEnumeration implements NamingEnumeration 325 { 326 int where = 0; 327 328 public BasicAttributeEnumeration () 329 { 330 } 331 332 public void close () throws NamingException 333 { 334 } 335 336 public boolean hasMore () throws NamingException 337 { 338 return hasMoreElements (); 339 } 340 341 public Object next () throws NamingException 342 { 343 return nextElement (); 344 } 345 346 public boolean hasMoreElements () 347 { 348 return where < values.size (); 349 } 350 351 public Object nextElement () throws NoSuchElementException 352 { 353 if (where == values.size ()) 354 throw new NoSuchElementException ("no more elements"); 355 return values.get (where++); 356 } 357 } 358 }