Blog

Sie befinden sich hier: Blog

JAXB Customizing - Generierung von equals und hashCode

Freitag, 17. Juni 2011 @ 10:17 geschrieben von Manfred Heiland

 

Nachdem ich, wie im vorherigen Blogeintrag beschrieben, das Mapping von XMLGregorianCalendar angepasst hatte, stellte sich kurz darauf ein weiteres Problem heraus. Ich mußte mehrere Listen mit Webservice Client Stub Objekte mergen und sortieren.

Dies wollte ich über eine java.util.TreeSet lösen. Um Duplikate feststellen zu können, benötigt dieses aber eine Implementierung der equals- und hashCode-Methode. Diese Methoden aber leider standardmäßig nicht generiert. 

Um die Genierung zu veranlassen, kann man auf bestehende Plugins des xjc-Binding-Compilers zurückgreifen. In unserem Setup (Maven, cxf-codegen-plugin) müssen dafür in der pom.xml des Projektes folgende Abhängigkeiten eingefügt werden.

<plugin>
  <artifactId>cxf-codegen-plugin</artifactId>
  .
  .
  <dependency>
    <groupId>org.jvnet.jaxb2_commons</groupId>
    <artifactId>jaxb2-basics</artifactId>
    <version>0.6.1</version>
  </dependency>
</plugin>

Zur Laufzeit der Generierung muß folgende Abhängigkeit vorhanden sein:

<dependency>
  <groupId>org.jvnet.jaxb2_commons</groupId>
  <artifactId>jaxb2-basics-runtime</artifactId>
  <version>0.6.1</version>
</dependency>

Da jetzt das Plugin verfügbar ist, kann der Aufruf in der pom.xml erweitert werden.

<plugin>
  <artifactId>cxf-codegen-plugin</artifactId>
.
.
. 
<wsdl>example.wsdl</wsdl>
<bindingFiles>
  <bindingFile>jaxb-binding.xml</bindingFile>
</bindingFiles> 
<extraargs>
  <extraarg>-xjc-Xequals</extraarg>
  <extraarg>-xjc-XhashCode</extraarg>
</extraargs> 
.
.
. 
</plugin>

Standardmäßig wird vom Compiler die org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy verwendet. Diese Strategy gibt dann true für die equals-Methode zurück, sofern alle Properties ein equals==true zurückliefern. Die Strategie selber kann mit Hilfe des Parameters -Xequals-equalsStrategyClass angepasst werden.

Ich wollte wiederum nicht die Strategie wechseln, sondern nur die Auswahl der Properties einschränken. Denn mein Objekt hatte schon ein ID-Property, die ich verwenden wollte. Das andere Property (standardText), sollte nicht für die EqualsStrategy verwendet werden.

Um dies zu erreichen, muß man die jaxb-bindings.xml folgendermaßen anpassen.

<jaxb:bindings version="2.0"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:basic="http://jaxb2-commons.dev.java.net/basic"
  jaxb:extensionBindingPrefixes="basic">

  <jaxb:bindings schemaLocation="example.wsdl#types4" node="//xs:schema">
    <jaxb:bindings node="//xs:complexType[@name='DataItem']">
      <jaxb:bindings node="//xs:element[@name='standardText']">
        <basic:ignored/>
      </jaxb:bindings>
    </jaxb:bindings>
  </jaxb:bindings>

</jaxb:bindings>

Über schemaLocation="example.wsdl#types4" referenzierte ich den 4. Block der Types-Einträge in der example.wsdl.

Danach hangelte ich mich mit weiteren XPath Ausdrücken zu meinem Element, das ich dann mit <basic:ignored/> annotierte. Über das Extension-Binding basic kann man mit einer Angabe alle Plugins veranlassen dieses Element zu ignorieren.

Nach einer weiteren Stub-Generierung kam dann dabei die von mir gewünschte equals-Methode heraus.

    public boolean equals(ObjectLocator thisLocator, 
                          ObjectLocator thatLocator, 
                          Object object, 
                          EqualsStrategy strategy) {
                          
        if (!(object instanceof DataItem)) {
            return false;
        }

        if (this == object) {
            return true;
        }

        final DataItem that = ((DataItem) object);
        {
            String lhsId;
            lhsId = this.getId();
            String rhsId;
            rhsId = that.getId();
            if (!strategy.equals(LocatorUtils.property(thisLocator, "id", lhsId), 
                 LocatorUtils.property(thatLocator, "id", rhsId), lhsId, rhsId)) {
                return false;
            }
        }
        return true;
    }

    public boolean equals(Object object) {
        final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE;
        return equals(null, null, object, strategy);
    }

 

zur Übersicht

Willkommen auf dem avono Blog

Hier auf dem avono Blog finden Sie in regelmäßigen Abständen sowohl technische Neuigkeiten aus unserer Partnerproduktwelt als auch nützliche Entwicklertipps.
Und jetzt kommt der obligatorische Disclaimer: Die Ausführungen der Blogeinträge spiegeln nicht die Meinung der avono AG sondern nur die Sicht der einzelnen Autoren wider.

Kategorien


Suche