How to generate equals() and hashcode() methods using wsimport in jaxws - jaxb

The generated classes from my WSDL using wsimport are not having equals() and hashcode() methods. How can I customize and generate the client classes to get equals() and hashcode() methods.
I am not sure about using JAXB to achieve this.
In Axis2.0 generated stubs these methods are generated but not sure why such a basic thing is not available in JAXWS!

You can use the JAXB2 Basics Plugin to generate equals() and hashcode() methods:
https://github.com/highsource/jaxb2-basics
http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins

If you are looking to generate hashcode() and equals() using wsimport in maven, check this answer on how to generate value constructors, but also includes the configuration for generating hashcode() and equals() too:
How do I make wsimport generate constructors?

More information on how it worked.
I have to add classpath to jaxb2-commons and without which wsimport runs without complaining but nothing happens! After adding the classpath as below
<path id="jaxb2-commons.classpath">
<fileset dir="${dir.toolchain}/noarch/jaxb2-basics-dist-0.6.0">
<include name="**/*.jar" />
</fileset>
</path>
the below wsimport worked as expected
<wsimport wsdl="#{dir-wsdl}/#{name-wsdl}"
taskname="wsimport-#{service}"
destdir="#{dest-dir}"
sourcedestdir="#{source-dest-dir}"
package="#{package}"
keep="#{keep}"
verbose="#{verbose}"
xdebug="#{xdebug}"
xnocompile="#{xnocompile}"
target="2.1">
<binding dir="#{dir-wsdl}" includes="bindings-wsdl-#{name-wsdl}.xml, bindings-schema-#{name-wsdl}.xml" />
<xjcArg value="-Xequals" />
<xjcArg value="-XhashCode" />
<xjcArg value="-XtoString" />
<!-- Generates per-package jaxb.index file which lists all of the schema-derived classes in this package.-->
<xjcArg value="-Xjaxbindex" />
<xjcArg value="-Xsetters" />
</wsimport>

Related

Using external dependency in Java bean annotation

Let's say I want to use opencsv. I have added the dependency in external-dependencies.xml asked to download the dependency by saying usemaven='true'. The jar file is downloaded and stored in the lib folder of the extension
Now if I want to use this dependency to generate Java bean which contains annotation example.
<bean class="com.something.dto.IndirectSaleData">
<import type="com.opencsv.bean.CsvBindByName"/>
<property name="firstName" type="java.lang.String">
<annotations>#CsvBindByName(column = "first_name", required = true)</annotations>
</property>
</bean>
Why is it not able to resolve the dependency?
On the other hand if I directly create the Java Class it works totally fine example-
import com.opencsv.bean.CsvBindByName;
public class Data {
#CsvBindByName(column = "first_name", required = true)
private String name;
}
From question itself seems like the problem is not in the library dependency, but in bean XML definition instead.
Also it's not readable to define beans with annotations like that. Better to add it as Java class directly.
There is a way to plug in the dependency in the build class path. We can use buildcallbacks.xml for this. What I did is I moved the external dependency to platform/core/lib as I want it to be available during generation of model classes.
code snippets:
<macrodef name="yourExtensionName_before_build">
<sequential>
<echo message="Copy external jar to platform core"/>
<!-- Copy the jar from your extension lib folder to platform core -->
<copy file="${ext.yourExtensionName.path}/lib/your-dependency.jar"
todir="${platformhome}/ext/core/lib" failonerror="true"/>
</sequential>
</macrodef>

EclipseLink MOXy: Suppress xsi:type when marshalling

