XML hierarchy with Java properties - java

Let's say I have a class Foo with some primitive instance variables. I initialize these with properties in XML files. Now every Foo also has a Bar as a variable, which in turn has its own properties. Since these are tied to the enclosing object, it would make sense to keep them in the same file. How should I format the XML so that it can initialize the object as well?

Use Spring. It's specifically designed to allow this type of object initialization, including handling inter-object references.

Take a look at XStream, which allows you to trivially serialise/deserialise a Java object hierarchy to/from XML.
At its simplest it'll work with a POJO, which no additional work (no interfaces/base classes etc. required). But you can customise how it serialises and deserialises to rename elements etc. to fit within an existing XML framework.

JAXB is worth a look:
public class JaxbDemo {
#XmlRootElement
public static class Foo {
#XmlElement public Bar bar;
}
public static class Bar {
#XmlAttribute public int baz;
}
public static void main(String[] args) {
String xml = "<foo><bar baz='123'/></foo>";
Foo foo = JAXB.unmarshal(new StringReader(xml), Foo.class);
System.out.println(foo.bar.baz);
}
}
(Public members used for demo purposes.)

Related

Is it supposed that developers should implement their own XXXProperties in JavaFX?

I am reading about javafx properties and can't understand why non abstract classes we can use for creating instances of properties (for example SimpleStringProperty) have Simple word in their names. As I know Simple in implementation means basic implementation of something.
Is it supposed that developers should implement their own XXXProperty that must extend XXXPropertyBase in JavaFX?
Let's consider for example SimpleStringProperty.
java.lang.Object
javafx.beans.binding.StringExpression
javafx.beans.property.ReadOnlyStringProperty
javafx.beans.property.StringProperty
javafx.beans.property.StringPropertyBase
javafx.beans.property.SimpleStringProperty
Should we develop our own OurStringProperty that will extend StringPropertyBase?
At the same time in javadoc it is said that javafx.beans.property.StringProperty class provides a full implementation of a Property wrapping a String value. So why do we need this SimpleStringProperty? How to explain it?
Here is a sample how to add a simple Object-based property to your class using the implementations provided by JavaFX (similar classes exist for String and primitive types):
private final ObjectProperty<Foo> foo = new SimpleObjectProperty<>(this,
"foo", null);
public final Foo getFoo() {
return fooProperty().get();
}
public final void setFoo(Foo foo) {
fooProperty().set(foo);
}
public ObjectProperty<Foo> fooProperty() {
return foo;
}
Here is a sample of a read-only property implementation based on some base classes provided by JavaFX:
public class MyClass {
private final ReadOnlyBarProperty bar = new ReadOnlyBarProperty();
public final Bar getBar() {
return barProperty().get();
}
private void setBar(Bar bar) {
this.bar.set(bar);
}
public ReadOnlyObjectProperty<Bar> barProperty() {
return bar;
}
[...]
private class ReadOnlyBarProperty extends ReadOnlyObjectPropertyBase<Bar> {
private Bar bar = null;
#Override
public final Bar get() {
return bar;
}
private void set(Bar newValue) {
if (!Objects.equals(bar, newValue)) {
bar = newValue;
fireValueChangedEvent();
}
}
#Override
public Object getBean() {
return MyClass.this;
}
#Override
public String getName() {
return "bar";
}
}
}
Then there are some rare cases where you want to provide your own property implementation. E.g. I've written a SimpleEventHandlerProperty in Drombler Commons.
I hope these samples cleared things up a bit.
It depends.
There is a fairly common pattern in the standard JavaFX libraries of creating local or anonymous classes that extend one of the "base" classes (ReadOnlyXXXPropertyBase or XXXPropertyBase). In my experience, this is done usually for one of two reasons:
It's a read-only property whose value is managed from outside the property.
Something must happen internally when the property is invalidated.
To see an example of the first case take a look at the source code of ListPropertyBase. This property class has two properties of its own, empty and size, inherited from ListExpression. These properties, as expected, reflect the empty and size states of the contained ObservableList. The way these properties are implemented are as local classes but their values are managed by the ObservableList itself. The ListPropertyBase class simply has them fire change events when appropriate.
For the second case, the local or anonymous class will override the protected invalidated method provided by most (all?) of the XXXPropertyBase classes. This method is called when the property is invalidated. It allows one to react without the overhead of a listener. You can see this in action by looking at the source code of ButtonBase. For example, the onAction property:
public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; }
public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); }
public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); }
private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() {
#Override protected void invalidated() {
setEventHandler(ActionEvent.ACTION, get());
}
#Override
public Object getBean() {
return ButtonBase.this;
}
#Override
public String getName() {
return "onAction";
}
};
When the property is invalidated, the invalidated method registers/unregisters the EventHandler from the Node.
With all that said, if you don't need to add customized behavior stick to using ReadOnlyXXXWrapper for read-only properties and SimpleXXXProperty for read-write properties.
Simple?
Why do the concrete implementations have Simple in their name? Why not just have XXXProperty be the concrete implementation?
I can't give a definitive answer, as I wasn't involved in development, but I can offer a guess: The JavaFX developers wanted to provide multiple "extension points" that offer various degrees of "already implemented". Need full customization? Extend XXXProperty. Need some customization? Extend XXXPropertyBase. And so on.
And the SimpleXXXProperty classes needed names that didn't conflict with the XXXProperty class names. Simple fits because that's what they are—simple implementations. They do nothing but what the interfaces require.
Worth Mentioning
On an API level, virtually every JavaFX class exposes properties as either ReadOnlyXXXProperty or XXXProperty. Never is it Property<SomeObject> or SimpleXXXProperty. Basically, when it comes to properties, consider using ReadOnlyXXXProperty and XXXProperty as "programming to the interface". Just like you'd expose List instead of ArrayList.
I'd also consider that quote:
This class provides a full implementation of a Property wrapping a String value.
To be misleading. If you look at the source of StringProperty is is certainly not a "full implementation". Maybe it's trying to say its the API level class? Maybe it's trying to say it implements all the necessary interfaces? Honestly, I have no idea...

