package com.idega.core.ldap.client.naming; import java.util.*; import javax.naming.*; //import javax.naming.directory.*; /** * A simple class that implements NamingEnumeration, used to * bundle up search results 'n stuff. Used by not-really-jndi * ftns to wrap things nicely for higher level ftns that are * expecting NamingEnumerations. * * as usual, the enumeration can be enumerated using the model: * <pre> * while (myEnumeration.hasMoreElements()) * doSomethingWith(myEnumeration.nextElement(); * </pre> * in addition, it supports the NamingEnumeration interface * equivalent, which (<b>in the future</b>) may also throw a NamingException. * <pre> * try * { * while (myEnumeration.hasMore()) * doSomethingWith(myEnumeration.next(); * } * catch (NamingException e) { } * </pre> * * As a spot of convenience evil, it implements a sort() ftn as well... * (Since it's not a 'dynamic' enumeration as a normal naming enumeration * would be, but uses a vector base object), and also allows the enumeration * to be dumped out as a vector or a string array :-) . */ public class DXNamingEnumeration implements NamingEnumeration { private int pointer = 0; private ArrayList data; //private Exception e = null; // not currently used; implement Naming Exceptions /** * A quickie class for ordering stuff using their intrinsic toString() methods... */ class SimpleComparator implements Comparable { Object myObject; String compareString; public SimpleComparator(Object o) { this.myObject = (o==null)?"null":o; if (this.myObject instanceof DXAttribute) { this.compareString = ((DXAttribute)this.myObject).getID().toLowerCase(); } else { this.compareString = this.myObject.toString().toLowerCase(); } } public int compareTo(Object compObject) { return this.compareString.compareTo(compObject.toString()); } public String toString() { return this.compareString; } public Object getObject() {return this.myObject; } } // with this if needed in future... /** * The constructor does nothing except initialise class variables. */ public DXNamingEnumeration() { this.data = new ArrayList(); } /** * A quicky to wrap normal enumerations with as well... */ public DXNamingEnumeration(Enumeration ne) { this.data = new ArrayList(); while (ne.hasMoreElements()) { add(ne.nextElement()); } } /** * The constructor takes another NamingEnumeration and uses * it to initialise with. */ public DXNamingEnumeration(NamingEnumeration ne) { this.data = new ArrayList(); if (ne!=null) { while (ne.hasMoreElements()) { add(ne.nextElement()); } } } /** * A convenience constructor to wrap an existing ArrayList. * Note that since the enumeration is supposed to be read-only, * the initialising ArrayList is <i>not</i> cloned, but used as is. */ public DXNamingEnumeration(ArrayList listData) { this.data = listData; } /** * Adds an object to the enumeration. * @param o object to be added. */ public void add(Object o) { this.data.add(o); } /** * Removes an object from the enumeration. * @param o the object to be removed. */ public void remove(Object o) { this.data.remove(o); } /** * Enumerations can't usually be re-used. Sometimes it would be * nice though... this resets the enumeration so you can reread it, * which is useful for debugging (i.e. you can print it before use...) */ public void reset() { this.pointer = 0; } /** * Not really necessary, this returns the number of elements in the * enumeration. * @return number of objects in enumeration */ public int size() { return this.data.size(); } /* * identical in ftn to hasMoreElements(). In future, this may * throw NamingEnumerationExceptions. * @return true if more elements are available. */ public boolean hasMore() { return (this.pointer < this.data.size()); } /* * standard enumeration ftn. * @return true if more elements are available */ public boolean hasMoreElements() { return hasMore(); } /* * identical in ftn to nextElement(). * * @return returns the next element in the enumeration. */ public Object next() throws NoSuchElementException { try { return this.data.get(this.pointer++); } catch (ArrayIndexOutOfBoundsException e) { throw new NoSuchElementException(); } } /* * standard enumeration ftn. * * @return returns the next element in the enumeration. */ public Object nextElement() throws NoSuchElementException { return next(); } /** * This method attempts to order the components of the * SimpleEnumeration using their intrinsic 'toString()' * methods (this may be meaningless for some components). */ // XXX there may be a a heft time hit for using this... public DXNamingEnumeration sort() { int size = this.data.size(); // wrap the contents of the data ArrayList in SimpleComparators, and // dump them to an array... SimpleComparator[] a = new SimpleComparator[size]; for (int i=0; i<size; i++) { a[i] = new SimpleComparator(this.data.get(i)); } // use the built in static Arrays.sort method Arrays.sort(a); // reload the ArrayList with the sorted data this.data.clear(); for (int i=0; i<size; i++) { this.data.add(a[i].getObject()); } return this; } /** * A simple existance test against the core ArrayList list of * objects. */ public boolean contains(Object test) { return this.data.contains(test); } /** * Included for Naming Enumeration compatibility... does nothing, * 'cause DXNamingEnumeration isn't really an enumeration, and * has already slurped all the data... :-) */ public void close() {;} public String toString() // mainly used for debugging { StringBuffer ret = new StringBuffer(); for (int i=0; i<this.data.size(); i++) { Object o = this.data.get(i); ret.append((o==null)?"null":o.toString() + "\n"); } return ret.toString(); } public Object[] toArray() { return this.data.toArray(); } public String[] toStringArray() { String[] ret = new String[this.data.size()]; for (int i=0; i<this.data.size(); i++) { Object o = this.data.get(i); ret[i] = ((o==null)?null:o.toString()); } return ret; } public ArrayList getArrayList() { return this.data; } }