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>