JAVA Is it possible to dynamically have a class extend another?

I've been at this since yesterday looking for a way to do this. What I have are hundreds of POJOs from a third party and need to apply properties to these based on business rules. I'm avoiding the altering of the POJOs because the third party could potentially recreate them thus creating a nightmare for managing files down the road.
What I'm attempting to do is to dynamically have a class extend another class.
For example.
POJO: Foo.java
package abc.service;
public class Foo {
private String greeting = "";
public Foo(){
gretting = "Good morning";
}
public String getGreeting(){
return greeting;
}
}
// end file
Mine: Bar.java
package abc.service;
public class Bar {
private String claim = "";
public Bar(){
claim = "You're correct";
}
public String getClaim(){
return claim;
}
}
// end file
Mine: TestMe.java
Trying here in a class separate from the POJOs to have a POJO extend another of my classes.
Is this beyond the abilities of JAVA?
package abc;
public class TestMe {
Foo f = new Foo();
Class c1 = f.getClass();
Bar b = new Bar();
Class c2 = b.getClass();
Class merged = c2.asSubclass(c1);
// Trying to call the Foo method
System.out.println(merged.getGreeting());
// Trying to call the Bar method
System.out.println(merged.getClaim());
}
Additionally what is going on is that JSON schemas are being created from the POJOs that are provided. But the POJOs are only based on an UPDATE record scenario. I'm looking for the best way to have the POJOs extend another class for CREATE record scenarios which is why I'm looking to dynamically have their POJOs extend my code when required.
Need to generate json schema for the POJOs for UPDATE
Need to verifying their json meets the POJOs requirements for UPDATE
Need to convert their json to the POJOs for UPDATE
Also,
Need to generate json schema for the POJOs for CREATE
Need to verifying their json meets the POJOs requirements for CREATE
Need to convert their json to the POJOs for CREATE
Using Jackson Mixin and the ObjectMapper I'm able to dynamically apply my code to the classes when creating the schemas but the issue I'm having is when trying to have the POJOs extend the class where Mixin is not going to solve the issue.
With plain Java: no, it can't be done.
You can change byte code, either in the build process, or at runtime. But it's hard, and there's not a lot of documentation.
AspectJ's declare parents expression is probably the easiest way to do it at build time.
If you want to do it at runtime, look at frameworks like asm, CGLib or ByteBuddy. But you will have to run the code from inside a custom ClassLoader or agent.
You can use composition instead of inheritance.
public class Foo {
private String greeting = "";
public Foo(){
gretting = "Good morning";
}
public String getGreeting(){
return greeting;
}
}
Your class
public class Bar {
private String claim = "";
private Foo foo;
public Bar(){
claim = "You're correct";
foo = new Foo();
}
public String getClaim(){
return claim;
}
public Foo getFoo(){
return foo;
}
}
And the test
public class TestMe {
// Trying to call the Foo method
System.out.println(bar.getFoo().getGreeting());
// Trying to call the Bar method
System.out.println(bar.getClaim());
}
Or you can do you class a little bit different.
public class Bar {
private String claim = "";
private Foo foo;
public Bar(){
claim = "You're correct";
foo = new Foo();
}
public String getClaim(){
return claim;
}
public String getGreeting(){
return foo.getGreeting();
}
}
And the test
public class TestMe {
// Trying to call the Foo method
System.out.println(bar.getGreeting());
// Trying to call the Bar method
System.out.println(bar.getClaim());
}
It is Not Possible.
Simply to put, JAVA at present(till latest version) does not have a provision to dynamically extend the class at runtime and load to JVM.
Instead of extending, you should use a design pattern. For example the Stategy Pattern. This allows you to change your strategy dynamicaly.

