/************************************************* * * = PACKAGE * JACE.ServiceConfigurator * * = FILENAME * ServiceConfig.java * *@author Prashant Jain * *************************************************/ package JACE.ServiceConfigurator; import java.io.*; import java.net.*; import JACE.OS.*; import JACE.Misc.*; /** *
TITLE
* Provide the base class that supplies common server daemon
* operations.
*/
public class ServiceConfig
{
public static int open (String [] args) throws
FileNotFoundException, IOException, ClassNotFoundException,
IllegalAccessException, InstantiationException
{
ServiceConfig.parseArgs (args);
if (ServiceConfig.svcRep_ == null)
ServiceConfig.svcRep_ = new ServiceRepository ();
return ServiceConfig.processDirectives ();
}
protected static int processDirectives () throws
FileNotFoundException, IOException, ClassNotFoundException,
IllegalAccessException, InstantiationException
{
File configFile = new File (ServiceConfig.serviceConfigFile_);
// Check if file exists and is a normal file
if (!configFile.exists () || !configFile.isFile ())
throw new FileNotFoundException ("File " + ServiceConfig.serviceConfigFile_ + " not found");
// Check if the file is readable
if (!configFile.canRead ())
throw new IOException ("File " + ServiceConfig.serviceConfigFile_ + " not readable");
// Set up the stream
FileInputStream fileIn = new FileInputStream (configFile);
// Parse the file
StreamTokenizer in = new StreamTokenizer (fileIn);
// Set '#' as comment character to be ignored and set '/' as
// ordinary character (was original comment character)
// in.commentChar ('#');
in.ordinaryChar ('/');
// Set characters in ASCII range 33 to 47, ASCII range 91 to 96,
// and ASCII range 123 to 126 as ordinary characters
in.wordChars ('!', '/'); // ASCII range 33 to 47
in.wordChars (':', '@'); // ASCII range 58 to 64
in.wordChars ('[', '`'); // ASCII range 91 to 96
in.wordChars ('{', '~'); // ASCII range 123 to 126
String className = null;
String classType = null;
String args = null;
// Create a state machine
int state = ServiceConfig.CLASS_NAME;
while (in.nextToken () != StreamTokenizer.TT_EOF)
{
switch (state)
{
case ServiceConfig.CLASS_NAME:
if (in.ttype == StreamTokenizer.TT_WORD)
className = in.sval;
else
throw new IOException ("Illegal CLASS NAME argument in file " + ServiceConfig.serviceConfigFile_);
state = ServiceConfig.CLASS_TYPE;
break;
case ServiceConfig.CLASS_TYPE:
if (in.ttype == StreamTokenizer.TT_WORD)
classType = in.sval;
else
throw new IOException ("Illegal CLASS TYPE argument in file " + ServiceConfig.serviceConfigFile_);
state = ServiceConfig.ARGS;
// Set space to be an ordinary character to allow
// arguments to be parsed in
in.wordChars (' ', ' ');
break;
case ServiceConfig.ARGS:
if (in.ttype == StreamTokenizer.TT_WORD)
{
args = in.sval;
// Load the class
Class c = null;
// First check if we need to load the class from the
// file system or from across the network.
if (className.lastIndexOf ("://") != -1)
{
// We need to get the bytes over the network since
// the name specified in the configuration file
// contains a protocol specification
c = ServiceConfig.svcRep_.load (new URL (className));
}
else
{
c = ServiceConfig.svcRep_.load (className);
}
// Note that c should be defined else an exception
// would have been thrown by now
// Figure out the type of the class, create an
// instance and then invoke the initialization method
if (classType.equals ("ServiceObject"))
{
ServiceObject svcObj = (ServiceObject) c.newInstance ();
// Create an array of String from args String
String [] argArray = OS.createStringArray (args, " ");
// Call init on the Service Object passing in arguments
svcObj.init (argArray);
}
else
throw new IOException ("Illegal CLASS TYPE argument in file " + ServiceConfig.serviceConfigFile_);
}
else
throw new IOException ("Illegal ARGS argument in file " + ServiceConfig.serviceConfigFile_);
state = ServiceConfig.CLASS_NAME;
// Set space back to whitespace-character to extract the
// next token
in.whitespaceChars (' ', ' ');
break;
default:
throw new IOException ("Illegal argument in file " + ServiceConfig.serviceConfigFile_);
}
}
return 0;
}
protected static void parseArgs (String [] args)
{
GetOpt getopt = new GetOpt (args, "bdnf:");
for (int c; (c = getopt.next ()) != -1; )
switch (c)
{
case 'b':
// Note: not supported yet!
ServiceConfig.beADaemon_ = true;
break;
case 'd':
ServiceConfig.debug_ = true;
break;
case 'n':
ServiceConfig.noDefaults_ = true;
break;
case 'f':
ServiceConfig.serviceConfigFile_ = getopt.optarg ();
break;
default:
ACE.ERROR ((char ) c + " is not a ServiceConfig option");
break;
}
}
// Set by command line options
private static boolean beADaemon_ = false;
private static boolean debug_ = false;
private static boolean noDefaults_ = false;
private static String serviceConfigFile_ = "svc.conf";
private static ServiceRepository svcRep_ = null;
// States for the state-machine used in parsing the config file
private final static int CLASS_NAME = 0;
private final static int CLASS_TYPE = 1;
private final static int ARGS = 2;
}