peersim的配置管理器的代码都放在了peersim下的config包里面,如上图所示!其中比较重要的有四个类:ConfigContainer、ConfigProperties、Configuration、ParsedProperties。这四个类可以分为两组,第一组就是ParseProperties、ConfigProperties这两个类,主要是用来解析配置文件(.cfg文件);第二组就是ConfigContainer、Configuration这两个类,主要是用来解析Properties里面的参数。
而在这个包里面其他比较重要的就是CheckConfig,这个类带有main()方法,因此可以单独运行,其主要作用就是检查你的配置文件,并且输出配置文件的相应配置信息。至于其他的本人没有深入了解了。
下面就以上提到的两组类进行详细分析:
第一组:ConfigProperties类是用来处理配置文件的,它继承Properties类,该类有四种构造方式,代码如下:
// =========== Public Constructors ===================================
// ===================================================================
/**
* Calls super constructor.
*/
public ConfigProperties() { super(); }
// -------------------------------------------------------------------
/**
* Constructs a ConfigProperty object from a parameter list.
* The algorithm is as follows: first <code>resource</code> is used to attempt
* loading default values from the given system resource.
* Then all Strings in <code>pars</code> are processed in the order they
* appear in the array. For <code>pars[i]</code>, first a property file
* with the name <code>pars[i]</code> is attempted to be loaded. If the file
* does not exist or loading produces any other IOException, <code>pars[i]</code>
* is interpreted as a property definition, and it is set.
* <p>
* A little inconvenience is that if <code>pars[i]</code> is supposed to be
* a command line argument, but it is a valid filename at the same time by
* accident, the algorithm will process it as a file instead of a command line
* argument. The caller must take care of that.
* <p>
* No exceptions are thrown, instead error messages are written to the
* standard error. Users who want a finer control should use
* the public methods of this class.
*
* @param pars The (probably command line) parameter list.
* @param resource The name of the system resource that contains the
* defaults. null if there isn't any.
*
*/
public ConfigProperties( String[] pars, String resource ) {
try
{
if( resource != null )
{
loadSystemResource(resource);
System.err.println("ConfigProperties: System resource "
+resource+" loaded.");
}
}
catch( Exception e )
{
System.err.println("ConfigProperties: " + e );
}
if( pars == null || pars.length == 0 ) return;
for (int i=0; i < pars.length; i++)
{
try
{
load( pars[i] );
System.err.println(
"ConfigProperties: File "+pars[i]+" loaded.");
pars[i] = "";
}
catch( IOException e )
{
try
{
loadPropertyString( pars[i] );
System.err.println("ConfigProperties: Property '" +
pars[i] + "' set.");
}
catch( Exception e2 )
{
System.err.println("ConfigProperties: " + e2 );
}
}
catch( Exception e )
{
System.err.println("ConfigProperties: " + e );
}
}
}
// -------------------------------------------------------------------
/**
* Constructs a ConfigProperty object by loading a file by calling
* {@link #load}.
* @param fileName The name of the configuration file.
*/
public ConfigProperties( String fileName ) throws IOException {
//重写了Properties的load方法
load( fileName );
}
// -------------------------------------------------------------------
/**
* Calls super constructor.
*/
public ConfigProperties( Properties props ) {
super( props );
}
// -------------------------------------------------------------------
/**
* Calls {@link #ConfigProperties(String[],String)} with resource set to null.
*/
public ConfigProperties( String[] pars ) {
this( pars, null );
}
可以通过四种方式处理配置文件。并且重写了父类中的load(String fileName )方法,其代码如下:
/**
* Loads given file. Calls <code>Properties.load</code> with a file
* input stream to the given file.
*/
public void load( String fileName ) throws IOException {
//读取配置文件从fileName的路径下读取
FileInputStream fis = new FileInputStream( fileName );
//load配置文件,把配置文件一行一行的读出来,并且存储在hashtable中
//load属于Properties下的一个方法,而Properties其实就是对于一个Hashtable的封装
load( fis );
//注意关闭IO
fis.close();
}
这个load方法就是把配置文件一行一行的读出来,并且存储在hashtable中。
而ParseProperties继承自ConfigProperties,并且提供了两种构造方式,代码如下:
// ================= initialization =================================
// ==================================================================
/**
* Calls super constructor.
* @see ConfigProperties#ConfigProperties(String[])
*/
public ParsedProperties( String[] pars ) {
super( pars );
}
// ------------------------------------------------------------------
/**
* Calls super constructor.
* @see ConfigProperties#ConfigProperties(String)
*/
//解析配置文件
public ParsedProperties( String filename ) throws IOException {
//由于ParseProperties重写了ConfigProperties中的load方法,而ConfigProperties又重写了Properties的load方法,
//所以以下执行的是ParseProperties中的load方法。
super( filename );
}
这个类中最重要的就是重写了ConfigProperties中的load方法,为配置文件的解析提供了一种自由自我的解析方式,因此对于复杂的配置文件,诸如:
/* This set is used to store prefixes that have been associated
* to brackets blocks. If a prefix is inserted twice, this means
* that there are two blocks referring to the same prefix -
* which may be caused by a commented prefix in the config
* file, something like this:
*
* prefix1
* {
* property 1
* }
* #prefix2
* {
* property 2
* }
*
*/
都可以提供解析,并且把解析的参数以键值对的方式存储在一个Properties(Properties继承自Hashtable)中。
第二组:这两个类中,Configuration是对ConfigContainer的封装,并且Configuration不提供继承。这组类的主要是从第一组解析出的Properties中提取出参数,并且设置配置参数到到相应的配置属性值上。ConfigContainer提供了所有取得配置参数的方法,比如:getInt()、getDouble()、getInstance()等等。其最主要的行为在于其构造器,其代码如下:
// =================== initialization ================================
// ===================================================================
public ConfigContainer(Properties config, boolean check)
{
this.config = config;
this.check = check;
//此处设置迭代的次数,假如配置文件中没有相应的参数设置默认设置为100
maxdepth = getInt(Configuration.PAR_MAXDEPTH, Configuration.DEFAULT_MAXDEPTH);
// initialize protocol id-s
protocols = new HashMap<String, Integer>();
String[] prots = getNames(Configuration.PAR_PROT);// they're returned in correct order
for (int i = 0; i < prots.length; ++i) {
protocols.put(prots[i].substring(Configuration.PAR_PROT.length() + 1), Integer.valueOf(i));
}
String debug = config.getProperty(Configuration.PAR_DEBUG);
if (Configuration.DEBUG_EXTENDED.equals(debug))
debugLevel = DEBUG_CONTEXT;
else if (Configuration.DEBUG_FULL.equals(debug)) {
Map<String, String> map = new TreeMap<String, String>();
Enumeration e = config.propertyNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = config.getProperty(name);
map.put(name, value);
}
Iterator i = map.keySet().iterator();
while (i.hasNext()) {
String name = (String) i.next();
System.err.println("DEBUG " + name
+ ("".equals(map.get(name)) ? "" : " = " + map.get(name)));
}
} else if (debug != null) {
debugLevel = DEBUG_REG;
} else {
debugLevel = DEBUG_NO;
}
}
ConfigContainer就是一个配置参数的容器,其可以实现对Properties的解析,提取出所有的配置参数。
而对于CheckConfig,以下只提供运行这个方法的结果,一看就明白这个类的用途:
Warning: Property expressions.maxdepth = 100 (DEFAULT)
Warning: Property include.protocol = null (DEFAULT)
Warning: Property order.protocol = null (DEFAULT)
Warning: Property include.range = null (DEFAULT)
Warning: Property order.range = null (DEFAULT)
Warning: Property network.initialCapacity = 50000 (DEFAULT)
Warning: Property include.protocol = null (DEFAULT)
Warning: Property order.protocol = null (DEFAULT)
Warning: Property include.control = null (DEFAULT)
Warning: Property order.control = null (DEFAULT)
Warning: Property include.protocol = null (DEFAULT)
Warning: Property order.protocol = null (DEFAULT)
Warning: Property protocol.avg.step = 1 (DEFAULT)
Warning: Property protocol.avg.from = 0 (DEFAULT)
Warning: Property protocol.avg.until = 9223372036854775807 (DEFAULT)
Warning: Property protocol.lnk.step = 1 (DEFAULT)
Warning: Property protocol.lnk.from = 0 (DEFAULT)
Warning: Property protocol.lnk.until = 9223372036854775807 (DEFAULT)
Warning: Property .step = 1 (DEFAULT)
Warning: Property .from = 0 (DEFAULT)
Warning: Property .until = 9223372036854775807 (DEFAULT)
Warning: Property control.ao.accuracy = -1.0 (DEFAULT)
Warning: Property control.ao.step = 1 (DEFAULT)
Warning: Property control.ao.from = 0 (DEFAULT)
Warning: Property control.ao.until = 9223372036854775807 (DEFAULT)
Warning: Property include.control.dnet.init = null (DEFAULT)
Warning: Property order.control.dnet.init = null (DEFAULT)
Warning: Property control.dnet.maxsize = 2147483647 (DEFAULT)
Warning: Property control.dnet.minsize = 0 (DEFAULT)
Warning: Property control.dnet.step = 1 (DEFAULT)
Warning: Property control.shf.step = 1 (DEFAULT)
Warning: Property control.shf.from = 0 (DEFAULT)
Warning: Property control.shf.until = 9223372036854775807 (DEFAULT)
才疏学浅,研究不深!先写了这么多,等再研究了,再写点。。。。。。。。。。