在sphinx4的属性管理中,PropertySheet的作用实在是太重大了,以至于不得不单独进行介绍。
先来看一下PropertySheet的成员变量:
// 保存了属性的注解信息
private Map<String, S4PropWrapper> registeredProperties = new HashMap<String, S4PropWrapper>();
// 保存了component节点所有的属性,name为属性名称,value为属性值
private Map<String, Object> propValues = new HashMap<String, Object>();
// 保存了component节点所有的属性
private Map<String, Object> rawProps = new HashMap<String, Object>();
// 配置管理器
private ConfigurationManager cm;
// component节点的实例对象
private Configurable owner;
// component节点的实例对应的Class
private Class<? extends Configurable> ownerClass;
// component节点的实例名称
private String instanceName;
PropertySheet的构造函数:
public PropertySheet(Class<? extends Configurable> confClass, String name, ConfigurationManager cm, RawPropertyData rpd) {
ownerClass = confClass;
this.cm = cm;
this.instanceName = name;
parseClass(confClass);
setConfigurableClass(confClass);
// now apply all xml properties
Map<String, Object> flatProps = rpd.flatten(cm).getProperties();
rawProps = new HashMap<String, Object>(rpd.getProperties());
for (String propName : rawProps.keySet())
propValues.put(propName, flatProps.get(propName));
}
}
构造函数中调用了 parseClass(confClass)方法,parseClass扫描该component中的所有成员字段,然后通过扫描到的字段来获取字段上面的注解信息,最后用字段作为key,注解信息作为value构造一个map。奇怪的是这个函数返回该component所有的字段的注解信息,构造函数中并没有使用这个Map值。
接着调用setConfigurableClass方法,setConfigurableClass中调用了上面的parseClass,并将返回值保存起来了,这样就得到了所有的字段和注解信息:
final Map<Field, Annotation> classProps = parseClass(ownerClass);
然后对classProps进行遍历,调用
registerProperty(propertyName, new S4PropWrapper((Proxy)entry.getValue()));
前面介绍过S4PropWrapper实际上是对注解的一个包装,为了便于理解,就认为S4PropWrapper是一个注解类。
再看下registerProperty方法:
private void registerProperty(String propName, S4PropWrapper property) {
if (property == null || propName == null)
throw new InternalConfigurationException(getInstanceName(), propName, "property or its value is null");
if (!registeredProperties.containsKey(propName))
registeredProperties.put(propName, property);
if (!propValues.containsKey(propName)) {
propValues.put(propName, null);
rawProps.put(propName, null);
}
}
这个方法的作用就是把之前的字段注解信息又保存到了 registeredProperties 这个Map中,同时检查了一下如果不在propValues和rawProps中的话,则添加进去,value设为null。
再来看一下构造函数的剩余部分:
Map<String, Object> flatProps = rpd.flatten(cm).getProperties();
rawProps = new HashMap<String, Object>(rpd.getProperties());
for (String propName : rawProps.keySet())
propValues.put(propName, flatProps.get(propName));
这里又把rawProps的值添加到propValues中,这样rawProps和propValues就都保存了属性的键值对信息了。