I have a bindings file with the following content:
<java-type name="JavaType">
<xml-root-element name="root"/>
<java-attributes>
...
</java-attributes>
</java-type>
When I marshall the JavaType class using this binding, the XML looks like this
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="JavaType">
I don't want the xsi:type to be there, how can I suppress this when marshalling?
The xsi:type attribute will appear when you are marshalling a subclass. You can have it be suppressed by wrapping your object in a JAXBElement that supplies information about the root element including type.
JAXBElement<JavaType> je = new JAXBElement(new QName(), JavaType.class javaType);
marshaller.marshal(je, System.out);
Example
Is there a possibility to hide the "#type" entry when marshalling subclasses to JSON using EclipseLink MOXy (JAXB)?
UPDATE
Thanks. I now made the superclass XmlTransient, which makes the
xsi:type disapear as well. I used the annotation to do that. Is there
actually a way to use to make a java-type be
transient? I could only make it work for java-attributes.
You are correct. You can use #XmlTransient at the class level to have it removed from the inheritance hierarchy. Below is how this can be done using MOXy's external mapping document.
<?xml version="1.0" encoding="UTF-8"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
package-name="com.example.foo">
<java-types>
<java-type name="Foo" xml-transient="true"></java-type>
</java-types>
</xml-bindings>
For More Information
http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html
I tried #blaise-doughan's suggestion and added the #XmlTransient annotation to top of my abstract base class.
With my environment (so my product depends something strictly), the jaxb-api library says "The annotation #XmlTransient is disallowed for this location" because of the version of it high probably older than 2.1. I realized that when I tried to adding the annotation with a new test class-path which contains version >=2.1, so it allows to defining it top of a class.
So let me get straight to the point, I suggest below method in order to get rid of the type fields which appears on responses which are building and marshaling from extended classes.
I only added #XmlDiscriminatorNode("") to top of my base class and I supposed that you are using the EclipseLink MOXy:
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;
#XmlDiscriminatorNode("")
public abstract class Base {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
As a summary you can use #XmlTransient if you have the jaxb-api version greater than 2.1 or use my method if you have EclipseLink MOXy.

Mule ESB JAXB XML To Object Transformer Better Way?

Mule 3.3 can automatically unmarshall an XML string to an object using JAXB given that:
1. you first register your jaxb annotated classes with spring.
2. there is a component that requires such type as input
So I have managed to do the transformation, but I had to create a "DumbTransformer" that does nothing. It has a method that returns the same object it receives. I need it in order to trigger the XML to Object conversion so that I can further process the message.
Flow Example:
<spring:beans>
<spring:bean id="dumbTransformer" class="foo.bar.DumbTransformer"/>
</spring:beans>
<flow name="main" doc:name="main">
<vm:inbound-endpoint path="in" doc:name="VM" />
<component doc:name="Java">
<spring-object bean="dumbTransformer"/>
</component>
<splitter expression="#[payload.items]" doc:name="Split Items"/>
<logger message="#[payload]" level="INFO" doc:name="Log Item"/>
<vm:outbound-endpoint path="out" doc:name="VM" />
</flow>
DumbTransformer.java
package foo.bar;
#ContainsTransformerMethods
public class InvoiceUnmarshaller extends AbstractTransformer {
#Transformer
public MyJaxbAnnotatedClass foo(#Payload MyJaxbAnnotatedClass i) {
return i;
}
}
Is there a way to acomplish this without having to create such DumbTransformers?
Thanks.
As you guessed it, the JAXB deserialization doesn't occur because there is no component to satisfy:
there is a component that requires such type as input
So what if you had an auto-transformer to do just that:
<auto-transformer returnClass="foo.bar.MyJaxbAnnotatedClass" />
The Mule XML Module provides OOTB a JAXB Transformer. I would rather leverage mule capabilities whenever possible rather than writing custom code

JAXB Marshalling - extending an existing class

I am in need of creating a series of Java objects via XML using JAXB that all extend a common base class that is already created (not using JAXB). For example, let's say I have following JAXB classes that I am trying to generate:
Penguin.xml -> Penguin.java
Robin.xml -> Robin.java
Cardinal.xml -> Cardinal.java
I already have an existing base class called Bird.java that I wish the three classes above to extend.
What is the best way to do this?
Thanks for your help!
That is very simple: you need to to create a JAXB binding file with following contents:
<jaxb:bindings version="1.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
>
<jaxb:globalBindings>
<!-- All beans should extend this base class: -->
<xjc:superClass name="org.mycompany.common.Bird" />
</jaxb:globalBindings>
</jaxb:bindings>
More information on this option (and other sweet things) you can find here.

DSL Toolkit: How can I get correct elements written in this scenario?

Info: C# , VS2010 Beta 2 , DSL ToolKit Beta 2
I am trying to create the following generated XML in my DSL Diagram when used
<Method>
...
<FilterDescriptors>
<FilterDescriptor Type="Comparison" Name="EmployeeKey" />
</FilterDescriptors>
...
</Method>
This is how the Method and Filter Descriptor Domain Classes look
I believe I have set the multiplicity correct:
Method should only have 1 Filter Descriptor
A Filter Descriptor can have many Filter Descriptors i.e
<FilterDescriptors>
<FilterDescriptor Type="Comparison" Name="EmployeeKey" />
<FilterDescriptor Type="Wildcard" Name="EmployeeName" />
</FilterDescriptors>
The issue is that the output XML is like this:
<FilterDescriptors>
<FilterDescriptor>
<FilterDescriptors>
<FilterDescriptor Type="Comparison" Name="EmployeeKey" />
</FilterDescriptors>
</FilterDescriptor>
</FilterDescriptors>
We have this same pattern is several locations in our DSL Diagram and was hoping there is a something simple to resolve this rather than overriding the ReadElements and WriteElements of each domain class
Have you posted this in the DSL Tools forum at http://social.msdn.microsoft.com/Forums/en-US/dslvsarchx/threads? I don't see a thread there for it.

Resources