Author: simonetripodi Date: Tue Jul 20 12:29:34 2010 New Revision: 965826 URL: http://svn.apache.org/viewvc?rev=965826&view=rev Log: added Bootstrapping and sample description
Modified: commons/sandbox/at-digester/trunk/src/java/org/apache/commons/digester/annotations/package.html Modified: commons/sandbox/at-digester/trunk/src/java/org/apache/commons/digester/annotations/package.html URL: http://svn.apache.org/viewvc/commons/sandbox/at-digester/trunk/src/java/org/apache/commons/digester/annotations/package.html?rev=965826&r1=965825&r2=965826&view=diff ============================================================================== --- commons/sandbox/at-digester/trunk/src/java/org/apache/commons/digester/annotations/package.html (original) +++ commons/sandbox/at-digester/trunk/src/java/org/apache/commons/digester/annotations/package.html Tue Jul 20 12:29:34 2010 @@ -40,10 +40,6 @@ <a href="#doc.Bootstrapping">[Bootstrapping]</a> <br /> <a href="#doc.Example">[Example: a simple RSS parser]</a> - <br /> - <a href="#doc.UserDefined">[User defined Digester annotation rules]</a> - <br /> - <a href="#doc.SPI">[Service provider interface]</a> </div> <a name="doc.Intro"></a> @@ -317,4 +313,207 @@ public @interface ObjectCreate { </tbody> </table> </body> + + <a name="doc.Bootstrapping"></a> + <h3>Bootstrapping</h3> + <p>The core of Digester annotations rules processor is the + <code>org.apache.commons.digester.annotations.DigesterLoader</code> class.</p> + + <p>A <code>org.apache.commons.digester.annotations.DigesterLoader</code> + instance is able to analyze <code>Class<?></code> graphs and builds + the relative <code>org.apache.commons.digester.RuleSet</code> to create + <code>org.apache.commons.digester.Digester</code> instances.</p> + + <p>The bootstrap sequence has been designed to be as simple as possible, + all that's needed is creating a new + <code>org.apache.commons.digester.annotations.DigesterLoader</code> instance, + plugging optionally the desired + <code>org.apache.commons.digester.annotations.spi.AnnotationRuleProviderFactory</code> and + <code>org.apache.commons.digester.annotations.spi.DigesterLoaderHandlerFactory</code>.</p> + + <p>An <code>org.apache.commons.digester.annotations.spi.AnnotationRuleProviderFactory</code> + implementation performs the creation of + <code>org.apache.commons.digester.annotations.AnnotationRuleProvider<A extends Annotation, E extends AnnotatedElement, R extends Rule></code> + instances; the default implementation is limited to create the provider + by invoking the default empty constructor of the required class, but + users are free to give their implementation if they need a more complex + factory, i.e. providers requires components that could be injected from a + context, etc. etc.</p> + + <h5>Note</h5> + <p>It is strongly descouraged caching <code>AnnotationRuleProvider</code> + instances!!!</p> + + <p>Same thing for the <code>org.apache.commons.digester.annotations.spi.DigesterLoaderHandlerFactory</code>, + which implementation performs the creation of + <code>DigesterLoaderHandler<A extends Annotation, E extends AnnotatedElement></code> + instances; the default implementation is limited to create the handler + by invoking the default empty constructor of the required class, but + users are free to give their implementation if they need a more complex + factory, i.e. providers requires components that could be injected from a + context, etc. etc.</p> + + <p>Said that, to obtain a fresh new + <code>org.apache.commons.digester.annotations.DigesterLoader</code> instance + with default factories, it is enough invoking the default empty constructor:</p> + <pre>DigesterLoader digesterLoader = new DigesterLoader();</pre> + <p>Otherwise, if users need specify theyr custom factories:</p> + <pre>DigesterLoader digesterLoader = + new DigesterLoader(new MyAnnotationRuleProviderFactory(), + new MyDigesterLoaderHandlerFactory());</pre> + + <a name="doc.Example"></a> + <h3>Example: a simple RSS parser</h3> + + <p>Let's assume there is the need to parse the following (simplified) + XML/RSS feed:</p> + + <pre><rss version="2.0"> + <channel> + + <title>Apache</title> + <link>http://www.apache.org</link> + <description>The Apache Software Foundation</description> + <language>en-US</language> + <rating>(PICS-1.1 "http://www.rsac.org/ratingsv01.html" + 2 gen true comment "RSACi North America Server" + for "http://www.rsac.org" on "1996.04.16T08:15-0500" + r (n 0 s 0 v 0 l 0))</rating> + + <image> + <title>Apache</title> + <url>http://jakarta.apache.org/images/jakarta-logo.gif</url> + <link>http://jakarta.apache.org</link> + <width>505</width> + <height>480</height> + <description>The Jakarta project. Open source, serverside java.</description> + </image> + + <item> + <title>Commons Attributes 2.1 Released</title> + <link>http://jakarta.apache.org/site/news/news-2004-2ndHalf.html#20040815.1</link> + <description>The Apache Commons team is happy to announce the release of Commons Attributes 2.1. This is the first release of the new Commons-Attributes code.</description> + </item> + + <item> + <title>Cloudscape Becomes Apache Derby</title> + <link>http://jakarta.apache.org/site/news/elsewhere-2004-2ndHalf.html#20040803.1</link> + <description>IBM has submitted a proposal to the Apache DB project for a Java-based package to be called 'Derby'.</description> + </item> + + <item> + <title>Commons BeanUtils 1.7 Released</title> + <link>http://jakarta.apache.org/site/news/news-2004-2ndHalf.html#20040802.1</link> + <description/> + </item> + + <item> + <title>Commons JXPath 1.2 Released</title> + <link>http://jakarta.apache.org/site/news/news-2004-2ndHalf.html#20040801.2</link> + <description/> + </item> + </channel> +</rss></pre> + + <p>So, let's define the Java entities and annotate them; first the <code>Channel</code> entity:</p> + + <pre>@ObjectCreate(pattern = "rss/channel") +class Channel { + + private final List<Item> items = new ArrayList<Item>(); + + @BeanPropertySetter(pattern = "rss/channel/title") + private String title; + + @BeanPropertySetter(pattern = "rss/channel/link") + private String link; + + @BeanPropertySetter(pattern = "rss/channel/description") + private String description; + + @BeanPropertySetter(pattern = "rss/channel/language") + private String language; + + private Image image; + + // getters and setters + + @SetNext + public void setImage(Image image) { + this.image = image; + } + + @SetNext + public void addItem(Item item) { + this.items.add(item); + } + +}</pre> + + <p>Then the <code>Image</code> entity:</p> + + <pre>@ObjectCreate(pattern = "rss/channel/image") +class Image { + + @BeanPropertySetter(pattern = "rss/channel/image/description") + private String description; + + @BeanPropertySetter(pattern = "rss/channel/image/width") + private int width; + + @BeanPropertySetter(pattern = "rss/channel/image/height") + private int height; + + @BeanPropertySetter(pattern = "rss/channel/image/link") + private String link; + + @BeanPropertySetter(pattern = "rss/channel/image/title") + private String title; + + @BeanPropertySetter(pattern = "rss/channel/image/url") + private String url; + + // getters and setters + +}</pre> + + <p>and finally the <code>Item</code> entity:</p> + + <pre>@ObjectCreate(pattern = "rss/channel/item") +class Item { + + @BeanPropertySetter(pattern = "rss/channel/item/description") + private String description; + + @BeanPropertySetter(pattern = "rss/channel/item/link") + private String link; + + @BeanPropertySetter(pattern = "rss/channel/item/title") + private String title; + + // getters and setters + +}</pre> + + <p>It is now possible to create the <code>Digester</code> instance and parse the XML:</p> + + <pre>DigesterLoader digesterLoader = new DigesterLoader(); +... +Digester digester = digesterLoader.createDigester(Channel.class); +try { + Channel channel = (Channel) digester.parse(new URL("http://www.myfeedprovider.com/rss.xml").openStream()); +} catch (Exception e) { + // do something +} + </pre> + + <h5>Notes</h5> + <p>If asking to the <code>DigesterLoader</code> instance more then twice the + <code>Digester</code> for the same <code>Class<?></code>, the + <code>DigesterLoader</code> won't analize the target class for each request, + but rather will reuse cached results.</p> + + <p>The same <code>DigesterLoader</code> instance can be reused to create + other <code>Digester</code> instances.</p> + </html>