1 / 30

OGNL-training (30 minutes)

OGNL-training (30 minutes). Xiang yingbing 2011-05-15. Content List. 1. Express Language (EL) 在 J2EE(MVC) 中的应用 2. OGNL 2.1 History 2.2 Syntax 2.3 Expressions 3. OGNL 与 ANTLR /JavaCC ( Java Compiler Compiler ) 3.1 OGNL 源代码是怎么生成出来的 3.2 AMS 和 ANTLR/JSMIPARSER 4. OGNL examples

alden
Download Presentation

OGNL-training (30 minutes)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. OGNL-training(30 minutes) Xiang yingbing2011-05-15

  2. Content List 1. Express Language (EL)在J2EE(MVC)中的应用 2. OGNL 2.1 History 2.2 Syntax 2.3 Expressions 3. OGNL与ANTLR /JavaCC(Java Compiler Compiler ) 3.1 OGNL源代码是怎么生成出来的 3.2 AMS和ANTLR/JSMIPARSER 4. OGNL examples 4.1 ArrayCreationTest 4.2 ognl\src\test\java\org\ognl\test 4.3 ArithmeticAndLogicalOperatorsTest.java

  3. 1. Express Language (EL)在J2EE(MVC)中的应用 (a)model

  4. (b)controller

  5. (c)view

  6. 说明: • view中,#{menuMBean.getMenu(topicQueryMBean.mid).getName()} 就是个EL表达式。 • Controller中,@ManagedBean(name=“menuMBean”)中“menuMBean”是个简单的EL表达式。 OGNL最开始作为MVC架构中UI组件和Controllers之间的一种关联方法,利用属性名字进行关联。 • JSF/JSP页面如何显示给用户(web browser) • Web browser发送request(list.xhtml)到web container • Web container 读取list.xhtml文件,把所有的#{…}用适当的内容替换掉。 这个替换的过程就是对EL表达式的解析过程。 • 替换完毕后, Web container 把得到的html页面发送回web browser。 • 不同的web container/WEB FRAMEWORK采用不同的EL实现。 • Struts采用OGNL。 • JSF: sun EL(jsf-impl.jar\com\sun\faces\el ) • JBossEL: http://anonsvn.jboss.org/repos/jboss-el

  7. 2. OGNL • OGNL是Object-Graph Navigation Language的意思;它是一个表达式语言,用于获取Java对象的属性,或者为之设置属性。使用相同的表达式来读取属性或者设置属性。 • 主页OGNL 旧的主页: http://www.ognl.org/ [现在已经不可访问]OGNL 新的主页: http://www.opensymphony.com/ognl/OGNL由OpenSymphony开发,该公司其它产品 • WebWork • Quartz • OSCache • OSWorkflow • SiteMesh • Compass • OGNL • Tonic • XWork • OSUser • PropertySet • Clickstream • OSCore

  8. 文档Language Guide (PDF) • 下载cvs sourcecode: http://svn.opensymphony.com/svn/ognl/官方maven下载:http://maven.opensymphony.com/opensymphony/jars/ognl-2.6.10-javadoc.jar 15-Feb-2007 10:53 321K ognl-2.6.10-sources.jar 15-Feb-2007 10:53 198K ognl-2.6.10.jar 15-Feb-2007 10:53 164K ognl-2.6.11-javadoc.jar 18-Feb-2007 07:47 321K ognl-2.6.11-sources.jar 18-Feb-2007 07:47 198K ognl-2.6.11.jar 18-Feb-2007 07:47 164K • 应用(http://en.wikipedia.org/wiki/OGNL) • WebWork and its successor Struts2 • Tapestry • Spring Web Flow • Apache Click • NReco (.NET integration framework for lightweight MDD) • op4j (op4j-ognl extension) - Java fluent interface implementation. • MyBatis - SQL mapper framework • The Thymeleaf Template Engine - A Java XML/XHTML/HTML5 template engine • Unitils - Modular Testing framework for Java

  9. 2.1 History OGNL最开始作为MVC架构中UI组件和Controllers之间的一种关联方法,利用属性名字进行关联。随着对更复杂关联的需求的日益增加,Drew Davidson创建了一个他称为KVCL的东西,用于Key-Value Coding Language,这是Luke Blanshard鼓动的。Luke然后用ANTLR重新实现了该语言,取了个新名字,这次由Drew鼓动的,这就是现在这种状态。后来Luke又用 JavaCC重新实现了该语言。所有代码的进一步维护都由Drew完成 (Luke进行spiritual指导)。

  10. 2.2 Syntax • 简单的OGNL表达式非常简单。该语言带有各种features,变得非常丰富,但是,通常情况下,你不需要关心该语言的复杂部分:the simple cases have remained that way。比如说,要访问一个对象的name属性,OGNL表达式就是name。要得到通过headline属性返回的对象的text属性,OGNL表达式 就是headline.text。 • OGNL表达式的基本单元是导航链(navigation chain),通常就叫做链“chain”。最简单的chains包含下面几部分:

  11. 举例:name.toCharArray()[0].numericValue.toString() • This expression follows these steps to evaluate: • extracts the name property of the initial, or root, object (which the user provides to OGNL through the OGNL context) • calls the toCharArray() method on the resulting String • extracts the first character (the one at index 0) from the resulting array • gets the numericValue property from that character (the character is represented as a Character object, and the Character class has a method called getNumericValue()). • calls toString() on the resulting Integer object. The final result of this expression is the String returned by the last toString() call.

  12. 2.3 Expressions • EL表达式遵守的格式(语法) 下面先列举一些简单的例子,以及一些重要的例子。 完整内容请参见Language Guide (PDF)的第四章 • 简单的例子: array.length: 获取数组的长度 array[0]: 读取数组的第一个元素 array.length = array["length"] = array["len" + "gth"] session.attribute[“foo”] :从map中获取某key对应的值

  13. 2.3.1 Variable References: #this • OGNL在表达式的每个点号(.)那里存储该点号(.)之前的EL表达式的值,该值通过#this来获取。比如:listeners.size().(#this > 100? 2*#this : 20+#this) 第二个点(.)那里,存储的值为"listeners.size()",接着,在括号(...)内部,用#this来指向这个值,也就是"listeners.size()"。整个表达式的结果:如果listeners.size()大于100,那么为2*(listeners.size());否则,整个EL表达式的值为20+(listeners.size())

  14. 2.3.2 Chained Subexpressions • 如果OGNL表达式中,某个点号(.)后面跟了个括号表达式(...),比如:headline.parent.(ensureLoaded(), name)那么,这个点号(.)之前的所有表达式(这里为headline.parent)的值被传入括号表达式内,作为该括号表达式的root object。上例(ensureLoaded(), name)等价于:(a) rootObj1=headline.parent(b) 调用rootObj1.ensureLoaded()方法 【方法调用,可以用来做一些动作!比如赋值,检测,日志...】(c) 然后把rootObj1.name作为整个表达式的值。还可以按照这种模式,做很长的链接:obj1.obj2.(methodOfObj2(), propertyOfObj2).p1.p2.obj3.(methodOfObj3(), propertyOfObj3)另外一个例子:obj1.(obj2).(obj3).(obj4).(obj5)  等价于:obj1.obj2.obj3.obj4.obj5

  15. 其余内容,自己研究。

  16. 3. OGNL与ANTLR/JavaCC(Java Compiler Compiler ) • 前面History中,我们提到: Luke然后用ANTLR重新实现了该语言,取了个新名字,这次由Drew鼓动的,这就是现在这种状态。后来Luke又用 JavaCC重新实现了该语言。 • JavaCC/ANTLR Java Compiler Compiler [tm] (JavaCC [tm]) is the most popular parser generator for use with Java [tm] applications. A parser generator is a tool that reads a grammar specification and converts it to a Java program that can recognize matches to the grammar. In addition to the parser generator itself, JavaCC provides other standard capabilities related to parser generation such as tree building (via a tool called JJTree included with JavaCC), actions, debugging, etc. JavaCC是一种grammar parser generator:语法解析器的生成器。也就是用于生成语法解析器。 ANTLR也是类似的工具 很多语言,比如Java,HTML,C/C++,OGNL,MIB,都遵循一定的格式。那么,就可以用ANTLR/JAVACC为这些语言生成parser以解析这些语言。

  17. 3.1 OGNL源代码是怎么生成出来的 • ognl-2.6.9-sources\ognl\src\java\ognl • ArrayElementsAccessor.java • ArrayPropertyAccessor.java • ASTAdd.java • … • ognl.jjt • ognl.jj • ognl-2.6.9-sources\ognl\build.xml

  18. 用JAVACC生成OGNL的Compiler(OGNL源代码)过程: • <java classname=“org.javacc.jjtree.Main”…> 根据ognl.jjt文件生成一些java文件和ognl.jj文件 • <java classname=“org.javacc.parser.Main” …>根据ognl.jj再生成一些java文件。 • 生成的Java文件可以用来读取并解析符合OGNL语言规范的EL表达式。也就是说,这些JAVA文件组成OGNL compiler。比如a+b,OGNL解析它的时候,就能理解该表达式的意思是a加上b。 • 如果想要计算EL表达式的值,或者根据EL表达式为java对象设置值,那么需要手工加入(OGNL开发人员已经完成)一些代码,一边OGNL解析完EL表达式的时候,接着执行get/set。

  19. 3.2 AMS和ANTLR/JSMIPARSER 【扩展内容,快速提示】 • AMS使用了jsmiparser解析MIB,而jsmiparser采用了antlr语法解析器生成器。通OGNL一样, jsmiparser也可以用JAVACC实现。 • JSMIPARSER读取MIB文件 9.0.10\basic.fttbmdu.1.2\axs-fttbmdu-mobject-plugin (a) \src\main\resources\META-INF\mobject-mibs.xml 下面这个bean指示哪些mib文件名字(路径)被读入bean id="mibFileNames"

  20. (b)mobject-beans.xml 用SmiDefaultParser.parse解析mib文件,得到的结果: bean id="mib"

  21. 4.OGNL examples • 先把ognl-2.6.9-sources\ognl导入eclipse,然后运行ognl-2.6.9-sources\ognl\src\test\java\org\ognl\test中的test cases。 • 先看看改造的:

  22. 4.1 ArrayCreationTest import ognl.ExpressionSyntaxException; … public class ArrayCreationTest { private static Root ROOT = new Root(); private static Object[][] TESTS = { // Array creation { ROOT, "new String[] { \"one\", \"two\" }", new String[] { "one", "two" } }, { ROOT, "new String[] { 1, 2 }", new String[] { "1", "2" } }, //… };

  23. 接上… public static void main(String[] args) throws Exception { String expressionString = ""; Object root; for(int i=0;i<TESTS.length;i++){ try{ root = TESTS[i][0]; expressionString = (String)TESTS[i][1]; SimpleNode expression = (SimpleNode)Ognl.parseExpression(expressionString); OgnlContext context = new OgnlContext(); //OgnlContext context = (OgnlContext)Ognl.createDefaultContext(null); Object expressionvalue = Ognl.getValue(expression, context, root);//表达式值 Object expectedvalue = TESTS[i][2];//期望值 System.out.println(expressionString+" test-->" + OgnlTestCase.isEqual(expressionvalue, expectedvalue)); }catch(Exception e){ if(e.getClass() == ExpressionSyntaxException.class){ System.out.println(expressionString+" test-->This is the expected Exception"); }else{ e.printStackTrace(); } } } } }

  24. 4.2 ognl\src\test\java\org\ognl\test • 所有测试classes的定义结构相同,都扩展org.ognl.test.OgnlTestCase最终都是验证:表达式是否和某个期望值相同。运行过程:(a)//Root             root= new Root();Root             root= null;//(b)    OgnlContext context = (OgnlContext)Ognl.createDefaultContext(null);(c)SimpleNode expression = (SimpleNode)Ognl.parseExpression(expressionString);(d)assertTrue(isEqual(Ognl.getValue(expression , context, root), expectedResult));  

  25. 4.3 ArithmeticAndLogicalOperatorsTest.java public class ArithmeticAndLogicalOperatorsTest extends OgnlTestCase { private static Object[][] TESTS = { // Double-valued arithmetic expressions { "-1d", new Double(-1) }, { "+1d", new Double(1) }, { "--1f", new Float(1) }, { "2*2.0", new Double(4) }, { "5/2.", new Double(2.5) }, { "5+2D", new Double(7) }, { "5f-2F", new Float(3) }, { "5.+2*3", new Double(11) }, { "(5.+2)*3", new Double(21) }, // BigDecimal-valued arithmetic expressions { "-1b", new BigDecimal(-1) }, { "+1b", new BigDecimal(1) }, { "--1b", new BigDecimal(1) }, ... ... { "#y + \"1\"", "11" }, { "\"1\" + #y", "11" } }; ...

  26. 这里(a) root为空,(b) context为context = (OgnlContext)Ognl.createDefaultContext(null);        context.put("x", "1");        context.put("y", new BigDecimal(1));(c)表达式TESTS [i][0]的值,总是等于期望值TESTS [i][1] 可以到源代码中看其它例子,设计web container/ams server的时候,这些例子非常有用。

  27. The END

More Related