@ -48,6 +48,8 @@ import java.io.PrintWriter;
import java.net.InetAddress ;
import java.net.InetAddress ;
import java.util.Enumeration ;
import java.util.Enumeration ;
import java.util.Hashtable ;
import java.util.Hashtable ;
import java.util.Map ;
import java.util.HashMap ;
import java.util.Iterator ;
import java.util.Iterator ;
import java.util.Properties ;
import java.util.Properties ;
import java.util.TreeMap ;
import java.util.TreeMap ;
@ -56,12 +58,14 @@ public abstract class serverAbstractSwitch implements serverSwitch {
// configuration management
// configuration management
private final File configFile ;
private final File configFile ;
private Hashtable configProps ;
private Map configProps ;
private final String configComment ;
private final String configComment ;
private final Hash table authorization ;
private final Hash Map authorization ;
private String rootPath ;
private String rootPath ;
private final TreeMap workerThreads ;
private final TreeMap workerThreads ;
protected int serverJobs ;
private final TreeMap switchActions ;
protected serverLog log ;
protected int serverJobs ;
public serverAbstractSwitch ( String rootPath , String initPath , String configPath ) throws IOException {
public serverAbstractSwitch ( String rootPath , String initPath , String configPath ) throws IOException {
// we initialize the switchboard with a property file,
// we initialize the switchboard with a property file,
@ -77,20 +81,18 @@ public abstract class serverAbstractSwitch implements serverSwitch {
new File ( configFile . getParent ( ) ) . mkdir ( ) ;
new File ( configFile . getParent ( ) ) . mkdir ( ) ;
// predefine init's
// predefine init's
Hashtable initProps ;
Map initProps ;
if ( initFile . exists ( ) ) initProps = loadHash table ( initFile ) ; else initProps = new Hash table ( ) ;
if ( initFile . exists ( ) ) initProps = loadHash Map ( initFile ) ; else initProps = new Hash Map ( ) ;
// load config's from last save
// load config's from last save
if ( configFile . exists ( ) ) configProps = loadHash table ( configFile ) ; else configProps = new Hash table ( ) ;
if ( configFile . exists ( ) ) configProps = loadHash Map ( configFile ) ; else configProps = new Hash Map ( ) ;
// remove all values from config that do not appear in init (out-dated settings)
// remove all values from config that do not appear in init (out-dated settings)
Enumeration e = configProps . keys ( ) ;
Iterator i = configProps . keySet ( ) . iterator ( ) ;
String key ;
String key ;
while ( e . hasMoreElements ( ) ) {
while ( i . hasNext ( ) ) {
key = ( String ) e . nextElement ( ) ;
key = ( String ) i . next ( ) ;
//System.out.println("TESTING " + key);
if ( ! ( initProps . containsKey ( key ) ) ) {
if ( ! ( initProps . containsKey ( key ) ) ) {
//System.out.println("MIGRATE: removing out-dated property '" + key + "'");
configProps . remove ( key ) ;
configProps . remove ( key ) ;
}
}
}
}
@ -104,16 +106,28 @@ public abstract class serverAbstractSwitch implements serverSwitch {
saveConfig ( ) ;
saveConfig ( ) ;
// other settings
// other settings
authorization = new Hash table ( ) ;
authorization = new Hash Map ( ) ;
// init thread control
// init thread control
workerThreads = new TreeMap ( ) ;
workerThreads = new TreeMap ( ) ;
// init switch actions
switchActions = new TreeMap ( ) ;
// init busy state control
// init busy state control
serverJobs = 0 ;
serverJobs = 0 ;
}
}
public static Hashtable loadHashtable ( File f ) {
// a logger for this switchboard
public void setLog ( serverLog log ) {
this . log = log ;
}
public serverLog getLog ( ) {
return log ;
}
public static Map loadHashMap ( File f ) {
// load props
// load props
Properties prop = new Properties ( ) ;
Properties prop = new Properties ( ) ;
try {
try {
@ -125,15 +139,16 @@ public abstract class serverAbstractSwitch implements serverSwitch {
return ( Hashtable ) prop ;
return ( Hashtable ) prop ;
}
}
public static void save Hashtable( File f , Hashtable props , String comment ) throws IOException {
public static void save Map( File f , Map props , String comment ) throws IOException {
PrintWriter pw = new PrintWriter ( new FileOutputStream ( f ) ) ;
PrintWriter pw = new PrintWriter ( new FileOutputStream ( f ) ) ;
pw . println ( "# " + comment ) ;
pw . println ( "# " + comment ) ;
Enumeration e = props . keys ( ) ;
Iterator i = props . entrySet ( ) . iterator ( ) ;
String key , value ;
String key , value ;
while ( e . hasMoreElements ( ) ) {
Map . Entry entry ;
key = ( String ) e . nextElement ( ) ;
while ( i . hasNext ( ) ) {
//value = (String) props.get(key);
entry = ( Map . Entry ) i . next ( ) ;
value = ( ( String ) props . get ( key ) ) . replaceAll ( "\n" , "\\\\n" ) ;
key = ( String ) entry . getKey ( ) ;
value = ( ( String ) entry . getValue ( ) ) . replaceAll ( "\n" , "\\\\n" ) ;
pw . println ( key + "=" + value ) ;
pw . println ( key + "=" + value ) ;
}
}
pw . println ( "# EOF" ) ;
pw . println ( "# EOF" ) ;
@ -145,35 +160,93 @@ public abstract class serverAbstractSwitch implements serverSwitch {
}
}
public void setConfig ( String key , String value ) {
public void setConfig ( String key , String value ) {
configProps . put ( key , value ) ;
// perform action before setting new value
Map . Entry entry ;
serverSwitchAction action ;
Iterator i = switchActions . entrySet ( ) . iterator ( ) ;
while ( i . hasNext ( ) ) {
entry = ( Map . Entry ) i . next ( ) ;
action = ( serverSwitchAction ) entry . getValue ( ) ;
try {
action . doBevoreSetConfig ( key , value ) ;
} catch ( Exception e ) {
log . logError ( "serverAction bevoreSetConfig '" + action . getShortDescription ( ) + "' failed with exception: " + e . getMessage ( ) ) ;
}
}
// set the value
String oldValue = ( String ) configProps . put ( key , value ) ;
saveConfig ( ) ;
saveConfig ( ) ;
// perform actions afterwards
i = switchActions . entrySet ( ) . iterator ( ) ;
while ( i . hasNext ( ) ) {
entry = ( Map . Entry ) i . next ( ) ;
action = ( serverSwitchAction ) entry . getValue ( ) ;
try {
action . doAfterSetConfig ( key , value , oldValue ) ;
} catch ( Exception e ) {
log . logError ( "serverAction afterSetConfig '" + action . getShortDescription ( ) + "' failed with exception: " + e . getMessage ( ) ) ;
}
}
}
}
public String getConfig ( String key , String dflt ) {
public String getConfig ( String key , String dflt ) {
// get the value
String s = ( String ) configProps . get ( key ) ;
String s = ( String ) configProps . get ( key ) ;
// do action
Map . Entry entry ;
serverSwitchAction action ;
Iterator i = switchActions . entrySet ( ) . iterator ( ) ;
while ( i . hasNext ( ) ) {
entry = ( Map . Entry ) i . next ( ) ;
action = ( serverSwitchAction ) entry . getValue ( ) ;
try {
action . doWhenGetConfig ( key , s , dflt ) ;
} catch ( Exception e ) {
log . logError ( "serverAction whenGetConfig '" + action . getShortDescription ( ) + "' failed with exception: " + e . getMessage ( ) ) ;
}
}
// return value
if ( s = = null ) return dflt ; else return s ;
if ( s = = null ) return dflt ; else return s ;
}
}
public Enumeration configKeys ( ) {
public Iterator configKeys ( ) {
return configProps . keys ( ) ;
return configProps . key Set( ) . iterator ( ) ;
}
}
private void saveConfig ( ) {
private void saveConfig ( ) {
try {
try {
saveHashtable ( configFile , configProps , configComment ) ;
save Map ( configFile , configProps , configComment ) ;
} catch ( IOException e ) {
} catch ( IOException e ) {
System . out . println ( "ERROR: cannot write config file " + configFile . toString ( ) + ": " + e . getMessage ( ) ) ;
System . out . println ( "ERROR: cannot write config file " + configFile . toString ( ) + ": " + e . getMessage ( ) ) ;
}
}
}
}
public void deployThread ( String threadName , String threadShortDescription , String threadLongDescription , serverThread newThread , serverLog log , long startupDelay ) {
// add/remove action listener
public void deployAction ( String actionName , String actionShortDescription , String actionLongDescription ,
serverSwitchAction newAction ) {
newAction . setLog ( log ) ;
newAction . setDescription ( actionShortDescription , actionLongDescription ) ;
switchActions . put ( actionName , newAction ) ;
}
public void undeployAction ( String actionName ) {
switchActions . remove ( actionName ) ;
}
public void deployThread ( String threadName , String threadShortDescription , String threadLongDescription , serverThread newThread , long startupDelay ) {
deployThread ( threadName , threadShortDescription , threadLongDescription ,
deployThread ( threadName , threadShortDescription , threadLongDescription ,
newThread , log , startupDelay ,
newThread , startupDelay,
Long . parseLong ( getConfig ( threadName + "_idlesleep" , "novalue" ) ) ,
Long . parseLong ( getConfig ( threadName + "_idlesleep" , "novalue" ) ) ,
Long . parseLong ( getConfig ( threadName + "_busysleep" , "novalue" ) ) ) ;
Long . parseLong ( getConfig ( threadName + "_busysleep" , "novalue" ) ) ) ;
}
}
public void deployThread ( String threadName , String threadShortDescription , String threadLongDescription , serverThread newThread , serverLog log , long startupDelay , long initialIdleSleep , long initialBusySleep ) {
public void deployThread ( String threadName , String threadShortDescription , String threadLongDescription , serverThread newThread , long startupDelay , long initialIdleSleep , long initialBusySleep ) {
if ( newThread . isAlive ( ) ) throw new RuntimeException ( "undeployed threads must not live; they are started as part of the deployment" ) ;
if ( newThread . isAlive ( ) ) throw new RuntimeException ( "undeployed threads must not live; they are started as part of the deployment" ) ;
newThread . setStartupSleep ( startupDelay ) ;
newThread . setStartupSleep ( startupDelay ) ;
long sleep ;
long sleep ;