Source for gnu.javax.net.ssl.provider.X500PrincipalList

   1: /* X500PrincipalList.java -- A list of X.500 names.
   2:    Copyright (C) 2006  Free Software Foundation, Inc.
   3: 
   4: This file is a part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2 of the License, or (at
   9: your option) any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; if not, write to the Free Software
  18: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  19: USA
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version.  */
  37: 
  38: 
  39: package gnu.javax.net.ssl.provider;
  40: 
  41: import java.io.PrintWriter;
  42: import java.io.StringWriter;
  43: 
  44: import java.nio.ByteBuffer;
  45: 
  46: import java.util.ConcurrentModificationException;
  47: import java.util.ListIterator;
  48: import java.util.NoSuchElementException;
  49: 
  50: import javax.security.auth.x500.X500Principal;
  51: 
  52: public final class X500PrincipalList implements Iterable<X500Principal>
  53: {
  54:   private final ByteBuffer buffer;
  55:   private int modCount;
  56: 
  57:   public X500PrincipalList (final ByteBuffer buffer)
  58:   {
  59:     this.buffer = buffer;
  60:     modCount = 0;
  61:   }
  62: 
  63:   public int size ()
  64:   {
  65:     return (buffer.getShort (0) & 0xFFFF);
  66:   }
  67: 
  68:   public int count ()
  69:   {
  70:     int size = size ();
  71:     int i = 0;
  72:     for (int offset = 2; offset < size; i++)
  73:       {
  74:         int _size = (buffer.getShort (offset) & 0xFFFF);
  75:         // We don't want this going into an infinite loop if
  76:         // you mistakenly put a zero-length name.
  77:         if (_size == 0)
  78:           break;
  79:         offset += _size + 2;
  80:       }
  81:     return i;
  82:   }
  83: 
  84:   public X500Principal get (final int index)
  85:   {
  86:     if (index < 0)
  87:       throw new IndexOutOfBoundsException ("negative index");
  88:     int size = size ();
  89:     int i = 0;
  90:     for (int offset = 2; offset < size; i++)
  91:       {
  92:         int _size = (buffer.getShort (offset) & 0xFFFF);
  93:         if (_size == 0)
  94:           throw new IndexOutOfBoundsException ("zero-length name encountered");
  95:         if (i == index)
  96:           {
  97:             byte[] buf = new byte[_size];
  98:             buffer.position (offset + 2);
  99:             buffer.get (buf);
 100:             return new X500Principal (buf);
 101:           }
 102:         offset += 2 + _size;
 103:       }
 104:     throw new IndexOutOfBoundsException ("limit: " + i + "; requested: " + index);
 105:   }
 106: 
 107:   public void put (final int index, final X500Principal principal)
 108:   {
 109:     put (index, principal.getEncoded ());
 110:   }
 111: 
 112:   public void put (final int index, final byte[] encoded)
 113:   {
 114:     if (index < 0)
 115:       throw new IndexOutOfBoundsException ("negative index");
 116:     int size = size ();
 117:     int i = 0;
 118:     for (int offset = 2; offset < size; i++)
 119:       {
 120:         int off = (buffer.getShort (offset) & 0xFFFF);
 121:         if (i == index)
 122:           {
 123:             buffer.putShort (offset, (short) encoded.length);
 124:             buffer.position (offset + 2);
 125:             buffer.put (encoded);
 126:             modCount++;
 127:             return;
 128:           }
 129:         offset += 2 + off;
 130:       }
 131:     throw new IndexOutOfBoundsException ("limit: " + (i-1) + "; requested: " + index);
 132:   }
 133: 
 134:   public void setSize (final int numNames, final int namesSize)
 135:   {
 136:     if (numNames < 1)
 137:       throw new IllegalArgumentException ("must have at least one name");
 138:     int size = (numNames * 2) + namesSize;
 139:     if (size < 3 || size > buffer.capacity () || size > 0xFFFF)
 140:       throw new IllegalArgumentException ("size out of range; maximum: "
 141:                                           + Math.min (buffer.capacity (), 0xFFFF));
 142:     buffer.putShort (0, (short) size);
 143:   }
 144: 
 145:   public String toString ()
 146:   {
 147:     return toString (null);
 148:   }
 149: 
 150:   public String toString (final String prefix)
 151:   {
 152:     StringWriter str = new StringWriter ();
 153:     PrintWriter out = new PrintWriter (str);
 154:     if (prefix != null) out.print (prefix);
 155:     out.print ("[");
 156:     out.print (count ());
 157:     out.println ("] {");
 158:     for (Iterator it = new Iterator (); it.hasNext (); )
 159:       {
 160:         if (prefix != null) out.print (prefix);
 161:         out.print ("  ");
 162:         out.println (it.next ());
 163:       }
 164:     if (prefix != null) out.print (prefix);
 165:     out.print ("};");
 166:     return str.toString ();
 167:   }
 168: 
 169:   public boolean equals (Object o)
 170:   {
 171:     if (!(o instanceof X500PrincipalList))
 172:       return false;
 173:     X500PrincipalList that = (X500PrincipalList) o;
 174: 
 175:     if (size () != that.size ())
 176:       return false;
 177: 
 178:     for (Iterator it1 = new Iterator (), it2 = that.new Iterator ();
 179:          it1.hasNext () && it2.hasNext (); )
 180:       {
 181:         if (!it1.next ().equals (it2.next ()))
 182:           return false;
 183:       }
 184:     return true;
 185:   }
 186: 
 187:   public java.util.Iterator<X500Principal> iterator ()
 188:   {
 189:     return new Iterator();
 190:   }
 191: 
 192:   public class Iterator implements ListIterator<X500Principal>
 193:   {
 194:     private final int modCount;
 195:     private int index;
 196:     private final int count;
 197: 
 198:     public Iterator ()
 199:     {
 200:       this.modCount = X500PrincipalList.this.modCount;
 201:       index = 0;
 202:       count = count ();
 203:     }
 204: 
 205:     public void add (X500Principal o)
 206:     {
 207:       throw new UnsupportedOperationException ();
 208:     }
 209: 
 210:     public boolean hasNext ()
 211:     {
 212:       return (index < count);
 213:     }
 214: 
 215:     public boolean hasPrevious ()
 216:     {
 217:       return (index > 0);
 218:     }
 219: 
 220:     public X500Principal next () throws NoSuchElementException
 221:     {
 222:       if (modCount != X500PrincipalList.this.modCount)
 223:         throw new ConcurrentModificationException ();
 224:       try
 225:         {
 226:           return get (index++);
 227:         }
 228:       catch (IndexOutOfBoundsException ioobe)
 229:         {
 230:           throw new NoSuchElementException ();
 231:         }
 232:     }
 233: 
 234:     public int nextIndex ()
 235:     {
 236:       if (hasNext ())
 237:         return (index + 1);
 238:       return -1;
 239:     }
 240: 
 241:     public X500Principal previous () throws NoSuchElementException
 242:     {
 243:       if (index == 0)
 244:         throw new NoSuchElementException ();
 245:       if (modCount != X500PrincipalList.this.modCount)
 246:         throw new ConcurrentModificationException ();
 247:       try
 248:         {
 249:           return get (--index);
 250:         }
 251:       catch (IndexOutOfBoundsException ioobe)
 252:         {
 253:           throw new NoSuchElementException ();
 254:         }
 255:     }
 256: 
 257:     public int previousIndex ()
 258:     {
 259:       return (index - 1);
 260:     }
 261: 
 262:     public void remove ()
 263:     {
 264:       throw new UnsupportedOperationException ();
 265:     }
 266: 
 267:     public void set (final X500Principal o)
 268:     {
 269:       throw new UnsupportedOperationException ();
 270:     }
 271:   }
 272: }