simple-framework - how to pass member to super class - java

I'm trying to serialize a simple hierarchy:
public class RootClass {
#Element
private final int a;
public RootClass( int a) {
this.a = a;
}
}
class SubClass extends RootClass {
#Element(name="b")
int b;
public SubClass() {
super(0);
this.b=0;
}
}
when I run
SubClass sub = new SubClass();
Serializer serializer = new Persister();
StringBuilderWriter writer = new StringBuilderWriter(1000);
serializer.write(sub, writer);
I get:
ConstructorException: Default constructor can not accept read only
#org.simpleframework.xml.Element(name=, data=false, type=void, required=true)
on field 'a' private final int
com.informatica.b2b.structurediscovery.serialization.tests.RootClass.a in class
com.informatica.b2b.structurediscovery.serialization.tests.SubClass
I couldn't find any way to make it work.

What is Serializer? if you want to serialize your object, you should implement the interface Serializable. Here is my code:
public class RootClass implements Serializable{
private final int a;
public RootClass(int a) {
this.a = a;
}
public void print(){
System.out.println(a);
};
}
public class SubClass extends RootClass {
int b;
public SubClass() {
super(0);
this.b = 0;
}
public void print() {
super.print();
}
}
SubClass sub = new SubClass();
sub.print();
try {
File file = new File("SubClass");
if (!file.exists())
file.createNewFile();
FileOutputStream fileOut = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(sub);
out.close();
fileOut.close();
} catch (IOException i) {
i.printStackTrace();
}

You need to pass in the value for a like so.
class SubClass extends RootClass {
#Element(name="b")
int b;
public SubClass(#Element(name="a")int a) {
super(a);
this.b=0;
}
}
Or try this
class SubClassSubstitute {
#Element
int a;
#Element
int b
public SubClassSubstitute(#Element(name="a")int a, #Element(name="b")int b){
this.a = a;
this.b = b;
}
#Resolve
public SubClass resolve() {
return new Subclass(a)
}
}
class SubClass extends RootClass {
#Element(name="b")
int b;
public SubClass(#Element(name="a")int a) {
super(a);
this.b=0;
}
public SubClassDelegate replace() {
return new SubClassSubstitute(a, b);
}
}
The above works the same as readResolve() and writeReplace() in java object

Related

Deserialize json string to object with properties which are strings in jackson

I have a json string which looks like:
{"a":5, "b":"asd", "c":"{\"d\":3}"}
This can be deserialized to an object like:
class A {
int a; // --> 5
String b; // --> 'asd'
String c; // --> '{"d":3}'
}
but i want it to be deserialized as:
class A {
int a; // --> 5
String b; // --> 'asd'
MyClass c; // --> '{"d":3}'
}
where MyClass is:
class MyClass {
int d; // --> 3
}
How can I achieve this in jackson during deserialization?
I just found out that I can use the jackson converter:
public class MyClassConverter implements Converter<String, MyClass> {
#Override
public MyClass convert(String value) {
try {
return new ObjectMapper().readValue(value, MyClass.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
#Override
public JavaType getInputType(TypeFactory typeFactory) {
return typeFactory.constructSimpleType(String.class, null);
}
#Override
public JavaType getOutputType(TypeFactory typeFactory) {
return typeFactory.constructSimpleType(MyClass.class, null);
}
}
And in the Bean:
class A {
int a;
String b;
#JsonDeserialize(converter = MyClassConverter.class)
MyClass c;
}
Try to do the deserialization twice:
A aObject = mapper.readValue(json,A.class);
aObject.setCObject(mapper.readValue(aObject.getC(),C.class));
class A {
int a;
String b;
String c;
C cObject;
}
class C {
int d;
}

Access instance property from enclosed class

I'm a newbie on java, in this example is it possible to get the id of ClassA from ClassB?
public class ClassA {
private Long id;
private List<ClassB> listOfClassB;
[...]
}
public class ClassB {
private Long num;
public boolean isValidRow() {
return this.num > ***ClassA.this.getId()***;
}
[...]
}
For getting the id field of ClassA, you need to have an instance of ClassA in ClassB, for example:
public class ClassA {
private Long id;
private List<ClassB> listOfClassB;
[...]
}
public class ClassB {
private Long num;
private ClassA a;
public ClassB(Long num, ClassA a) {
this.num = num;
this.a = a;
}
public boolean isValidRow() {
return this.num > a.getId();
}
[...]
}
And initiate it this way:
new ClassB(1, new ClassA(...));
Try the following:
public class ClassB {
private ClassA a;
private Long num;
public ClassB(ClassA a){
this.a=a;
}
public boolean isValidRow() {
return this.num > a.getId();
}
}
Use it as follows:
...
ClassA a = new ClassA();
ClassB b = new ClassB(a);
...
Or if you create Bs inside A:
ClassB b = new ClassB(this);
This will work for nested classes only:
class ClassA {
private long id;
class ClassB {
ClassA.this.getId(); // Will work here
}
}
To make it work in your case you need inject instance of ClassA to instance of ClassB:
class ClassA {
long id;
}
class ClassB {
private ClassA a;
ClassB(ClassA a) {
this.a = a;
}
void someMethod() {
long id = a.getId();
}
}
You cannot get the id of ClassA, but you can get it from instance of ClassA
For example:
ClassA a =new ClassA():
ClassB b =new ClassB(a);
ClassA:
public class ClassA{
private Integer id;
public Integer getId(){return id;}
}
ClassB:
public class B {
//whatever
private A a;
public B(A a){
this.a=a;
}
public void someMethod(){
//whatever
t.getId() // here you have the id.
}
}
now everywhere in your ClassB you will have access to a.getId().

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;
}
}

extend class issue when creating new object

There's something wrong in my code, but i don't know why. I have two class:
public class MyClass extends MySuperClass {
potected int field1;
public MyClass() {
super();
}
#Override
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
}
public class MySuperClass {
potected int field1, field2;
public MySuperObject() {
}
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
public void setField2(int f) {
this.field2 = f;
}
public int getField2() {
return this.field2;
}
}
When i create different new MyClass object (i.e. for insert inside an ArrayList) something go wrong:
ArrayList<MyClass> list = new ArrayList<MyClass>();
while(condidion) {
MyClass obj = new MyClass();
obj.setField1(value1);
obj.setField2(value2);
list.add(obj);
}
If value1 and value2 assume the sequent value
1 and 50
2 and 70
3 and 80
After my code is executed, my list contains
1 and 80
2 and 80
3 and 80
It looks like that every time i create new MyClass object, only an instance of MySuperClass it's created (field2 assume the value of last input value).
How can i fix it?
Here is the code which you have given. It is working perfectly if you give correct input.
import java.util.ArrayList;
class MyClass extends MySuperClass {
protected int field1;
public MyClass() {
super();
}
#Override
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
}
class MySuperClass {
protected int field1, field2;
public MySuperClass() {
}
public int getField1() {
return this.field1;
}
public void setField1(int f) {
this.field1 = f;
}
public void setField2(int f) {
this.field2 = f;
}
public int getField2() {
return this.field2;
}
}
public class Tryouts {
public static void main(String[] args) {
int i = 0;
ArrayList<MyClass> list = new ArrayList<MyClass>();
while(i < 3) {
MyClass obj = new MyClass();
obj.setField1(40 + i);
obj.setField2(80+ i);
list.add(obj);
i++;
}
for (MyClass c : list) {
System.out.println(c.getField1() + "::" + c.getField2());
}
}
}
The output is
40::80, 41::81, 42::82

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