PTF3 配置管理使用手册

文档编号:PT-TR-configuration

 

 

 

PTF3 配置管理使用手册

PTF3 Configuration Architect Document

   

V3.0

 

 

 

 

 

 

 

初始版发行时间: 2004/06/01

 

 

 

 

 

 

 

 

 

蓬天信息系统(北京)有限公司

技术研发部


目录

基本信息... 3

功能特点... 4

技术背景... 4

接口范围... 4

API说明... 5

注意事项... 5

开发和测试实例... 5

基于HashMap的配置数据容器... 5

基于XML文件的配置管理... 6

AbstractManagerAgent实例(Command配置为例) 6

AbstractMappingLoad实例(Command配置为例) 8

AbstractParse实例(Command配置为例) 11

基于Properties文件的配置管理... 12

AbstractManagerAgent实例(Velocity配置为例) 12

AbstractMappingLoad实例(Velocity配置为例) 13

AbstractParse实例(Velocity配置为例) 15

测试实例... 17

 


 

基本信息

文档描述信息:

文件名:

PTF3 Configuration规范的使用文档

最新版本:

V3.0

文档创建者:

蓬天公司技术研发部

文档维护者:

组织:蓬天公司技术研发部

成员:原力、陈永辉,任民

文档评审者:

蓬天公司技术研发部、西安地税项目组

定稿日期:

2004-06-01

文档目标:

此文档从理论根据,概念,特征,实例的角度描述了PTF3 Cofiguration的技术细节以及开发时的接口和使用

 

文档修改摘要:

版本

日期

修改描述

作者

V3.0

2004-06-01

PTF3 Cofiguration规范的使用文档

原力

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


PTF ConfigurationPTF3的新核心,其使用了插件技术进行Configuration的扩展和管理,Configuration主要包含:

一个全局注册表:

Registery

三个父类:

AbstractMappingAgent

AbstractMappingLoad

AbstractMappingParse

一个容器规范:

xxxxable extends HashMap

通过三个父类的继承和实现,以及自定义Configuration数据容器,可以针对相应的配置项管理到注册表中,同时提供有针对性的查询和访问方式。

 

 

功能特点

1、 Configuration的数据由注册表来管理

2、 Configuration是单子访问的,其常驻内存

3、 Configuration由核心CfgMapping管理器来管理扩展的配置插件

4、 Configuration支持对异型配置文件的管理方式,例如xmlpropertiestxt等文件

5、 Configuration容许对解析文件的完整性校验,对XML文件有效

6、 Configuration支持对各种存储方式的文件的访问,例如目录,文件,压缩文件,流等

7、 Configuration可以使用一个树状结构的文件系统来填充具体的Mapping容器,例如一个Jar中文件的文件树

8、 Configuration中存储的单个元素必须是唯一的

9、 Configuration提供可以扩展的注册表查找方式

技术背景

Configuration是一个开放的架构体系所必须的组件,也可以说Configuration是一个架构体系的核心组件,这是因为在开放的机构中,各种组件相互直接都相对独立,它们实际是使用一直可配置的Configuration管理器来相互作用。这就是Configuration的核心所在:组件一个可扩展的由配置器组织的框架结构。

ConfigurationPTF2中使用了曾经使用过两种技术实现:

1.      Mapping容器 这个方式是在内存中管理一个单子的Mapping,相当于注册表,在此注册表中按Domain存放注册项,这个概念的模型是完善的,但在实现中,由于使用了硬编码,造成Configuration的扩展和访问困难,Configuration被局限在一个狭小的应用层面上。

2.      JMX ConfigurationPTF2中还完整的使用JMX实现了符合JMX规范的Configuration,这种方式虽然可以实现动态的管理配置对象的各种属性,但由于其管理方式和应用的组件较多而放弃

3.      现在Configuration的实际采用了Mapping容器模式,在实现上,分离了注册表,解析器底层,和Domain容器这个几个层面,同时实现了一种自我管理的插件模式的Configuration管理器

接口范围

一个全局注册表:

Registery: 注册表是一个全局的单子容器,其需要在启动时进行初始化

三个父类:

AbstractManagerAgent: ConfigurationManager Agent的抽象类

Manager AgemtConfiguration的主控制器,从指定的

Configuration 注册相应类型Map项中获得指定的属性.

AbstractMappingLoad: ConfigurationMapping解析的Load程序接口

本程序支持以下方法的文件访问.

在压缩文件中所有文件.

在物理目录中的所有文件.

单独文件.

单独文件流

AbstractParse: Configuration进行配置或外部数据解析的抽象类

一个容器规范:

xxxxable extends HashMap: 是继承HashMap用于存放配置元素的容器,其将按照Domain注册到注册表中

API说明

(PTF3javadoccom.ptf.cfgcom.ptf.mapping包部分)

注意事项

1xxxable必须继承HashMapserializable

2、对Configuration的访问必须使用REGISTRY_NAME=”xxxxx”来声明访问注册表的Domain,不进行声明回出现ClassCastException异常

3、对于具体的Agent,用户可以自定义配置元素的查询方法,用于自定义环境

4、多个Agent可以用于解析一个XML的各个部分,也就是说,不是一种类型的XML对于一个AgentAgent是按照逻辑类型分类的,而XML是实际的数据存储类

开发和测试实例

基于xml文件的配置管理,需要具体的解析过程,这是因为xml文件是一个复杂的结构文档。必须按照用户自定义的需求进行具体解析。

多个Agent可以用于解析一个XML的各个部分,也就是说,不是一种类型的XML对于一个AgentAgent是按照逻辑类型分类的,而XML是实际的数据存储类

基于HashMap的配置数据容器

/**

 * Command Config数据容器,继承了HashMap并实现了Serializable接口

 */

public class CmdConfigable

    extends HashMap

    implements Serializable

{

    /** CmdConfigable对象的构造器 */

    public CmdConfigable()

    {

    }

 

    /**

     * 根据名称获得Command Config

     *@param name  参数描述

     *@return      the SqlNamedQuery value of sqlNamedQuery.

     */

    public CommandsConfig getCommandsConfig(String name)

    {

        return (CommandsConfig)this.get(name);

    }

 

    /**

     * 向容器中新增Command Config

     *@param name            新增属性 CmdConfig的值

     *@param cmdcfg          新增属性 CmdConfig的值

     */

    public void addCmdConfig(String name, CommandsConfig cmdcfg)

    {

        this.put(name, cmdcfg);

    }

 

    /**

     * 新增 CommandsConfig属性到对象 CmdConfigable object

     *

     *@param name     新增属性 CommandsConfig的值

     *@param form     新增属性 CommandsConfig的值

     *@param cmdlist  新增属性 CommandsConfig的值

     */

    public void addCommandsConfig(String name, String form, List cmdlist)

    {

        CommandsConfig cfg = new CommandsConfig();

 

        cfg.setName(name);

        cfg.setFormClassName(form);

        cfg.setCommandList(cmdlist);

    }

}

基于XML文件的配置管理

AbstractManagerAgent实例(Command配置为例)

/**

 * Class描述 CmdConfigManagerAgentPTF Configuration AbstractManagerAgent的子类.<BR>

 * CmdConfigManagerAgent完成管理Command Config配置数据到注册表的操作,并提供查询方法

 */

public class CmdConfigManagerAgent

    extends AbstractManagerAgent

{

    /**

     * 属性描述  Command Config数据容器

     */

    private CmdConfigable cfgable = null;

    /**

     * 属性描述 Log实例

     */

    private final static Logger log = Logger.getLogger(CmdConfigManagerAgent.class);

 

    /** CmdConfigManagerAgent对象的构造器 */

    public CmdConfigManagerAgent()

    {

        super();

    }

 

    /**

     * 获得指定Command名称的Command Config对象

     *

     *@param name        Description of the Parameter

     *@return            The property value

     */

    public CommandsConfig getCommandsConfig(String name)

    {

        cfgable = (CmdConfigable) registry.configContext.get(REGISTRY_NAME);

 

        CommandsConfig cfg = null;

 

        if (registry == null)

        {

            log.debug(" registry is null, please init registry with Registry.getRegistry() method ");

        }

        if (cfgable != null)

        {

//         log.debug(sqlable);

            cfg = cfgable.getCommandsConfig(name);

        }

        return cfg;

    }

 

    /**

     * 方法描述 调用解析配置文件接口AbstractParse及其实现CmdConfigMappingParse

     *

     *@exception MappingException  异常处理

     */

    public void parse()

        throws MappingException

    {

        AbstractParse parse = new CmdConfigMappingParse();

 

        parse.PATH = this.PATH;

        cfgable = (CmdConfigable) parse.getResult();

    }

 

    /**

     * 新增解析后的Command Config容器到注册表

     */

    public void addRegistry()

    {

        registry.addDomain(REGISTRY_NAME, cfgable);

    }

}

