users@jaxb.java.net

Re: [Issue 115] Supports Method Chaining/ FluentAPI

From: Hanson Char <hanson.char_at_gmail.com>
Date: Thu, 26 Jan 2006 10:42:11 -0800

I've got the initial version of xjc plugin working for supporting the
fluent api requested in RFE 115.

Any idea how I can host it at jaxb2-common ?

See below for sample usage and configuration.

Hanson

build.xml
-------------
<taskdef name="xjc"
    classname="com.sun.tools.xjc.XJCTask">
  <classpath>
    <pathelement path="/path/to/jaxb-xjc.jar"/>
    <pathelement path="/path/to/jaxb-ri-fluent-api.jar" />
  </classpath>
</taskdef>

<xjc ...>
  <arg value="-Xfluent-api" />
  ...
</xjc>

Sample Usage
---------------------
Contrast the following code (which is simpler and clearer) against the
original jaxb's samples/create-marshal/src/Main.java

// Modified to use the fluent api generated by enabling the fluent-api
xjc plugin.
public class Main {

    // This sample application demonstrates how to construct value classes
    // and create a java content tree from scratch and marshal it
    // to XML data

    public static void main( String[] args ) {
        try {
            // create a JAXBContext
            JAXBContext jc = JAXBContext.newInstance( "primer.po" );

            // create an empty PurchaseOrder
            PurchaseOrderType po = new PurchaseOrderType()
               // set the required orderDate attribute
              .withOrderDate( getDate() )
               // set the required shipTo address
              .withShipTo( new USAddress()
                                .withName("Alice Smith")
                                .withStreet("123 Maple Street")
                                .withCity("Cambridge")
                                .withState("MA")
                                .withZip( new BigDecimal("12345")) )
               // set the requred billTo address
              .withBillTo( new USAddress()
                                .withName("Robert Smith")
                                .withStreet("8 Oak Avenue")
                                .withCity("Cambridge")
                                .withState("MA")
                                .withZip( new BigDecimal("12345" )) )
              ;

            // create an empty Items object
            Items items = new Items();

            // get a reference to the ItemType list
            List<Items.Item> itemList = items.getItem();

            // start adding ItemType objects into it
            itemList.add( new Items.Item()
                                .withProductName("Nosferatu - Special Edition (1929)")
                                .withQuantity(5)
                                .withUSPrice(new BigDecimal( "19.99" ))
                                .withComment(null)
                                .withShipDate(null)
                                .withPartNum("242-NO"))
                                ;
            itemList.add( new Items.Item()
                                .withProductName("The Mummy (1959)")
                                .withQuantity(3)
                                .withUSPrice(new BigDecimal( "19.98" ))
                                .withComment(null)
                                .withShipDate(null)
                                .withPartNum("242-MU"))
                                ;
            itemList.add( new Items.Item()
                                .withProductName("Godzilla and Mothra: Battle for
Earth/Godzilla vs. King Ghidora")
                                .withQuantity(3)
                                .withUSPrice(new BigDecimal( "27.95" ))
                                .withComment(null)
                                .withShipDate(null)
                                .withPartNum("242-GZ"))
                                ;

            // set the required Items list
            po.setItems( items );

            // create an element for marshalling
            JAXBElement<PurchaseOrderType> poElement = (new
ObjectFactory()).createPurchaseOrder(po);

            // create a Marshaller and marshal to System.out
            Marshaller m = jc.createMarshaller();
            m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
            m.marshal( poElement, System.out );

        } catch( JAXBException je ) {
            je.printStackTrace();
        }
    }

    private static XMLGregorianCalendar getDate() {
        try {
            return DatatypeFactory.newInstance().newXMLGregorianCalendar(new
GregorianCalendar());
        } catch (DatatypeConfigurationException e) {
            throw new Error(e);
        }
    }
}


On 1/25/06, Hanson Char <hanson.char_at_gmail.com> wrote:
> For the same reason, it would be nice to have access to JVar's internal "mods".
>
> Hanson
>
>
>
> On 1/25/06, Hanson Char <hanson.char_at_gmail.com> wrote:
> > Hi,
> >
> > I am trying to write a xjc plugin to support a fluent api in addition to the default (JavaBean) setter methods.
> >
> > The initial idea is simply to add a "with*" method to the generated class (via JDefinedClass.method) for every "set*" method encountered, with the only difference of returning the class instance, instead of void.
> >
> > In creating a "with*" method, I am trying to clone across the modifiers of the corresponding setter method. These modifiers can be accessed via JMethod.getMods() which is of type JMods. However, although JMods has an internal "mods" int field, there seems no API to gain access to it. (I don't want to resort to reflection to break the API.) Meanwhile, the required "mods" parameter of JDefinedClass.method is an int.
> >
> > Any chance this can be changed ?
> > ie.
> >
> >
> > Either JDefinedClass.method should allow passing in a JMods instead of int for the modifiers; or
> > JMods should provide a getter method to its internal "mods". Does this make sense ?
> >
> > Hanson
> >
>
>