Author: simonetripodi
Date: Wed Mar 2 21:46:40 2011
New Revision: 1076408
URL: http://svn.apache.org/viewvc?rev=1076408&view=rev
Log:
started describing the differences of Digester and Digester3
Added:
commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml (with props)
Modified:
commons/sandbox/digester3/trunk/src/site/site.xml
Modified: commons/sandbox/digester3/trunk/src/site/site.xml
URL:
http://svn.apache.org/viewvc/commons/sandbox/digester3/trunk/src/site/site.xml?rev=1076408&r1=1076407&r2=1076408&view=diff
==============================================================================
--- commons/sandbox/digester3/trunk/src/site/site.xml (original)
+++ commons/sandbox/digester3/trunk/src/site/site.xml Wed Mar 2 21:46:40 2011
@@ -31,12 +31,13 @@
</menu>
<menu name="Developers Guide">
- <item name="Core APIs" href="/guide/core.html"/>
- <item name="Plugins" href="/guide/plugins.html"/>
- <item name="Substitution" href="/guide/substitution.html"/>
- <item name="XML Rules" href="/guide/xmlrules.html"/>
- <item name="Annotations" href="/guide/annotations.html"/>
- <item name="FAQ" href="/guide/faq.html"/>
+ <item name="Core APIs" href="/guide/core.html"/>
+ <item name="Plugins" href="/guide/plugins.html"/>
+ <item name="Substitution" href="/guide/substitution.html"/>
+ <item name="XML Rules" href="/guide/xmlrules.html"/>
+ <item name="Annotations" href="/guide/annotations.html"/>
+ <item name="Digester vs. Digester3" href="/guide/dvsd3.html"/>
+ <item name="FAQ" href="/guide/faq.html"/>
</menu>
</body>
Added: commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml
URL:
http://svn.apache.org/viewvc/commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml?rev=1076408&view=auto
==============================================================================
--- commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml (added)
+++ commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml Wed Mar 2
21:46:40 2011
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<document xmlns="http://maven.apache.org/XDOC/2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/XDOC/2.0
http://maven.apache.org/xsd/xdoc-2.0.xsd">
+ <properties>
+ <title>Commons Digester | How to migrate from old Digester</title>
+ <author email="[email protected]">Commons Documentation Team</author>
+ </properties>
+ <body>
+ <section name="New Digester APIs">
+ <p>The main difference between Digester <i>1.X</i>, <i>2.X</i> and
<i>3.X</i> is that the
+ while the first follows the approach <i>"given a Digester instance, then
configure it"</i>,
+ the new Digester instead follows the opposite approach <i>"given one (or
more) configuration(s), create
+ multiple Digester instances" or "configure once, create
everywhere".</i></p>
+ <p>Why? Even if both approaches sound complementary, the core concept is
given by the assumption that every
+ Digester instance is not thread-safe, that implies that in a
multi-thread application users have often
+ to reinstantiate the Digester and reconfigure it, i.e in a Servlet:</p>
+ <source>public class EmployeeServlet extends HttpServlet {
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ Digester digester = new Digester();
+ digester.setNamespaceAware(true);
+ digester.setXIncludeAware(true);
+ digester.addObjectCreate("employee", Employee.class);
+ digester.addCallMethod("employee/firstName", "setFirstName", 0);
+ digester.addCallMethod("employee/lastName", "setLastName", 0);
+
+ digester.addObjectCreate("employee/address", Address.class);
+ digester.addCallMethod("employee/address/type", "setType", 0);
+ digester.addCallMethod("employee/address/city", "setCity", 0);
+ digester.addCallMethod("employee/address/state", "setState", 0);
+ digester.addSetNext("employee/address", "addAddress");
+
+ Employee employee = (Employee)
digester.parse(openStream(req.getParameter("employeeId")));
+ ...
+}</source>
+ <p>Nothing wrong with that approach but configuration is not reusable;
the <i>RuleSet</i>
+ interface fills in some way the reuse of configurations lack:</p>
+ <source>public class EmployeeRuleSet implements RuleSet {
+
+ public void addRuleInstances(Digester digester) {
+ digester.addObjectCreate("employee", Employee.class);
+ digester.addCallMethod("employee/firstName", "setFirstName", 0);
+ digester.addCallMethod("employee/lastName", "setLastName", 0);
+
+ digester.addObjectCreate("employee/address", Address.class);
+ digester.addCallMethod("employee/address/type", "setType", 0);
+ digester.addCallMethod("employee/address/city", "setCity", 0);
+ digester.addCallMethod("employee/address/state", "setState", 0);
+ digester.addSetNext("employee/address", "addAddress");
+ }
+
+}</source>
+ <p>then, in our sample servlet</p>
+ <source>public class EmployeeServlet extends HttpServlet {
+
+ private final RuleSet employeeRuleSet = new EmployeeRuleSet();
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ Digester digester = new Digester();
+ digester.setNamespaceAware(true);
+ digester.setXIncludeAware(true);
+
+ employeeRuleSet.addRuleInstances(digester);
+
+ Employee employee = (Employee)
digester.parse(openStream(req.getParameter("employeeId")));
+ ...
+ }
+
+}</source>
+ <p>Nothing wrong again, but:</p>
+ <ol>
+ <li>RuleSet is not really a configuration, it just sets rules to given
Digester instance;</li>
+ <li>Digester instance creation is totally delegated to clients;</li>
+ <li>Rules that match to the same pattern, need to specify this last
<i>n</i> times for how many
+ rules match, that violates the DRY principle;</li>
+ <li>Rules semantic is not intuitive, since their creation is strictly
related to
+ methods/constructors arguments.</li>
+ </ol>
+ <p>In the new Digester, <i>RuleSet</i> has been suppressed in favor of
<i>RulesModule</i></p>
+ <source>class EmployeeModule extends AbstractRulesModule {
+
+ @Override
+ protected void configure() {
+ forPattern("employee").createObject().ofType(Employee.class);
+ forPattern("employee/firstName").setBeanProperty();
+ forPattern("employee/lastName").setBeanProperty();
+
+ forPattern("employee/address")
+ .createObject().ofType(Address.class)
+ .then()
+ .setNext("addAddress");
+ forPattern("employee/address/type").setBeanProperty();
+ forPattern("employee/address/city").setBeanProperty();
+ forPattern("employee/address/state").setBeanProperty();
+ }
+
+}</source>
+ <p>Then, our sample Servlet become:</p>
+ <source>public class EmployeeServlet extends HttpServlet {
+
+ private final DigesterLoader loader = newLoader(new EmployeeModule())
+ .setNamespaceAware(true)
+ .setXIncludeAware(true);
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ Digester digester = loader.newDigester()
+
+ Employee employee =
digester.parse(openStream(req.getParameter("employeeId")));
+ ...
+ }
+
+}</source>
+
+ <p>As you can notice, the <i>RulesModule</i> implements rules via fluent
APIs,
+ making rules semantic simpler, and the effort of configuration is moved
to the startup;
+ the <i>DigesterLoader</i> indeed will analyze all the <i>RulesModule</i>
instances
+ and will be ready to create new Digester instances with pre-filled
rules.</p>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml
------------------------------------------------------------------------------
svn:keywords = Date Revision Author HeadURL Id
Propchange: commons/sandbox/digester3/trunk/src/site/xdoc/guide/dvsd3.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml