/* ** j###t ########## #### #### ** j###t ########## #### #### ** j###T "###L J###" ** ######P' ########## ######### ** ######k, ########## T######T ** ####~###L #### ** #### q###L ########## .##### ** #### \###L ########## #####" ** ** $Id$ ** ** Class History ** ** Date Name Description ** ---------|------------|----------------------------------------------- ** 19Aug98 subtle start of recorded history ** */ package key.collections; import key.*; import key.util.LinkedList; import java.util.Enumeration; import java.io.*; import java.util.NoSuchElementException; import java.util.Hashtable; /** * A special collection that requires that all its * symbols use AliasListKey's as their key. WARNING: * this collection should NOT be used by a reference * container, as it has a nasty tendancy to change the * key of everything added to it to AliasListKey's. * * This collections very specific purpose at the moment * is for help files. (ie, "help res" and "help resident" * call the same file - the lookup must be equivalent. */ public final class AliasCollection implements Collection { private transient Hashtable theHash; private LinkedList theList; public AliasCollection() { init(); theList = new LinkedList(); } public AliasCollection( Collection c ) { this(); for( Enumeration e = c.elements(); e.hasMoreElements(); ) { try { link( (Symbol) e.nextElement() ); } catch( BadKeyException ex ) { } catch( NonUniqueKeyException ex ) { } } } private void init() { theHash = new Hashtable(); } private void readObject( ObjectInputStream ois ) throws IOException { try { ois.defaultReadObject(); } catch( ClassNotFoundException e ) { throw new UnexpectedResult( e.toString() ); } init(); for( Enumeration e = theList.elements(); e.hasMoreElements(); ) { try { linkToHash( (Symbol) e.nextElement() ); } catch( NonUniqueKeyException ex ) { Log.debug( this, ex.toString() ); ex.printStackTrace( System.out ); } } } private void linkToHash( Symbol a ) throws NonUniqueKeyException { Object key = a.getKey(); AliasListKey newKey; if( !(key instanceof AliasListKey) ) { newKey = new AliasListKey(); newKey.setPrimary( key.toString() ); a.setKey( newKey ); // this is pretty hacky. if( a instanceof Reference ) { ((Reference)a).get().setKey( newKey ); } //System.out.println( "Added non-ALK: " + key.toString() + " to AliasColl" ); } else { newKey = (AliasListKey) key; //System.out.println( "Added ALK: " + key.toString() + " to AliasColl" ); } String pk = newKey.getPrimary(); if( theHash.contains( pk ) ) throw new NonUniqueKeyException( "'" + newKey.getPrimary() + "' is already in this collection." ); theHash.put( pk, a ); addSecondaries( newKey, a ); } /** * Add this object to the list of objects * @param p the player to add to the list * @exception NonUniqueKeyException if there is already a player in with this name * @exception BadKeyException if this players name is malformed somehow */ public void link( Symbol a ) throws NonUniqueKeyException,BadKeyException { linkToHash( a ); theList.append( a ); } public void conceal( Symbol a ) { } public void reveal( Symbol a ) { } /** * Adds this atom to the database in such a * way that it can be matched, but not seen * by iterating through the elements. */ public void partialLink( Symbol a ) throws NonUniqueKeyException,BadKeyException { link( a ); } /** * Take this player out of the list of players * @param p the player to remove from the list * @exception NoSuchElementException if the player is not in the list * @exception BadKeyException if the players name is malformed somehow */ public void unlink( Symbol a ) throws NoSuchElementException,BadKeyException { Object key = a.getKey(); // its not possible that the element be // in this collection unless it has an // aliaslistkey key. if( key instanceof AliasListKey ) { AliasListKey alk = (AliasListKey) key; if( theHash != null ) { theHash.remove( alk.getPrimary() ); theList.removeEqual( a ); removeSecondaries( alk ); } } } public boolean contains( Symbol o ) { return( theList.containsEqual( o ) ); } /** * Sorts the elements in this linked trie */ public void sort() { } /** * Returns the atom matched, or, possibly, an instance of * a Trie object that contains all the matching atoms. * <p> * A null is returned if no matches were found at all. The * match string is searched until the end of the string or * a non-alphabetical character is found. * * @param match the start or whole string to match from * @return An atom object, referring to the sole match, or a Trie */ public Object get( Object key ) { if( key instanceof String ) return( theHash.get( ((String)key).toLowerCase() ) ); else return( theHash.get( key.toString() ) ); } public Symbol getExact( String key ) { return( (Symbol) get( key ) ); } public Object getTrieFor( String match ) { return( null ); } public Symbol getElementAt( int c ) { return( (Symbol) theList.getElementAt( c ) ); } /** * aha!, but I reserve the right to make this function more efficient * this way ;p~ (ie, it isn't very, atm) */ public void removeElementAt( int c ) throws NonUniqueKeyException,NoSuchElementException,BadKeyException { Symbol s = (Symbol) theList.getElementAt( c ); unlink( s ); } public Enumeration elements() { return( theList.elements() ); } public int count() { return( theList.count() ); } public void deallocate() { } public void concealable( boolean t ) { } public void removeSecondaries( AliasListKey alk ) { for( Enumeration e = alk.secondaryKeys(); e.hasMoreElements(); ) theHash.remove( e.nextElement() ); } public void addSecondaries( AliasListKey alk, Symbol o ) { for( Enumeration e = alk.secondaryKeys(); e.hasMoreElements(); ) { Object n = e.nextElement(); //System.out.println( "ALK: aliased " + n.toString() ); theHash.put( n, o ); } } }