Bean-To-XML annotations: how to process nested structure - java

For bean->xml convertion in webservices we use Aegis from CXF (it is jaxb-compatible, as I understand).
This is my type:
class C{
private int a;
private int b;
private T t;
...
}
class T{
private int t1;
private int t2;
}
I need t.t1 field to be on the same level in XML as a and b in C (bean restored from xml should be like this:
class C{
private int a;
private int b;
private int t1
}
(client code is interested only in field t1 from structure T).
Thanks.

You could add getT1() and setT1(int) to C and make getT() #XmlTransient
class C {
// snip
/**
* JAXB only
*/
#SuppressWarnings("unused")
#XmlElement
private void setT1(int t1) {
if(t != null) {
t.setT1(t1);
} else {
// TODO
}
}
/**
* JAXB only
*/
#SuppressWarnings("unused")
private int getT1() {
if(t != null) {
return t.getT1(t1);
} else {
// TODO
}
}
}

Related

Pass enum class as parameter to method in java

I have two different Enums:
public enum A {
mass(10); // many other values omitted for clarity
private final int m;
private A(int m) { this.m = m; }
public int value() { return this.m; }
}
public enum B {
mass(100); // many other values omitted for clarity
private final int m;
private B(int m) { this.m = m; }
public int value() { return this.m; }
}
and want to pass enum class as parameter to my function. From other answers that I found on SO, it is suggested that I can pass Class, but I am not sure how to correctly detect and use A or B enum in the function body:
public int mass(Class<?> clazz) {
// Is it the best way? How to avoid a bunch of ifs?
if (clazz == A.class) return A.mass.value();
if (clazz == B.class) return B.mass.value();
}
Not sure what you're trying to accomplish buddy but you seem to be in need of polymorphism. Try using an interface with Enums like this:
public enum A implements MassProvider {
MASS(10);
private int mass;
A(int mass) {
this.mass = mass;
}
#Override
public int getMass() {
return mass;
}
}
public enum B implements MassProvider {
MASS(100);
private int mass;
B(int mass) {
this.mass = mass;
}
#Override
public int getMass() {
return mass;
}
}
public interface MassProvider {
int getMass();
}
public static int mass(MassProvider p) {
return p.getMass();
}
Basically instead of passing a class to the mass method you pass a MassProvider that is implemented by both enums.

Is it possible to get public static field from template class argument?

Given
class A {
public static A newInstance(int x) { ... }
}
And several classes containing static fields of type A
class B1 {
public static A MIN = A.newInstance(10);
}
class B2 {
public static A MIN = A.newInstance(15);
}
I would like to parameterize a class with B1 or B2 to get MIN field of type A from class B in the class C:
class C <T, P> {
private T t = ???;
}
When C<A, B1> c = new C(); what should be placed instead ??? to get B1.MIN?
Is it possible?
EDIT:
Thank you for the answers, I have upvoted both.
I have arrived simply at
class C <T, P> {
private T t;
public C(T min) {
this.t = min;
}
}
This will be just C<A, B1> c = new C<A, B1>(B1.MIN); because as you can see it is hard to avoid a constructor for C taking an instance of B1 or smth like that. But in this case B1 at least not instantiated.
You can use an interface to achieve this behavior:
class A {
public static A newInstance() { return new A(); }
}
interface HasMin {
public static A MIN = null;
}
class B1 implements HasMin {
public static A MIN = A.newInstance();
}
class B2 implements HasMin {
public static A MIN = A.newInstance();
}
class C<T extends HasMin> {
private A t = T.MIN;
}
Then you can create: C<B1> and C<B2> and use both.
As Tom suggested in the comments below, this approach is limited to use static fields. An even better approach would be:
public class Play {
public static void main(String[] args) {
B1 b1 = new B1();
C<B1> c = new C<>(b1);
System.out.println(c.getA()); // prints: A{ x=10 }
B2 b2 = new B2();
C<B2> c2 = new C<>(b2);
System.out.println(c2.getA()); // prints: A{ x=20 }
}
}
class A {
private int x;
public A(int x) {
this.x = x;
}
#Override
public String toString() {
return "A{ x=" + x + " }";
}
public static A newInstance(int x) {
return new A(x);
}
}
interface GetMin {
public A getMin();
}
class B1 implements GetMin {
public A MIN = A.newInstance(10);
#Override
public A getMin() {
return MIN;
}
}
class B2 implements GetMin {
public A MIN = A.newInstance(20);
#Override
public A getMin() {
return MIN;
}
}
class C<T extends GetMin> {
private A a = null;
public C(T t) {
a = t.getMin();
}
public A getA() {
return a;
}
}
I would forget static and have a concrete instance of an interface:
public interface Bounds<T> {
T min();
}
The concrete instance could be singleton, so next best thing to a static:
public enum B implements Bounds<A> {
INSTANCE;
private final A min = A.newInstance(10);
#Override
public A min() {
return min;
}
}
C then defined like so:
public class C<T, P extends Bounds<T>> {
private T min;
public C(P bounds) {
min = bounds.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A, B> c = new C(B.INSTANCE);
Self describing
Maybe you don't want this meta data type (B), maybe you want types to describe themselves. So C could be defined for types that can describe their own bounds:
public class C<T extends Bounds<T>> {
private T min;
public C(T anyT) {
min = anyT.min();
}
public T getMin() {
return min;
}
}
Usage:
C<A> c = new C(A.zero); //any A will do
Where A is:
public class A implements Bounds<A>{
public final static A zero = A.newInstance(0);
private final static A min = A.newInstance(10);
public static A newInstance(int x) {
return new A(x);
}
private int x;
public A(int x) {
this.x = x;
}
#Override
public A min() {
return min;
}
}

Java type parameter is not within its bound

I have a class Zeitpunkt which implements a date with time and in addition a class Suchbaum which represents a binary search tree.
I want to use a Comparator-Object in Suchbaum to sort a tree by the day of Zeitpunkt, but when I want to create a Suchbaum object, it prints the named error.
Zeipunkt
public class Zeitpunkt<T> implements Comparable<T>
{
private int jahr;
private int monat;
private int tag;
private int stunden;
private int minuten;
private double sekunden;
public int vergleich(Zeitpunkt a) { ... }
#Override
public int compareTo(T o) {
if(o instanceof Zeitpunkt)
return vergleich((Zeitpunkt)o);
return 0;
}
...
}
Suchbaum
public class Suchbaum<T extends Comparable<T>> {
private class Element {
private T daten;
private Element links;
private Element rechts;
public Element(T t) {
daten = t;
links = null;
rechts = null;
}
}
private Element wurzel;
private Comparator<T> comp;
...
}
Testclass
public class BaumTest {
public static void main(String[] args) {
// error in the following line (IntelliJ underlines the first
// "Zeitpunkt"). Suchbaum<Zeitpunkt<?>> = ... doesn't work either..
// *Completely confused*
Suchbaum<Zeitpunkt> sb = new Suchbaum<>((Zeitpunkt z1, Zeitpunkt z2) -> {
if(z1.getTag() > z2.getTag())
return 1;
else if(z1.getTag() == z2.getTag())
return 0;
else
return -1;
});
}
}
Any ideas? (the other threads with this topic didn't help me out)
Seems that you don't want to make your Zeitpunkt class parametrized, you just want it to implement Comparable interface. So change it like this:
public class Zeitpunkt implements Comparable<Zeitpunkt> {
private int jahr;
private int monat;
private int tag;
private int stunden;
private int minuten;
private double sekunden;
public int vergleich(Zeitpunkt a) {
return 0;
}
#Override
public int compareTo(Zeitpunkt o) {
return vergleich(o);
}
}
Also you need to define a constructor in your Suchbaum class:
public Suchbaum(Comparator<T> comp) {
this.comp = comp;
}

JAVA: Setting member data at creation, without using constructor

I'm working with som generated classes which I need to set the member data of at creation. The generated classes only have a default constructor, and no setters for the member data. It doesn't make sence to modify the classes, as the modification will be overwritten, when I regenerate the classes again (It's a shared project, so somebady else might also overwrite the generated classes).
Is it possible to do something like this.
Example:
public class A{
private int value;
}
public class B{
private A a;
public void initA()
{
a = new A(){
value = 9;
};
}
}
Something like this will allow you to set the value of the private field A.value:
class A {
private int value;
#Override
public String toString() {
return "Value of my private field: " + value;
}
}
class MutableA {
public A a;
private Field value;
public MutableA(A a) {
this.a = a;
try {
this.value = A.class.getDeclaredField("value");
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
this.value.setAccessible(true);
}
void setValue(int value) {
try {
this.value.set(a, value);
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
You can use it like this:
public class Test{
public static void main(String[] args) {
A a = new A();
System.out.println("before mutation:" + a);
MutableA mutableA = new MutableA(a);
mutableA.setValue(1);
System.out.println("before mutation: " + a);
}
}
Output:
before mutation: Value of my private field: 0
before mutation: Value of my private field: 1
If you only have no argument constructors you will have to use setters to set private members.
public class A{
private int value;
static{
value=10;
}
}
public class B{
private A a;
public void initA()
{
a = new A();
}
}

JAXB Can't handle interfaces

I think this question has been asked like a million times, but none of solutions suggested worked for me. Here is my sample implementation
public class FooImpl2 implements Foo {
private int a = 100 ;
private String b = "I am FooImpl2";
private boolean c;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public boolean isC() {
return c;
}
public void setC(boolean c) {
this.c = c;
}
}
#XmlRootElement
#XmlSeeAlso({FooImpl1.class, FooImpl2.class})
public interface Foo {}
public class FooImpl1 implements Foo {
private int x;
private String y ="I am FooImpl1";
private boolean z;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
public boolean isZ() {
return z;
}
public void setZ(boolean z) {
this.z = z;
}
}
#XmlRootElement
public class Response{
private Foo foo;
#XmlElement(type=Object.class)
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
public class SimpleResource {
#Path("foo/{val}") #Produces({"application/json"}) #GET
public FooAdapter getFoo(#QueryParam("val") int val) {
FooAdapter ret = new FooAdapter();
if(val % 2 == 0) {
ret.setFoo(new FooImpl2());
} else {
ret.setFoo(new FooImpl1());
}
return ret;
}
I always get following exception
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of
IllegalAnnotationExceptions
com.abc.objectsToReturn.Foo is an
interface,
can any one help me to figure out right solution
This isn't really an interface issue, you just need to change the way you bootstrap your JAXBContext.
If you change it to the following:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Response.class, FooImpl1.class, FooImpl2.class);
Response response = new Response();
FooImpl1 foo = new FooImpl1();
response.setFoo(foo);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}
Then you will get the following output (with any JAXB implementation: Metro, MOXy, etc):
<response>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="fooImpl1">
<x>0</x>
<y>I am FooImpl1</y>
<z>false</z>
</foo>
</response>
MOXy JAXB allows your entire model to be interfaces, checkout:
http://bdoughan.blogspot.com/2010/07/moxy-jaxb-map-interfaces-to-xml.html
I also have a blog post that may be relevant to what you are trying to build:
http://bdoughan.blogspot.com/2010/08/using-xmlanyelement-to-build-generic.html
When you use interfaces just to hide your implementation classes from exposure, and when there's 1-to-1 (or close to 1-on-1) relationship between a class and an interface, XmlJavaTypeAdapter can be used like below.
#XmlJavaTypeAdapter(FooImpl.Adapter.class)
interface IFoo {
...
}
class FooImpl implements IFoo {
#XmlAttribute
private String name;
#XmlElement
private int x;
...
static class Adapter extends XmlAdapter<FooImpl,IFoo> {
IFoo unmarshal(FooImpl v) { return v; }
FooImpl marshal(IFoo v) { return (FooImpl)v; }
}
}
class Somewhere {
public IFoo lhs;
public IFoo rhs;
}

Categories