Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 89445 invoked from network); 22 May 2002 18:14:00 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 22 May 2002 18:14:00 -0000 Received: (qmail 3344 invoked by uid 97); 22 May 2002 18:13:52 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@jakarta.apache.org Received: (qmail 3260 invoked by uid 97); 22 May 2002 18:13:52 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 3183 invoked by uid 97); 22 May 2002 18:13:51 -0000 X-Antivirus: nagoya (v4198 created Apr 24 2002) Date: 22 May 2002 18:13:41 -0000 Message-ID: <20020522181341.16536.qmail@icarus.apache.org> From: jstrachan@apache.org To: jakarta-commons-sandbox-cvs@apache.org Subject: cvs commit: jakarta-commons-sandbox/betwixt/xdocs overview.xml navigation.xml index.xml X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N jstrachan 02/05/22 11:13:41 Modified: betwixt build.xml .cvsignore Added: betwixt LICENSE.txt project.properties project.xml betwixt/xdocs overview.xml navigation.xml index.xml Removed: betwixt/src/test/org/apache/commons/betwixt TestAll.java Log: Ported Betwixt to a Maven build. Some unit test cases still fail when run inside Maven due to classpath problems; will patch those shortly. Revision Changes Path 1.16 +151 -9 jakarta-commons-sandbox/betwixt/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/build.xml,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- build.xml 17 May 2002 15:24:11 -0000 1.15 +++ build.xml 22 May 2002 18:13:40 -0000 1.16 @@ -1,18 +1,160 @@ - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + 1.2 +4 -0 jakarta-commons-sandbox/betwixt/.cvsignore Index: .cvsignore =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/betwixt/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- .cvsignore 22 Aug 2001 12:25:01 -0000 1.1 +++ .cvsignore 22 May 2002 18:13:40 -0000 1.2 @@ -1,2 +1,6 @@ build.properties dist +target +velocity.log +.project + 1.1 jakarta-commons-sandbox/betwixt/LICENSE.txt Index: LICENSE.txt =================================================================== /* * $Header: /home/cvs/jakarta-commons/LICENSE,v 1.4 2002/04/11 13:24:02 dion Exp $ * $Revision: 1.4 $ * $Date: 2002/04/11 13:24:02 $ * * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . * */ 1.1 jakarta-commons-sandbox/betwixt/project.properties Index: project.properties =================================================================== # ------------------------------------------------------------------- # P R O J E C T P R O P E R T I E S # ------------------------------------------------------------------- compile.debug = on compile.optimize = off compile.deprecation = off maven.jarResources.basedir=${basedir}/src/java # use Sun coding standards maven.checkstyle.lcurly.type = eol maven.checkstyle.lcurly.method = eol maven.checkstyle.lcurly.other = eol #maven.checkstyle.header.file = src/conf/checkstyle-LICENSE.txt maven.checkstyle.header.ignore.line = 1,2,3,4,5,6 maven.checkstyle.const.pattern = ^[a-z][a-zA-Z0-9]*$ # disable these non-critical errors to highlight # more important ones line missing javadoc maven.checkstyle.max.line.len = 100 maven.checkstyle.ignore.whitespace = true maven.checkstyle.ignore.public.in.interface = true 1.1 jakarta-commons-sandbox/betwixt/project.xml Index: project.xml =================================================================== 2 commons-betwixt commons-betwixt 1.0-dev Apache Software Foundation http://www.apache.org 2002 org.apache.commons.betwixt Commons Betwixt jakarta Commons Betwixt: mapping beans to XML http://jakarta.apache.org/commons/sandbox/betwixt.html http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/betwixt/ jakarta-commons-sandbox/betwixt http://nagoya.apache.org/ jakarta.apache.org /www/jakarta.apache.org/commons/sandbox/betwixt/ Commons Dev List commons-dev-subscribe@jakarta.apache.org commons-dev-unsubscribe@jakarta.apache.org http://nagoya.apache.org/eyebrowse/SummarizeList?listName=commons-dev@jakarta.apache.org James Strachan jstrachan jstrachan@apache.org SpiritSoft, Inc. Robert Burrell Donkin robertdonkin robertdonkin@mac.com commons-logging required 1.0 commons-logging-1.0.jar commons-beanutils required 1.2 commons-beanutils-1.2.jar commons-collections required 2.0 commons-collections-2.0.jar commons-digester required 1.2 commons-digester-1.2.jar src/java src/test include = **/Test*.java include = **/*.properties, **/*.xml commons-dev@jakarta.apache.org 1.1 jakarta-commons-sandbox/betwixt/xdocs/overview.xml Index: overview.xml =================================================================== Betwixt Overview James Strachan

Probably the best way to get started is to look at some examples. The best example to start with is the Ant target "demo.rss" which runs the RSSBeanWriter sample program in the src/test directory. Once you've got the Jakarta Commons build system working, by installing Ant and creating your own build.properties to point to the required JARs type the following at a command line

ant demo-rss

This uses the Commons Digester RSSDigester example to parse an RSS document, create a Channel bean and then write it out again as XML using the default XMLIntrospector and the BeanWriter. You should see the XML come out from the Channel bean which looks similar to a real RSS document.

The next example to look at is

ant demo-rss2

This is similar to the above but uses a BeanReader to parse the RSS file. So this is Betwixt defaulting the Digester rules required to parse the XML document. Then the BeanWriter is used to output the beans that get created.

