Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 40198 invoked from network); 2 Mar 2011 21:47:44 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 2 Mar 2011 21:47:44 -0000 Received: (qmail 62187 invoked by uid 500); 2 Mar 2011 21:47:43 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 62130 invoked by uid 500); 2 Mar 2011 21:47:43 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 62121 invoked by uid 99); 2 Mar 2011 21:47:43 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Mar 2011 21:47:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Mar 2011 21:47:40 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id A50C02388A70; Wed, 2 Mar 2011 21:46:40 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1076408 - in /commons/sandbox/digester3/trunk/src/site: site.xml xdoc/guide/dvsd3.xml Date: Wed, 02 Mar 2011 21:46:40 -0000 To: commits@commons.apache.org From: simonetripodi@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110302214640.A50C02388A70@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 @@ - - - - - - + + + + + + + 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 @@ + + + + + Commons Digester | How to migrate from old Digester + Commons Documentation Team + + +
+

The main difference between Digester 1.X, 2.X and 3.X is that the + while the first follows the approach "given a Digester instance, then configure it", + the new Digester instead follows the opposite approach "given one (or more) configuration(s), create + multiple Digester instances" or "configure once, create everywhere".

+

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:

+ 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"))); + ... +} +

Nothing wrong with that approach but configuration is not reusable; the RuleSet + interface fills in some way the reuse of configurations lack:

+ 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"); + } + +} +

then, in our sample servlet

+ 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"))); + ... + } + +} +

Nothing wrong again, but:

+
    +
  1. RuleSet is not really a configuration, it just sets rules to given Digester instance;
  2. +
  3. Digester instance creation is totally delegated to clients;
  4. +
  5. Rules that match to the same pattern, need to specify this last n times for how many + rules match, that violates the DRY principle;
  6. +
  7. Rules semantic is not intuitive, since their creation is strictly related to + methods/constructors arguments.
  8. +
+

In the new Digester, RuleSet has been suppressed in favor of RulesModule

+ 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(); + } + +} +

Then, our sample Servlet become:

+ 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"))); + ... + } + +} + +

As you can notice, the RulesModule implements rules via fluent APIs, + making rules semantic simpler, and the effort of configuration is moved to the startup; + the DigesterLoader indeed will analyze all the RulesModule instances + and will be ready to create new Digester instances with pre-filled rules.

+
+ +
\ 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