-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Starting with a simple class for a person
package xstreamfxextensions;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@XStreamAlias("Person") //define class level alias
public class Person {
@XStreamAlias("Sex")
public enum Sex {
MALE, FEMALE, UNKNOWN, OTHER
};
public StringProperty name = new SimpleStringProperty(this, "name", "nameless");
public IntegerProperty age = new SimpleIntegerProperty(this, "age", 0);
public ObjectProperty<Sex> sex = new SimpleObjectProperty<>(this, "sex", Sex.MALE);
public ObservableList<Person> children = FXCollections.<Person>observableArrayList();
public Person(String name, int age, Sex sex) {
this.name.set(name);
this.age.set(age);
this.sex.set(sex);
}
@Override
public String toString() {
return "Person{"
+ "name=" + name.get()
+ ", age=" + age.get()
+ ", sex=" + sex.get()
+ ", children=" + children
+ '}';
}
}
A simple test class to use XStream and XStreamFX to externalise and internalise some people.
package xstreamfxextensions;
import com.dooapp.xstreamfx.FXConverters;
import com.sun.javafx.collections.ObservableListWrapper;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleMapProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleSetProperty;
import javafx.beans.property.SimpleStringProperty;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.xml.sax.InputSource;
import xstreamfxextensions.Person.Sex;
public class XStreamFXExtensionsTest {
/**
* Add XStream aliases for common JavaFX types
*
* @param xstream
*/
public static void addFXAliases(XStream xstream) {
Class[] cs = new Class[]{
ObservableListWrapper.class,
// The Simple... properties
SimpleStringProperty.class,
SimpleIntegerProperty.class,
SimpleObjectProperty.class,
SimpleFloatProperty.class,
SimpleBooleanProperty.class,
SimpleListProperty.class,
SimpleLongProperty.class,
SimpleMapProperty.class,
SimpleSetProperty.class,
SimpleFloatProperty.class,};
for (Class c : cs) { //
// Alias the class's simple name to its pull name
xstream.alias(c.getSimpleName(), c);
}
}
@Test
public void testSXtreamPerson() throws IOException {
XStream xstream = new XStream(new StaxDriver());
Person fred = new Person("Fred", 71, Sex.MALE);
fred.children.add(new Person("Paul", 21, Sex.MALE));
fred.children.add(new Person("James", 20, Sex.MALE));
fred.children.add(new Person("Angela", 20, Sex.FEMALE));
xstream.autodetectAnnotations(true);
FXConverters.configure(xstream);
addFXAliases(xstream);
//Object to XML Conversion
String xml = formatXml(xstream.toXML(fred));
Files.write(Paths.get("PeopleImplicit.xml"), xml.getBytes());
//XML to Object Conversion
Person a = (Person) xstream.fromXML(xml);
System.out.println(a);
}
public static String formatXml(String xml) {
try {
Transformer serializer = SAXTransformerFactory.newInstance().newTransformer();
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
Source xmlSource = new SAXSource(new InputSource(new ByteArrayInputStream(xml.getBytes())));
StreamResult res = new StreamResult(new ByteArrayOutputStream());
serializer.transform(xmlSource, res);
return new String(((ByteArrayOutputStream) res.getOutputStream()).toByteArray());
} catch (Exception e) {
return xml;
}
}
}
Running this results in error:
Testcase: testSXtreamPerson(xstreamfxextensions.XStreamFXExtensionsTest): Caused an ERROR
Cannot instantiate com.sun.javafx.collections.ObservableListWrapper : com.sun.javafx.collections.ObservableListWrapper
---- Debugging information ----
message : Cannot instantiate com.sun.javafx.collections.ObservableListWrapper
cause-exception : java.lang.InstantiationException
cause-message : com.sun.javafx.collections.ObservableListWrapper
class : com.sun.javafx.collections.ObservableListWrapper
required-type : com.sun.javafx.collections.ObservableListWrapper
converter-type : com.dooapp.xstreamfx.ObservableListConverter
path : /Person/children
line number : 5
class[1] : xstreamfxextensions.Person
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version : 1.4.8
-------------------------------
com.thoughtworks.xstream.converters.ConversionException: Cannot instantiate com.sun.javafx.collections.ObservableListWrapper : com.sun.javafx.collections.ObservableListWrapper
---- Debugging information ----
message : Cannot instantiate com.sun.javafx.collections.ObservableListWrapper
cause-exception : java.lang.InstantiationException
cause-message : com.sun.javafx.collections.ObservableListWrapper
class : com.sun.javafx.collections.ObservableListWrapper
required-type : com.sun.javafx.collections.ObservableListWrapper
converter-type : com.dooapp.xstreamfx.ObservableListConverter
path : /Person/children
line number : 5
class[1] : xstreamfxextensions.Person
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version : 1.4.8
-------------------------------
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.createCollection(AbstractCollectionConverter.java:79)
at com.thoughtworks.xstream.converters.collections.CollectionConverter.createCollection(CollectionConverter.java:103)
at com.dooapp.xstreamfx.ObservableListConverter.createCollection(ObservableListConverter.java:40)
at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:79)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1052)
at xstreamfxextensions.XStreamFXExtensionsTest.testSXtreamPerson(XStreamFXExtensionsTest.java:77)
Caused by: java.lang.InstantiationException: com.sun.javafx.collections.ObservableListWrapper
at java.lang.Class.newInstance(Class.java:427)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.createCollection(AbstractCollectionConverter.java:77)
Caused by: java.lang.NoSuchMethodException: com.sun.javafx.collections.ObservableListWrapper.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
I found modifying ObservableListConverter to
package com.dooapp.xstreamfx;
import com.sun.javafx.collections.ObservableListWrapper;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.collections.CollectionConverter;
import com.thoughtworks.xstream.mapper.Mapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import xstreamfxextensions.Person;
/**
* TODO write documentation<br>
* <br>
* Created at 21/09/11 09:32.<br>
*
* @author Antoine Mischler <[email protected]>
* @since 2.2
*/
public class ObservableListConverter extends CollectionConverter implements Converter {
public ObservableListConverter(Mapper mapper) {
super(mapper);
}
@Override
public boolean canConvert(Class type) {
return ObservableList.class.isAssignableFrom(type);
}
@Override
protected Object createCollection(Class type) {
if (type == ObservableListWrapper.class) {
return FXCollections.<Person>observableArrayList();
}
return super.createCollection(type);
}
}
Explanation: ObservableListWrapper does not have a no argument constructor but has to be created with the FXCollections.observableArrayList() factory method.
So all well and good...
Until you try to to mark the collection with @XStreamImplicit In which case you get the same problem.
Any help with this gratefully appreciated!
Metadata
Metadata
Assignees
Labels
No labels