There are various ways of mapping beans to an XML structure. For example consider a simple bean

public class CustomerBean {
      public String getName();
      public Order[] getOrders();
      public String[] getEmailAddresses();
  }

This could be mapped to XML as these various ways

This example uses attributes for primitive types.

<CustomerBean name="James">
      <order id="1">...</order>
      <order id="2">...</order>
      <emailAddress>jstrachan@apache.org</emailAddress>
  </CustomerBean>

This example uses elements for all properties and wraps collections in an extra element (which can be quite common in XML schemas). Also note that some element names have been changed.

<customer>
      <name>James</name>
      <orders>
          <order id="1">...</order>
          <order id="2">...</order>
      </orders>
      <email-addresses>
          <email-address>jstrachan@apache.org</email-address>
      </email-addresses>
  </customer>    

Betwixt aims to provide a diversity of possible mappings such that the developer can choose, if they wish, how their beans appear as XML to support whatever XML encoding scheme that is desired. If no particular mapping is provided then Betwixt will create a default mapping for you. Also the customization mechanism allows you to just override the parts you want to and let Betwixt default the rest. So if you just want to rename a property in XML for a certain type, thats all you need to do. No need to hand-code what Betwixt can deduce for itself.

The XMLIntrospector will look for files of the form className.betwixt on the classpath using the same ClassLoader used to load the given class and use that document to specify the mapping to XML. If this file does not exist then the default introspection rules are used.

The simplest possible file may just set the name of the element. e.g.

<?xml version="1.0" encoding="UTF-8" ?>
  <info>
    <element name="channel"/>
    <addDefaults/>
  </info>

The above means to use the name 'channel' for the outer most element for the given type. The <addDefaults> means to add the defaults from the introspector. This allows you to just rename a few properties then let the introspector do the rest. There is also a <hide> element which allows one or more properties to be hidden. Also note that the <element> and <attribute> tags can be nested to any kind of depth allowing whatever XML structure you wish. This can be useful if you wish to wrap collections in some arbitrary collection tags or to group properties of a bean together in some XML structure. e.g.

<?xml version="1.0" encoding="UTF-8" ?>
  <info primitiveTypes="attribute">
    <element name="channel"/>
      <element name="customerList">
        <element name="customer" property="customers"/>
      </element>
      <element name="foo">
        <attribute name="qqq" property="ppp"/>
        <element name="bar" property="xyz"/>
      <hide property="something"/>
      <addDefaults/>
    </element>
  </info>
  

The primitiveTypes attribute in the <info> element is optional and can be used to specify whether primitive java types (strings, numbers, dates etc) are specified as attributes or elements by default.

Finally static text can be specified using a value attribute inside an <element> or <attribute> tag. e.g. to add constant attributes such as a version label to the generated XML...

<?xml version="1.0" encoding="UTF-8" ?>
  <info primitiveTypes="element">
    <element name="rss"/>
      <attribute name="version" value="0.91"/>
      <element name="channel"/>
      <addDefaults/>
    </element>
  </info>
  

The Java Beans specification contains various naming conventions that should be used when writing beans that will allow the beans introspector to automatically guess the properties in a bean and their getters & setter methods etc. Betwixt will use these same naming conventions to deduce how to make the beans appear as XML. There are some other naming conventions that you can use to make your beans easier to output as XML or parse.

This naming convention is used to indicate the singular type of some composite property.

To use: create an add method to match the getter method for 'composite properties'.

public class SomeBean {
      public <CollectionType> getFoo*();
      public void addFoo(<SingularType> foo);
  }

Where CollectionType can be an array, a Collection, Enumeration, Iterator, Map. The [SinglularType] refers to the type of an item in the collection. The name of the getter property starts with 'Foo'. So 'Foo' is the singular name, the plural collection name could be Foos, FooArray, FooList, FooIterator or some other encoding, though the plural name should start with the singular name for auto-detection to work properly.

In the RSS example from Digester there's a bean which matches this pattern.

  public class Channel
  
      public Item[] getItems();
  
      public void addItem(Item item);
  }
  

This means that the following bean does not match this naming convention, since the plural property name does not start with the singular name..

public class Foo {
      public Collection getPeople();
      public void addPerson(Person person);
  }

Though these two beans do match

public class Foo {
      public Collection getPersonCollection();
      public void addPerson(Person person);
  }
  public class Foo {
      public Iterator getPersonIterator();
      public void addPerson(Person person);
  }
  

The following are other valid examples of composite-getter methods and their matching adder methods.

Composite getter method Adder method
getChildren() addChild()
getPersonList() addPerson()
getItems() addItem()
getChannels() addChannel()
getSheep() addSheep()
1.1 jakarta-commons-sandbox/betwixt/xdocs/navigation.xml Index: navigation.xml =================================================================== Betwixt Jakarta 1.1 jakarta-commons-sandbox/betwixt/xdocs/index.xml Index: index.xml =================================================================== Betixt: turning beans into XML James Strachan

The Betwixt library provides an XML introspection mechanism for mapping beans to XML in a flexible way. It is implemented using an XMLIntrospector and XMLBeanInfo classes which are similar to the standard Introspector and BeanInfo from the Java Beans specification.

Betwixt provides a way of turning beans into XML as well as automatically generating digester rules in a way that can be customized on a per type manner in the same way that the BeanInfo mechanism can be used to customize the default introspection on a java object.

-- To unsubscribe, e-mail: For additional commands, e-mail: