Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove the "is" from JAXB generated boolean getters

Tags:

java

jaxb

JAXB is generating methods such as: isIsBuyNow() and isHasBuyNow() when I want isBuyNow() or hasBuyNow().

There are many many class methods being generated, so individually customizing the generated method names is not feasible.

Some sort of regex rule to customise the JAXB is the first thing that came to mind, but I can't find any such general way to change method names.

like image 267
Kevin Avatar asked Feb 03 '12 03:02

Kevin


3 Answers

You can use an external bindings file to customize your property name. In order for JAXB to recognize the method as a property it must follow the convention of starting with get or is for boolean types.

schema.xsd

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

   <xs:complexType name="root">
      <xs:attribute name="is-buy-now" type="xs:boolean"/>
   </xs:complexType>

</xs:schema>

bindings.xml

In the bindings file below we have specified a property name for the XML attribute called is-buy-now:

<jxb:bindings 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jxb:bindings schemaLocation="is.xsd">
        <jxb:bindings node="//xs:complexType[@name='root']/xs:attribute[@name='is-buy-now']">
        <jxb:property name="buyNow"/>
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

XJC Call

The -b option is used to specify a bindings file:

xjc -d out -b bindings.xml schema.xsd

Root

As a result the following class will be generated with: isBuyNow and setBuyNow methods:

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2012.02.03 at 05:18:59 AM EST 
//


package generated;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for root complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="root">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;attribute name="is-buy-now" type="{http://www.w3.org/2001/XMLSchema}boolean" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "root")
public class Root {

    @XmlAttribute(name = "is-buy-now")
    protected Boolean buyNow;

    /**
     * Gets the value of the buyNow property.
     * 
     * @return
     *     possible object is
     *     {@link Boolean }
     *     
     */
    public Boolean isBuyNow() {
        return buyNow;
    }

    /**
     * Sets the value of the buyNow property.
     * 
     * @param value
     *     allowed object is
     *     {@link Boolean }
     *     
     */
    public void setBuyNow(Boolean value) {
        this.buyNow = value;
    }

}

UPDATE

If you start from Java classes you can specify @XmlAccessorType(XmlAccessType.FIELD) to map to fields and name your methods as you choose:

@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlAttribute(name="has-buy-now")
    private boolean buyNow;

    public boolean hasBuyNow() {
        return buyNow;
    }

}
like image 80
bdoughan Avatar answered Oct 09 '22 07:10

bdoughan


From the sounds of it you only need to change method names, not class names. You may be able to either:

  1. find an XJC plugin that allows this, or
  2. write an XJC plugin that does this

I doubt the first option exists (though you might get lucky), but the second option seems pretty straightforward. See this page for some posts on how to write your own.

like image 34
Kaleb Brasee Avatar answered Oct 09 '22 09:10

Kaleb Brasee


Before marching the plugin route. I would emphasize corercting your variables name. It should be as per Java Bean conventions. And JAXB should be working as per that only.

so if the variable is boolean, ist should idealy be buyNow. Respective getter method will become isBuyNow() only which you want. It would be matter of regenerating the mappings again. No regeex no custom find/replace as you (rightly) want :)

like image 36
manocha_ak Avatar answered Oct 09 '22 08:10

manocha_ak