AbstractMappingLoad实例(Command配置为例)

/**

 * Class描述 CmdConfigMappingLoadPTF Configuration AbstractMappingLoad的子类.<BR>

 * CmdConfigMappingLoad完成解析Command Config配置动作,是具体的配置解析类

 */

public class CmdConfigMappingLoad

    extends AbstractMappingLoad

{

 

    /**

     * 属性描述 Command Config数据容器

     */

    private CmdConfigable cfgable = new CmdConfigable();

    /**

     * 属性描述 log实例

     */

    private static Logger log = Logger.getLogger(CmdConfigMappingLoad.class);

 

    /** CmdConfigMappingLoad对象的构造器 */

    public CmdConfigMappingLoad()

    {

        super();

        //声明配置文件的后缀

        descName = ".xml";

        //设置是否进行XML的有效性校验

        valid = false;

    }

 

    /**

     * 获得CmdConfigable

     *@return   the MsgMappingable value of msgable.

     */

    public CmdConfigable getCmdConfigable()

    {

        return cfgable;

    }

 

    /**

     * 方法描述 继承AbstractMappingLoadadd方法,向解析器中添加配置源,并进行解析,存入容器

     *

     *@param doc                   参数描述

     *@exception MappingException  异常处理

     */

    public void add(org.dom4j.Document doc)

        throws MappingException

    {

        //使用Dom4J进行XML的解析

        List cmdcfgs = doc.getRootElement().elements(CmdCfgContains.CMD_CFG);

 

        if (cmdcfgs != null)

        {

            for (Iterator it = cmdcfgs.iterator(); it.hasNext(); )

            {

                CommandsConfig cfg = new CommandsConfig();

                Element cmdcfg = (Element) it.next();

                String name = cmdcfg.element(CmdCfgContains.CMD_NAME).getText();

 

                cfg.setName(name);

 

                Element formel = cmdcfg.element(CmdCfgContains.CMD_FORM);

 

                if (formel != null)

                {

                    String form = formel.getText();

 

                    cfg.setFormClassName(form);

                }

 

                Element tx = cmdcfg.element(CmdCfgContains.CMD_TXDS);

                String txname = CmdCfgContains.CMD_DETXDS;

 

                if (tx != null)

                {

                    txname = tx.getText();

                    cfg.setTxDsName(txname);

                }

 

                Element cmdlist = cmdcfg.element(CmdCfgContains.CMD_LIST);

 

                if (cmdlist != null)

                {

                    Iterator cmds = cmdlist.elementIterator(CmdCfgContains.CMD);

                    List cmdits = new ArrayList();

 

                    while (cmds.hasNext())

                    {

                        Element cmd = (Element) cmds.next();

 

                        cmdits.add(cmd.getText());

                    }

                    cfg.setCommandList(cmdits);

                }

                cfgable.addCmdConfig(name, cfg);

            }

        }

    }

 

    /**

     * 方法描述 使用Dom4JDocument进行解析,本方法为伪方法

     *

     *@param doc                   参数描述

     *@exception MappingException  异常处理

     */

    public void configure(org.dom4j.Document doc)

        throws MappingException

    {

    }

}

AbstractParse实例(Command配置为例)

/**

 * Class描述 CmdConfigMappingParsePTF Configuration AbstractParse的子类.<BR>

 * CmdConfigMappingParse完成解析Command Config配置,并存储数据到CmdConfigable

 */

public class CmdConfigMappingParse

    extends AbstractParse

{

 

    /**

     * 属性描述 Command Config数据容器

     */

    private CmdConfigable cfgable;

    /**

     * 属性描述 Log实例

     */

    private final static Logger log = Logger.getLogger(CmdConfigMappingParse.class);

 

    /** CmdConfigMappingParse对象的构造器 */

    public CmdConfigMappingParse()

    {

        super();

    }

 

    /**

     * 获得CmdConfigMappingParse objectResult属性

     * 获得Command Config的所有数据

     *

     *@return   The Result value

     */

    public Object getResult()

    {

        CmdConfigMappingLoad load = new CmdConfigMappingLoad();

 

        try

        {

            String filename = this.PATH;

 

            load.addJar(filename);

            cfgable = load.getCmdConfigable();

        }

        catch (MappingException ex)

        {

            ex.printStackTrace();

        }

        return cfgable;

    }

}

