【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
配置文件都继承自XMLFileManager,需要提供readXml和writeXml方法的实现,其中每个xml读写都有深深的硬编码的烙印,这就导致了不同xml文件的读写实现都紧紧与内部数据结构耦合,因此每个xmlFileManager的读写实现都有很强的个性,导致难以从外部进行读写抽象。
在xml文件的实现类中,包含了很多成员变量,有一些基本类型(直接写标签),有一些XmLable的实现(也实现了readXml和writeXml方法,当读写这些变量时,委托他们各自的实现来进行读写),还有一些普通对象(这些对象没有实现readXml和writeXml,只是记录了一下对象里面的信息,读取的时候根据这些信息重新构造对象)
比如ConfigManager中,有成员变量(基本类型) private String resServerPath,直接在xml里面定义一个标签,然后把值写进去,有成员变量(实现了Xmlable接口)private EmbeddedTableData embeddedTableData,读写的时候直接调用embeddedTableData.readXml和writeXml,还有成员变量(普通对象)private Map styleMap = new ListMap(); key为String,value为Style,其中Style就是样式,写入的时候直接暴力记录Style里面信息,读取的时候根据这些信息重新构建Style。因为对象的读写没有一些强制的约束,所以基本上不可能从外部抽象文件读写。
基于以上原因,只能侵入配置文件内部,来逐层代理各个成员变量(这里面用ConfigHolder来进行封装,所有的读写逻辑根据代理对象的类型,由ConfigHolder来处理),这样至少可以保证配置文件类对外提供的接口不变。API提供了几个生成holder的工厂类,来生成各种holder。工厂类如下
(修改了工厂接口,不需要写property和nameSpace,property默认时成员变量的变量名,如果想自定义property,则在相应的成员变量上加注解Identifier)
package com.fr.config.holder.factory; import com.fr.config.holder.Conf; import com.fr.config.holder.impl.ColConf; import com.fr.config.holder.impl.MapConf; import com.fr.config.holder.impl.ObjConf; import com.fr.config.holder.impl.ObjectColConf; import com.fr.config.holder.impl.ObjectMapConf; import com.fr.config.holder.impl.SimConf; import java.util.Collection; import java.util.Map; /** * 包装类工厂 * http://www.finedevelop.com/pages/viewpage.action?pageId=18648778 */ public class Holders { /** * 创建一个基本类型的Holder类,只要T对象中没有成员变量ConfigHolder,就要用这个包装器 * * @param property 属性标签 * @param t 默认值 * @param nameSpace 名字空间 * @param <T> 包装的值类型 * @return 属性节点的包装 * @see Holders#simple(Object) */ @Deprecated public static <T> Conf<T> simple(String property, T t, String nameSpace) { return new SimConf<T>(property, t).setNameSpace(nameSpace); } public static <T> Conf<T> simple(T t) { return new SimConf<T>(t); } /** * 创建一个类型为T的对象的Holder,这个对象T里面会有ConfigHolder成员变量 * * @param property 属性标签 * @param t * @param type * @param nameSpace 名字空间 * @param <T> * @return 属性节点的包装 * @see Holders#obj(Object, Class) */ @Deprecated public static <T> Conf<T> obj(String property, T t, Class<T> type, String nameSpace) { return new ObjConf<T>(property, t, type).setNameSpace(nameSpace); } public static <T> Conf<T> obj(T t, Class<T> type) { return new ObjConf<T>(t, type); } /** * 创建一个类型K(基本类型)的Collection的Holder,只要对象中没有成员变量ConfigHolder,就要用这个包装器 * * @param property 属性标签 * @param collection * @param valueType * @param nameSpace 名字空间 * @param <K> * @return 属性节点的包装 * @see Holders#objCollection(Collection, Class) */ @Deprecated @SuppressWarnings("unchecked") public static <K> Conf<Collection<K>> collection(String property, Collection<K> collection, Class<K> valueType, String nameSpace) { return new ColConf(property, collection, valueType).setNameSpace(nameSpace); } @SuppressWarnings("unchecked") public static <K> ColConf<Collection<K>> collection(Collection<K> collection, Class<K> valueType) { return new ColConf(collection, valueType); } /** * 创建一个类型T的Collection的Holder,这个对象T里面会有ConfigHolder成员变量 * * @param property 属性标签 * @param collection * @param type * @param nameSpace 名字空间 * @param <T> * @return 属性节点的包装 * @see Holders#collection(Collection, Class) */ @Deprecated public static <T> ObjectColConf<Collection<T>> objCollection(String property, Collection<T> collection, Class<T> type, String nameSpace) { return new ObjectColConf<Collection<T>>(property, collection, type).setNameSpace(nameSpace); } public static <T> ObjectColConf<Collection<T>> objCollection(Collection<T> collection, Class<T> type) { return new ObjectColConf<Collection<T>>(collection, type); } public static <T> ObjectColConf<Collection<T>> objCollection(Collection<T> collection, Class<T> type, boolean order) { return new ObjectColConf<Collection<T>>(collection, type, order); } /** * 创建一个key和value均为基本类型的Map的Holder。只要K,V对象中没有成员变量ConfigHolder,就要用这个包装器,keyType和valueType均不能为空 * * @param property 属性标签 * @param map * @param keyType * @param valueType * @param nameSpace 名字空间 * @param <K> 包装的键值对中键类型 * @param <V> 包装的键值对中值类型 * @return 属性节点的包装 * @see Holders#map(Map, Class, Class) */ @Deprecated @SuppressWarnings("unchecked") public static <K, V> MapConf<Map<K, V>> map(String property, Map<K, V> map, Class<K> keyType, Class<V> valueType, String nameSpace) { return new MapConf(property, map, keyType, valueType).setNameSpace(nameSpace); } @SuppressWarnings("unchecked") public static <K, V> MapConf<Map<K, V>> map(Map<K, V> map, Class<K> keyType, Class<V> valueType) { return new MapConf(map, keyType, valueType); } /** * value是V类型的Map的Holder,这个对象V里面会有ConfigHolder成员变量 * K只能是基本类型或者字符串类型,又或者 K是一些简单的类型,这个不同的K对象可以转换成不同的String,注册K类型的ValueWriter对象,用来将K对象转换成String * 同样 也要注册K类型的ValueReader,用来从String中恢复重新构造K对象,ValueReader.registerReader, ValueWriter.registerWriter * keyType可以为空,但是map中的key只能是基本类型和String,ValueType可以为空,但是只能是复合类型。 * * @param property 属性标签 * @param map * @param keyType * @param valueType * @param nameSpace 名字空间 * @param <K> * @param <V> * @return 属性节点的包装 * @see Holders#objMap(Map, Class, Class) */ @Deprecated public static <K, V> ObjectMapConf<Map<K, V>> objMap(String property, Map<K, V> map, Class<K> keyType, Class<V> valueType, String nameSpace) { return new ObjectMapConf<Map<K, V>>(property, map, keyType, valueType).setNameSpace(nameSpace); } public static <K, V> ObjectMapConf<Map<K, V>> objMap(Map<K, V> map, Class<K> keyType, Class<V> valueType) { return new ObjectMapConf<Map<K, V>>(map, keyType, valueType); } public static <K, V> ObjectMapConf<Map<K, V>> objMap(Map<K, V> map, Class<K> keyType, Class<V> valueType, boolean ordered) { return new ObjectMapConf<Map<K, V>>(map, keyType, valueType, ordered); } }
使用规则:配置类对象中的成员变量
1.如果成员变量是基本类型,String或者JDK的内置类型(不包括集合),则使用 Conf<T> xxx = Holders.simple(t));
2.如果成员变量是Map类型,而且Map的key和value类型都是是基本类型,String类型或者JDK的内置类型(不包括集合),则使用 MapConf<K,V> xx = Holdes.map(map,keyType,valueType); keyType和ValueType需要明确指定,另外MapConf提供了一些操作map的方法,比如get,put,remove和clear。如果有个配置文件A,其中有个成员变量B是这种类型,假如需要修改Map,则需要在A中提供修改B的方法,调用MapConf修改。外部修改B,严禁使用 A.getB.put方法,remove等方法,这样只会修改内存,不会进行持久化存储。
3.如果成员变量是集合类型,而且集合中的类型是基本类型,String或者JDK的内置类型,则使用ColConf<Collection<K>> xxxx = Holders.collection(collection,valueType);
4.如果成员变量是我们报表的业务对象,那么这个成员变量需要用Conf<T> tt = Holders.obj(t,type),同样的成员变量所在类中的成员变量也需要根据其类型用 Conf来进行包装,。
5.如果成员变量是集合类型,值为报表的业务对象,那么需要 用ObjectColConf<T> ttt = Holders.objCollection();,这个ObjectColConf提供了集合操作的 add,remove,clear方法,如果修改Collection中,需要在配置类中提供修改集合的方法,委托ObjectColConf来进行修改。
6.如果成员变量是Map类型,key为基本类型,String或者JDK的内置类型(不包括集合),value是报表的业务对象,那么要使用MapConf<Map<K.V>> kkk = Holders.map(map,keytype,valueType); keytype和valueType可以为空。
注意,如果是报表的业务对象,均需要继承UniqueKey.
还有对一些复杂xmlable的包装类,(为啥还有提供呢,因为这些对象的结构复杂,涉及的类众多,会导致代理holder类层次过多,也会污染原来的业务对象,影响性能。直接包装Xmlable,委托其自身的readXml和writeXml来进行读写)
非常不推荐使用
package com.fr.config.holder.factory; import com.fr.config.holder.Conf; import com.fr.config.holder.impl.xml.XmlColConf; import com.fr.config.holder.impl.xml.XmlConf; import com.fr.config.holder.impl.xml.XmlMapConf; import com.fr.stable.xml.XMLable; import java.util.Collection; import java.util.Map; /** * http://www.finedevelop.com/pages/viewpage.action?pageId=18648778 * 这是一个不被允许使用的类,配置文件都要求以单行的形式存储到数据库中,而不能使用直接存储xml文件 * 目前的存在是属于过渡期,还有太多以前是xml格式序列化的对象没有办法一一更改 */ @Deprecated public class XmlHolders { //复杂Xmlable类型对象,其中包含其她复杂的对象,这样会影响很多其它业务对象,用这个包装器,这个包装器依赖readxml和writeXml //存储格式是 假设当前对象的父空间是config,property 是 arr ,存储格式为config.arr XXXXXX xxx是这个xmlable对象的序列化结果 @Deprecated @SuppressWarnings("unchecked") public static <T extends XMLable> Conf<T> obj(String property, T t, Class<T> clazz, String nameSpace) { return new XmlConf(property, t, clazz).setNameSpace(nameSpace); } @SuppressWarnings("unchecked") public static <T extends XMLable> Conf<T> obj(T t, Class<T> clazz) { return new XmlConf(t, clazz); } //复杂Xmlable类型对象集合,其中包含其她复杂的对象,这样会影响很多其它业务对象,用这个包装器,这个包装器依赖readxml和writeXml //存储格式是 假设当前对象的父空间是config,property 是 arr ,我会为集合中的对象随机分配一个id // 存储格式为config.arr.id XXXXXX xxx是这个xmlable对象的序列化结果 @Deprecated public static <T extends XMLable> XmlColConf<Collection<T>> collection(String property, Collection<T> t, Class<T> clazz, String nameSpace) { return new XmlColConf<Collection<T>>(property, t, clazz).setNameSpace(nameSpace); } public static <T extends XMLable> XmlColConf<Collection<T>> collection(Collection<T> t, Class<T> clazz) { return new XmlColConf<Collection<T>>(t, clazz); } //复杂Xmlable类型对象Map,其中包含其她复杂的对象,这样会影响很多其它业务对象,用这个包装器,这个包装器依赖readxml和writeXml ////存储格式是 假设当前对象的父空间是config,property 是 arr , // 存储格式为config.arr.key XXXXXX xxx是这个xmlable对象的序列化结果 //K只能是基本类型或者字符串类型,又或者 K是一些简单的类型,这个不同的K对象可以转换成不同的String,注册K类型的ValueWriter对象,用来将K对象转换成String //同样 也要注册K类型的ValueReader,用来从String中恢复重新构造K对象 @Deprecated public static <K, V extends XMLable> XmlMapConf<Map<K, V>> map(String property, Map<K, V> t, Class keyType, Class<V> clazz, String nameSpace) { return new XmlMapConf<Map<K, V>>(property, t, keyType, clazz).setNameSpace(nameSpace); } public static <K, V extends XMLable> XmlMapConf<Map<K, V>> map(Map<K, V> t, Class keyType, Class<V> clazz) { return new XmlMapConf<Map<K, V>>(t, keyType, clazz); } }
以上所有用holder封装的Map的key只能是一些基本数据类型,八种基本类型的包装类型和String类型。又或者 K是一些简单的类型,这个不同的K对象可以转换成不同的String,注册K类型的ValueWriter对象,用来将K对象转换成String,ValueWriter.registerWriter,同样 也要注册K类型的ValueReader,用来从String中恢复重新构造K对象,ValueReader.registerReader。
1 Comment
Anonymous
这个配置文件和插件开发有什么关系