/* ** 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; import key.collections.SiteCollection; import java.util.Enumeration; import java.io.IOException; import java.io.DataInput; import java.io.DataOutput; import java.util.StringTokenizer; import java.util.Hashtable; /** * A container for sites. The Container is used as a * numeric hashtable for each sites number... */ public class Network extends Container implements Subnet { int position; int maxLen; /** * @param num is the low number of this network, for instance * 138 for the start of SoCS */ protected Network( int place, int classDistance, Integer num ) { this(); setPosition( place, classDistance, num ); } public void setPosition( int place, int classDistance, Integer num ) { position = place; maxLen = classDistance; if( num != null ) setKey( num ); } Network() { contained = new SiteCollection(); setConstraint( Type.SUBNET ); } public void dump() { dump( 0 ); } /** * This command is overridden in Internet */ public void unRegisterTrailer( String t ) { ((Network)getParent()).unRegisterTrailer( t ); } /** * This command is overridden in Internet */ public void registerTrailer( Site t ) { ((Network)getParent()).registerTrailer( t ); } protected void dump( int indent ) { for( Enumeration e = elements(); e.hasMoreElements(); ) { Object o = e.nextElement(); if( o instanceof Site ) { System.out.println( spaces( indent ) + o.toString() ); } else { ((Network)o).dump( indent + 2 ); } } } public Site search( int[] address ) { if( position >= address.length ) { // not enough args to uniquely identify // maybe throw an exception? //Log.debug( this, "position shortcutted on pos " + position ); return( null ); } Integer sWrapper = new Integer( (int) address[position] ); //Log.debug( this, "position " + position + ", id of net is " + getId() + ", address at that is " + sWrapper.toString() ); Object matched = contained.get( sWrapper ); if( matched != null ) { if( matched instanceof Reference ) { try { matched = ((Reference)matched).get(); } catch( OutOfDateReferenceException e ) { try { contained.unlink( (Symbol)matched ); } catch( Exception ex ) { } return( null ); } } if( matched instanceof Network ) return( ((Network)matched).search( address ) ); // pass it down else if( matched instanceof Site ) return( (Site) matched ); else throw new UnexpectedResult( "Network siteLevel contains something other than subnets & sites" ); } else return( null ); } public void insert( Site site ) { int[] mask = site.getMask(); if( position == mask.length ) { // this network represents the site?? throw new UnexpectedResult( "invalid site IP address too short" ); } else if( position > mask.length ) throw new UnexpectedResult( "site insert passed down too many times" ); if( position == maxLen ) { // just insert the site - this is a last level network (eg, 138.25.) // could check there wasn't already anything here //siteLevel.put( new Integer( (int) mask[ position ] ), site ); try { super.add( site ); } catch( BadKeyException e ) { throw new UnexpectedResult( e.toString() + " while adding a *numbered* site to the network" ); } catch( NonUniqueKeyException e ) { throw new UnexpectedResult( e.toString() + " while adding a *numbered* site to the network" ); } //Log.debug( this, "inserted site at position " + position ); } else { Object o = contained.get( new Integer( (int) mask[ position ] ) ); if( o instanceof Reference ) o = ((Reference)o).get(); Network subnet = (Network) o; if( subnet == null ) { // need to insert another subnet Integer n = new Integer( (int) mask[ position ] ); subnet = (Network) Factory.makeAtom( Network.class ); subnet.setPosition( position + 1, maxLen, n ); //siteLevel.put( n, subnet ); try { super.add( subnet ); } catch( BadKeyException e ) { throw new UnexpectedResult( e.toString() + " while adding a *numbered* site to the network" ); } catch( NonUniqueKeyException e ) { throw new UnexpectedResult( e.toString() + " while adding a *numbered* site to the network" ); } //Log.debug( this, "added subnet at position " + (position+1) ); } subnet.insert( site ); } } private static final String SPACES=" "; /** * Returns a string of the specified number of spaces * <p> * This routine has been optimised for up to 70 spaces, * requesting more than this will slow it down. */ private static String spaces( int n ) { if( n > SPACES.length() ) { StringBuffer sb = new StringBuffer(); while( n > SPACES.length() ) { sb.append( SPACES ); n -= SPACES.length(); } sb.append( SPACES.substring( SPACES.length() - n ) ); return( sb.toString() ); } else return( SPACES.substring( SPACES.length() - n ) ); } }