/*
** 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 ) );
}
}