基于Properties文件的配置管理

基于Properties文件的配置管理,不需要具体的解析过程,这是因为Properties工具类直接解析了Properties类型文件,其解析器在Properties工具类内部实现,所有在这种类型文件解析时,在ParseLoad中只是实现了外部传入数据的类型定义和流处理,而没有具体的解析过程.

AbstractManagerAgent实例(Velocity配置为例)

/**

 * Class描述 VcManagerAgentPTF Configuration AbstractManagerAgent的子类.<BR>

 * VcManagerAgent完成管理velocityProperties的配置数据到注册表的操作,并提供查询方法

 */

public class VcManagerAgent

    extends AbstractManagerAgent

{

    /**

     * 属性描述 Velocity数据容器

     */

    private Velocityable vcable = null;

    /**

     * 属性描述 Log实例

     */

    private final static Logger log = Logger.getLogger(VcManagerAgent.class);

 

    /** VcManagerAgent对象的构造器 */

    public VcManagerAgent()

    {

        super();

    }

 

    /**

     * 从指定的名称中获得Velocity的指定Properties

     *

     *@param name        Description of the Parameter

     *@return            The property value

     */

    public Properties getVelocity(String name)

    {

        vcable = (Velocityable) registry.configContext.get(REGISTRY_NAME);

        if (registry == null)

        {

            log.debug(" registry is null, please init registry with Registry.getRegistry() method ");

        }

 

        Properties props = null;

 

        if (vcable != null)

        {

//         log.debug(sqlable);

            props = vcable.getProps(name);

        }

        return props;

    }

 

    /**

     * 方法描述 什么AbstractParse接口的具体实现,并进行解析

     *

     *@exception MappingException  异常处理

     */

    public void parse()

        throws MappingException

    {

        AbstractParse parse = new VcMappingParse();

 

        parse.PATH = this.PATH;

        vcable = (Velocityable) parse.getResult();

    }

 

    /**

     * 增加解析后的数据容器到注册表

     */

    public void addRegistry()

    {

        registry.addDomain(REGISTRY_NAME, vcable);

    }

}

AbstractMappingLoad实例(Velocity配置为例)

/**

 * Class描述 VcMappingLoadPTF Configuration AbstractMappingLoad的子类.<BR>

 * VcMappingLoad完成解析Velocity配置动作,是具体的配置解析类

 */

public class VcMappingLoad

    extends AbstractMappingLoad

{

 

    /**

     * 属性描述 Velocity数据容器

     */

    private Velocityable vcable = new Velocityable();

    /**

     * 属性描述 Log实例

     */

    private static Logger log = Logger.getLogger(VcMappingLoad.class);

    /**

     * 属性描述 默认属性名称

     */

    private final static String DEFAULT_NAME = "default";

 

    /** VcMappingLoad对象的构造器 */

    public VcMappingLoad()

    {

        super();

        //声明配置文件后缀

        descName = ".properties";

    }

 

    /**

     * 获得Velocity数据容器

     *@return   the MsgMappingable value of msgable.

     */

    public Velocityable getVelocityable()

    {

        return vcable;

    }

 

    /**

     * 方法描述 增加properties对象作为数据源,名称伪默认属性

     *

     *@param props                 参数描述

     *@exception MappingException  异常处理

     */

    public void add(Properties props)

        throws MappingException

    {

        vcable.addProps(DEFAULT_NAME, props);

    }

 

    /**

     * 方法描述 增加指定名称的properties对象作为数据源

     *

     *@param name                  参数描述

     *@param props                 参数描述

     *@exception MappingException  异常处理

     */

    public void add(String name, Properties props)

        throws MappingException

    {

        vcable.addProps(name, props);

    }

 

    /**

     * 方法描述 Dom4J对象作为数据源,本方法为伪方法

     *

     *@param doc                   参数描述

     *@exception MappingException  异常处理

     */

    public void add(org.dom4j.Document doc)

        throws MappingException

    {

    }

 

    /**

     * 方法描述  使用Dom4JDocument进行解析,本方法为伪方法

     *

     *@param doc                   参数描述

     *@exception MappingException  异常处理

     */

    public void configure(org.dom4j.Document doc)

        throws MappingException

    {

    }

}

AbstractParse实例(Velocity配置为例)

/**

 * Class描述 VcMappingParsePTF Configuration AbstractParse的子类.<BR>

 * VcMappingParse完成解析Velocity配置,并存储数据到Velocityable

 */

public class VcMappingParse

    extends AbstractParse

{

 

    /**

     * 属性描述 Velocity数据容器

     */

    private Velocityable vcable;

    /**

     * 属性描述 Log实例

     */

    private final static Logger log = Logger.getLogger(VcMappingParse.class);

 

    /** VcMappingParse对象的构造器 */

    public VcMappingParse()

    {

        super();

    }

 

    /**

     * 获得VcMappingParse objectResult属性

     *

     *@return   The Result value

     */

    public Object getResult()

    {

        VcMappingLoad load = new VcMappingLoad();

 

        try

        {

            String filename = this.PATH;

 

//         log.debug(filename);

            if (filename.endsWith("properties"))

            {

                load.addProps(filename);

            }

            else if (filename.endsWith(".jar"))

            {

                load.addJar(filename);

            }

            vcable = load.getVelocityable();

        }

        catch (MappingException ex)

        {

            ex.printStackTrace();

        }

        return vcable;

    }

}

测试实例

Configuration的测试比较简单,主要是选择具体的Agent和对象,并按照具体的查询方法操作即可,注意,一定要声明REGISTRY_NAME注册名

/**

 *  Configuration的测试程序,测试Configuration的初始化,和各种Agent的访问过程

 *

 *@author     原力

 *@created    20031126

 */

public class CfgTest

{

    /**

     *  本测试程序的主执行器方法

     *

     *@param  args  The command line arguments

     */

    public static void main(String[] args)

    {

        CfgTest cfgtest = new CfgTest();

        cfgtest.parse();

    }

 

    /**

     *  Cfgable数据容器的测试

     */

    public void cfgable()

    {

        Cfgable map = new Cfgable();

        Config conf = new Config();

        conf.setAlias("test");

        conf.setPath("./test");

        map.addCfg("com.ptf.cfg.Test.class", conf);

        System.out.println(map.getAlias("com.ptf.cfg.Test.class"));

    }

 

    /**

     * 测试Configuration的初始化,和各种Agent的访问过程

     */

    public void parse()

    {

        //测试Configuration的初始化

        ConfigurationFactory factory = ConfigurationFactory.getFactory();

        factory.initRegistry();

        //PTF2中的MsgManagerAgent的访问过程

        com.ptf.mapping.msgptf2.agent.MsgManagerAgent agento = new com.ptf.mapping.msgptf2.agent.MsgManagerAgent();

        //声明注册名

        agento.REGISTRY_NAME = "msgptf2mapping";

        //打印输出测试结果

        System.out.println("ptf2 message<-" + agento.getNamedMessage("dossier_date_invalid"));

        //PTF3中的MsgManagerAgent的访问过程

        com.ptf.mapping.msg.agent.MsgManagerAgent agent = new com.ptf.mapping.msg.agent.MsgManagerAgent();

        //声明注册名

        agent.REGISTRY_NAME = "msgmapping";

        //打印输出测试结果

        System.out.println("message<-" + agent.getNamedMessage("SystemException"));

        //PTF3中的SqlManagerAgent的访问过程

        com.ptf.mapping.sql.agent.SqlManagerAgent sqlagent = new com.ptf.mapping.sql.agent.SqlManagerAgent();

        //声明注册名

        sqlagent.REGISTRY_NAME = "sqlmapping";

        //打印输出测试结果

        System.out.println("sql<-" + sqlagent.getSqlQuery("acc.hello"));

        //PTF2中的SqlManagerAgent的访问过程

        com.ptf.mapping.sqlptf2.agent.SqlManagerAgent sqlptf2agent = new com.ptf.mapping.sqlptf2.agent.SqlManagerAgent();

        //声明注册名

        sqlptf2agent.REGISTRY_NAME = "sqlptf2mapping";

        //打印输出测试结果

        System.out.println("ptf2 sql<-" + sqlptf2agent.getSqlQuery("mytest1"));

        //PTF3中的VcManagerAgent的访问过程

        VcManagerAgent vc = new VcManagerAgent();

        //声明注册名

        vc.REGISTRY_NAME = "velocity";

        //打印输出测试结果

        System.out.println("velocity<-" + vc.getVelocity("velocity"));

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值