Should UUID be passed in or generated on construction of POJO?

When creating a POJO it is bad practice to set any attributes in the constructor without passing them in because of dependency injection.
If you are setting one of the fields to a UUID value is this acceptable to be generated and set on construction? Or should it be passed in through the constructor?
Or is there a general pattern used for this?
I would definitely have a constructor that accepts a UUID for the reasons you already outlined. (And testing.)
However I would also add a static factory method that only accepts the values you really want to set externally in regular code. So something like this:
public class Foo {
private final UUID id;
private final Bar bar;
Foo(UUID id, Bar bar) {
this.id = id;
this.bar = bar;
}
public static Foo create(Bar bar) {
return new Foo(UUID.randomUUID(), bar);
}
}
I specified the constructor as package-private, which is permissive enough for testing (if you happen to need it), and only leaves one publicly visible way to create instances of the class.

Serialize one class in two different ways with Jackson

In one of our projects we use a java webapp talking to a MongoDB instance. In the database, we use DBRefs to keep track of some object relations. We (de)serialize with POJO objects using jackson (using mongodb-jackson-mapper).
However, we use the same POJOs to then (de)serialize to the outside world, where our front end deals with presenting the JSON.
Now, we need a way for the serialization for the outside world to contain the referenced object from a DBRef (so that the UI can present the full object), while we obviously want to have the DBRef written to the database, and not the whole object.
Right now I wrote some untested static nested class code:
public static class FooReference {
public DBRef<Foo> foo;
// FIXME how to ensure that this doesn't go into the database?
public Foo getFoo() {
return foo.fetch();
}
}
Ideally I would like a way to annotate this so that I could (de)serialize it either with or without the getFoo() result, probably depending on some configuration object. Is this possible? Do you see a better way of going about doing this?
From looking at options, it seems you can annotate properties to only be shown if a given View is passed to the ObjectMapper used for serialization. You could thus edit the class:
public static class FooReference {
public DBRef<Foo> foo;
#JsonView(Views.WebView.class)
public Foo getFoo() {
return foo.fetch();
}
}
and provide:
class Views {
static class WebView { }
}
and then serialize after creating a configuration with the correct view:
SerializationConfig conf = objectMapper.getSerializationConfig().withView(Views.WebView.class);
objectMapper.setSerializationConfig(conf);
Which would then serialize it. Not specifying the view when serializing with the MongoDB wrapper would mean the method would be ignored. Properties without a JsonView annotation are serialized by default, a behaviour you can change by specifying:
objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
More info is available on the Jackson Wiki.
There are still other alternatives, too, it turns out: there are Jackson MixIns which would let you override (de)serialization behaviour of parts of a class without modifying the class itself, and as of Jackson 2.0 (very recent release) there are filters, too.
Use a custom JSONSerializer and apply your logic in the serialize method:
public static class FooReference {
public DBRef<Foo> foo;
#JsonSerialize(using = CustomSerializer.class)
public Foo getFoo() {
return foo.fetch();
}
}
public class CustomSerializer extends JsonSerializer<Object> {
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
// jgen.writeObjectField ...
}
}

Xstream: Implicitly ignoring all fields

How do I tell Xstream to serialize only fields which are annotated explicitly and ignore the rest?
I am trying to serialize a hibernate persistent object and all proxy related fields get serialized which I don’t want in my xml.
e.g.
<createdBy class="com..domain.Users " reference="../../values/createdBy"/>
is not something I want in my xml.
Edit: I don’t think I made this question clear. A class may inherit from a base class on which I have no control (as in hibernate’s case) on the base class properties.
public class A {
private String ShouldNotBeSerialized;
}
public class B extends A {
#XStreamAlias("1")
private String ThisShouldbeSerialized;
}
In this case when I serialize class B, the base class field ShouldNotBeSerialized will also get serialized. This is not something I want. In most circumstances I will not have control on class A.
Therefore I want to omit all fields by default and serialize only fields for which I explicitly specify the annotation. I want to avoid what GaryF is doing, where I need to explicitly specify the fields I need to omit.
You can omit fields with the #XstreamOmitField annotation. Straight from the manual:
#XStreamAlias("message")
class RendezvousMessage {
#XStreamOmitField
private int messageType;
#XStreamImplicit(itemFieldName="part")
private List<String> content;
#XStreamConverter(SingleValueCalendarConverter.class)
private Calendar created = new GregorianCalendar();
public RendezvousMessage(int messageType, String... content) {
this.messageType = messageType;
this.content = Arrays.asList(content);
}
}
I can take no credit for this answer, just sharing what I have found. You can override the wrapMapper method of the XStream class to achieve what you need.
This link explains in detail: http://pvoss.wordpress.com/2009/01/08/xstream/
Here is the code you need if you don't want the explanation:
// Setup XStream object so that it ignores any undefined tags
XStream xstream = new XStream() {
#Override
protected MapperWrapper wrapMapper(MapperWrapper next) {
return new MapperWrapper(next) {
#Override
public boolean shouldSerializeMember(Class definedIn,
String fieldName) {
if (definedIn == Object.class) {
return false;
}
return super
.shouldSerializeMember(definedIn, fieldName);
}
};
}
};
You might want to do all your testing before you implement this code because the exceptions thrown by the default XStream object are useful for finding spelling mistakes.
There was already a ticket for the XStream people:
Again, this is by design. XStream is a serialization tool, not a data
binding tool. It is made to serialize Java objects to XML and back. It
will write anything into XML that is necessary to recreate an equal
object graph. The generated XML can be tweaked to some extend by
configuration for convenience, but this is already an add-on. What you
like to do can be done by implementing a custom mapper, but that's a
question for the user's list and cannot be handled here.
http://jira.codehaus.org/browse/XSTR-569
I guess the only direct way is to dive into writing a MapperWrapper and exclude all fields you have not annotated. Sounds like a feature request for XStream.

Categories