Flame ---- chapter 4

本章研究的是Tomcat中的Digester。

Digester是Tomcat中处理xml的一种框架,Digester将xml与实体对象映射,并能建立对象之前的关系,在Tomcat源码中有比较广泛的使用(Tomcat6)。

Digester内部是由一系列规则Rule制定,Rule定义了解析标签时执行的动作。例如

digester.addSetNext("Server/Service/Connector/Listener",
                            "addLifecycleListener",
                            "org.apache.catalina.LifecycleListener");

上面这个规则定义:遇到Server/Service/Connector/Listener这个标签,执行一个SetNextRule,SetNextRule定义的规则如下:从digester内部堆栈中取出(注意不是弹出)两个元素, 然后调用位置靠底的那个元素的addLifecycleListener,参数类型为org.apache.catalina.LifecycleListener,参数为靠顶的那个元素。

参考SetNextRule的源码:

public class SetNextRule extends Rule {
    public SetNextRule(Digester digester, String methodName) {
        this(methodName);
    }

    public SetNextRule(Digester digester, String methodName, String paramType) {
        this(methodName, paramType);
    }

    public SetNextRule(String methodName) {
        this(methodName, null);
    }

    public SetNextRule(String methodName, String paramType) {
        this.methodName = methodName;
        this.paramType = paramType;
    }

    protected String methodName = null;
    protected String paramType = null;
    protected boolean useExactMatch = false;

    public boolean isExactMatch() {    
        return useExactMatch;
    }
    
    public void setExactMatch(boolean useExactMatch) {
        this.useExactMatch = useExactMatch;
    }

    public void end() throws Exception {
        Object child = digester.peek(0);
        Object parent = digester.peek(1);
        if (digester.log.isDebugEnabled()) {
            if (parent == null) {
                digester.log.debug("[SetNextRule]{" + digester.match +
                        "} Call [NULL PARENT]." +
                        methodName + "(" + child + ")");
            } else {
                digester.log.debug("[SetNextRule]{" + digester.match +
                        "} Call " + parent.getClass().getName() + "." +
                        methodName + "(" + child + ")");
            }
        }

        // Call the specified method
        IntrospectionUtils.callMethod1(parent, methodName,
                child, paramType, digester.getClassLoader());
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("SetNextRule[");
        sb.append("methodName=");
        sb.append(methodName);
        sb.append(", paramType=");
        sb.append(paramType);
        sb.append("]");
        return (sb.toString());
    }
}

你可能感兴趣的:(Flame ---- chapter 4)