浏览 5101 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-11-27
apache 的 Digester正是利用了策略模式来解决这个问题, 当SAX产生startElement, endElement等事件的时候, 马上将事件分配给匹配的Rule。 客户端只需要注册不同的模式和它们的对应关系,剩下来的事情转发给各不同的Rule实现。 Digester最开始使用的是Struts, 使用后发现非常好且通用. Digester被提到commons.apache.org. apache Digester中 实现的Rule:ObjectCreateRule.begin代码: /** * Process the beginning of this element. * * @param attributes The attribute list of this element */ public void begin(Attributes attributes) throws Exception { // 识别类名 // Identify the name of the class to instantiate String realClassName = className; if (attributeName != null) { String value = attributes.getValue(attributeName); if (value != null) { realClassName = value; } } if (digester.log.isDebugEnabled()) { digester.log.debug("[ObjectCreateRule]{" + digester.match + "}New " + realClassName); } // 实现类并将实例放到堆栈中 // Instantiate the new object and push it on the context stack Class clazz = digester.getClassLoader().loadClass(realClassName); Object instance = clazz.newInstance(); digester.push(instance); } end代码 /** * Process the end of this element. */ public void end() throws Exception { Object top = digester.pop(); if (digester.log.isDebugEnabled()) { digester.log.debug("[ObjectCreateRule]{" + digester.match + "} Pop " + top.getClass().getName()); } } 上面start和end代码, 和SaxCatalogUnmarshaller比较可以看出, 对XML元素的对比,类实现和对内容堆栈的处理都封装出来了,客户端无需关注这些技术细节。 客户端只需要将不同的模式和不同的Rule对应的注册到Digester里,分发和实现就可以交给Digester和不同的Rule做了。 DigesterDriver.java: package benewu.gmail.study.tomcat.digester; import java.io.File; import java.net.URL; import org.apache.commons.digester.Digester; public class DigesterDriver { public static void main( String[] args ) { try { Digester digester = new Digester(); digester.setValidating( false ); //The patterns must match XML elements, based on their name and location in the document tree. //The syntax used to describe the matching patterns resembles the XPath match patterns, a little: //the pattern catalog matches the top-level <catalog> element, //the pattern catalog/book matches a <book> element nested directly inside a <catalog> element /*ObjectCreateRule: 利用默认构造函数创建类实例并且压到堆栈, *元素结束的时候会从堆栈pop出来. */ digester.addObjectCreate( "catalog", Catalog.class ); digester.addObjectCreate( "catalog/book", Book.class ); /* * BeanPropertySetterRule: 将名字属性赋值给栈顶的元素 * (Example: <page>10</page>.) */ digester.addBeanPropertySetter( "catalog/book/author", "author" ); digester.addBeanPropertySetter( "catalog/book/title", "title" ); /* * SetNextRule: pop栈顶实例并且利用定义的方法传递给下个对象实例, 通常用来将一个完整的bean插到父对象上. */ digester.addSetNext( "catalog/book", "addBook" ); digester.addObjectCreate( "catalog/magazine", Magazine.class ); digester.addBeanPropertySetter( "catalog/magazine/name", "name" ); digester.addObjectCreate( "catalog/magazine/article", Article.class ); /* * SetPropertiesRule: 将名字属性的值赋给栈顶对象. * (Typically used to handle XML constructs like <article page="10">.) */ digester.addSetProperties( "catalog/magazine/article", "page", "page" ); digester.addBeanPropertySetter( "catalog/magazine/article/headline" ); digester.addSetNext( "catalog/magazine/article", "addArticle" ); digester.addSetNext( "catalog/magazine", "addMagazine" ); URL fileURL = DigesterDriver.class.getResource("catalog.xml"); File input = new File(fileURL.getFile()); Catalog c = (Catalog)digester.parse( input ); System.out.println( c.toString() ); } catch( Exception exc ) { exc.printStackTrace(); } } } DigesterDriver 实现了和SaxCatalogUnmarshaller完全相同的功能, 但更加灵活和可扩展。 这里使用的Rule有: ObjectCreateRule, SetPropertiesRule, BeanPropertySetterRule, SetNextRule, 在代码中已经做了注释。 下节我将分析Tomcat中使用到和自己实现的部分Rule, 和典型应用。 参考: 1 The Hidden Gems of Jakarta Commons http://www.onjava.com/pub/a/onjava/2004/12/22/jakarta-gems-1.html?page=2 2 Parsing, indexing, and searching XML with Digester and Lucene http://www.ibm.com/developerworks/java/library/j-lucene/ 3 Learning and Using Jakarta Digester http://www.onjava.com/pub/a/onjava/2002/10/23/digester.html?page=1 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |