I'm trying to implement a version of Gang of Four's Prototype Pattern using MOXy/JAXB 2.5.0. I want to be able to specify a list of items, some of which are "based on" others, i.e. copy their data from other instances. For reusability, I'd like to create an interface that any prototype-able object should implement, which will provide annotation for the properties necessary to support the pattern.
#XmlRootElement(name="IPrototype")
public interface IPrototype
{
/**
* Acts as a "copy constructor"
*/
#XmlAttribute(name="prototype")
#XmlIDREF
public void setPrototype(IPrototype prototype);
#XmlAttribute(name="id")
#XmlID
public void setId(String id);
public String getId();
}
An implementing object would ideally look something like this, not even having to bother with annotation of the methods implemented from the interface:
#XmlRootElement(name="Item")
public class Item implements IPrototype
{
private String m_id = null;
private String m_data = null;
public Item()
{
}
/**
* Never called
*/
#Override
public void setPrototype(IPrototype prototype)
{
m_data = ((Item)prototype).getData();
}
#Override
public void setId(String id)
{
m_id = id;
}
#Override
public String getId()
{
return m_id;
}
#XmlAttribute(name="data")
public void setData(String data)
{
m_data = data;
}
public String getData()
{
return m_data;
}
}
And the XML would look like:
<Wrapper>
<Item id="Item1" data="stuff and things" />
<Item id="Item2" prototype="Item1" />
</Wrapper>
where Wrapper is defined as:
#XmlRootElement(name="Wrapper")
public class Wrapper
{
#XmlElementRef
private ArrayList<Item> m_items = null;
}
If it worked the way I want, I would get a list with two elements, both of type Item, that contain the same data. However, MOXy doesn't seem to "see" the annotations on the interface, and I get a list with two Items that don't have their XmlID set, and setPrototype() is never called. The only solution appears to be annotating the setPrototype() and setId() methods in the Item class, but this appears to require changing setPrototype()'s argument type from IPrototype to Item so MOXy will look for the XmlID in the right class. Unfortunately, this breaks the inherited interface.
If I instead change the list type to IPrototype, hoping that would allow MOXy to see its annotations, I get the same behavior - null ID's, setPrototype() never called. This isn't really what I want anyways, I'd like to be able to constrain which subtypes may be included in a particular list.
Not sure I have correct expectations for how interface annotations are supposed to work, maybe that's the source of my error.
Any thoughts on how to get this working? Thanks in advance,
Steve
UPDATE: If I annotate the Item class, WITHOUT changing setPrototype's method signature (which I guess I can live with), I get a list with two items, with correctly set XmlID's, but setPrototype() is still not called. Seems like MOXy is looking for instances of IPrototype (impossible) with the same XmlID, not Item instances.
UPDATE 2: And, if I convert IPrototype into an abstract class, everything works perfectly. However, given Java's single inheritance model, this is too limiting for a framework object that is intended to supplement multiple inheritance hierarchies. So still stuck.
I got a somewhat acceptable version of this running by annotating Item's properties and declaring setPrototype() using generics. This is what the declaration looks like in IPrototype:
public <T> void setPrototype(T prototype);
And here's its implementation in Item:
#XmlAttribute(name="prototype")
#XmlIDREF
#Override
public <T> void setPrototype(T prototype)
{
m_data = ((Item)prototype).getData();
}
It works, but I don't particularly like having to re-annotate the subclass. I've opened a separate question about that, since it doesn't intuitively (to me) seem like that's the way interface annotations should work:
MOXy/JAXB interface annotation
You can use MOXy's external binding document to override the super class of the implementing clases (i.e. Item) from Object to the interface IPrototype. This will allow you to inherit the mappings from the interface.
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum16807019">
<java-types>
<java-type name="Item" super-type="forum16807019.IPrototype"/>
</java-types>
</xml-bindings>
For a complete example see:
MOXy/JAXB interface annotation
Related
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...
Lets say I have a Namespace class like follows:
abstract class Namespace {
protected prefix;
protected Map<String, String> tags;
public setTag(String tagKey, String tagValue) {
tags.put(tagKey, tagValue);
}
}
I have been told that a good design is to have separate implementations of each namespace with getters defining the information being retrieved from the tags map. ie.
class FooNamespace extends Namespace {
public String getNameTag() {
return tags.get("name");
}
}
We can have separate implementations of a namespace like BarNamespace which will have different tags stored (BarNamespace does not have a name tag for ex. and instead has an age tag). Why does the above design make more sense than simply having the consumer of a simple Namespace class request the tag they want. ie:
class Namespace {
private prefix;
private Map<String, String> tags;
public String getTag(String key) {
return tags.get(key);
}
}
The above is used like
Namespace.getTag("name");
The answer depends a lot on what you wish to achieve - but if I have to type getTag("name") a few hundred times, I'm bound to make a mistake.
getNameTag takes out some of the guess work and reduces the possibility that I'll type "name" wrong without noticing. It also reduces the amount of knowledge I need to have about the API - I know I can get the value for the name tag, but I don't need to know how that is actually implemented - and it might change between implementations.
Is it a "good design" is a matter of opinion and is dependent on how the intended class is to be used. Is "name" common enough in the application to be useful? What about "date" or "numeric" values - some helper methods there might be nice ;)
The one thing that bugs me about this is that while Bar does not have an accessor for "name", its backed by an abstract Namespace class that contains a raw Map so anyone can shove in a "name" tag by doing a Bar.putTag("name", "nameValue"); Any ideas on how to implement the "setters"?
This is also a bug-bear I have to the collections API generally.
You could create a non-mutable and mutable concepts...
public interface Namespace {
public String getTag(String key);
}
public interface MutableNamespace extends Namespace {
public void setTag(String key, String value);
}
Then you can begin to abstract those...
public abstract class AbstractNamespace implements MutableNamespace {
private prefix;
private Map<String, String> tags;
public setTag(String tagKey, String tagValue) {
tags.put(tagKey, tagValue);
}
public String getTag(String key) {
return tags.get(key);
}
}
And finally provide useful implementations for the context that it might be used in...
public interface MySuperHelpfulNamespace extends Namespace {
public String getNameTag();
}
public class DefaultMySuperHelpfulNamespace extends AbstractNamespace implements MySuperHelpfulNamespace {
public String getNameTag() {
return tags.get("name");
}
}
Then write you app to support them...
public void someMethodWhichDoesNotNeedToChangeTheValues(MySuperHelpfulNamespace namespace) {
//...
}
public void someMethodWhichDoesNeedToChangeTheValues(MutableNamespace namespace) {
//...
}
This is essentially an example of "coding to interface (not implementation)
The problem stems from..
Your attempt to reuse Namespace via inheritance for it's property: the Map.
The idea behind object orientation is to..
Tell objects to perform behaviors.
What is an Object?
Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.
When ClassA extends ClassB, the subtype ClassA should inherit the behaviors, or the public interface, of it's supertype ClassB. Your Namespace type doesn't seem to define any behaviors.
You may consider the setter or getter to be behaviors,
But don't be fooled. There is currently no reason for a developer to prefer your Namespace type over just using a Map, other than changing the interface they use from get to getTag.
getter & setter methods violate OOP. Feel free to read up on the discussion.
How should Namespace actually be used? What requirement is it fufilling? What behaviors should Namespace define?
You can answer this by analyzing how the getter is being used. To give an example, maybe you plan to append it to a StringBuilder to conjure some XML.
Imagine your requirement was..
Append an individual tag from a variety of XML tag sets to a StringBuilder that'll be used for rendering.
Instead of doing..
StringBuilder builder = ...;
Namespace namespace = ...;
builder.append(namespace.getTag("name"));
Namespace could be responsible for appending it's tags (Namespace is the owner of the Map storing the tags) to whatever is requesting it.
public final class Namespace {
private final Map<String, String> tags;
public Namespace(Map<String, String> tags) {
this.tags = tags;
}
// if you REALLY need to add tags after instantiation
public Namespace addTag(String key, String value) {
Map<String, String> tags = new HashMap<>(this.tags);
tags.put(key, value);
return new Namespace(tags);
}
// the behavior that fufills the requirement
public void appendTo(StringBuilder builder, String key) {
builder.append(tags.get(key));
}
}
Notice how Namespace has behavior (appends to a StringBuilder) rather than act as a proxy for Map.
StringBuilder builder = ...;
Namespace namespace = ...;
namespace.appendTo(builder, "name");
I'm not looking for reasons to create subtypes (not forcing it). You should only create subtypes when you must extend upon the behavior of the supertype. If BarNamespace doesn't add any functionality to Namespace, there's no need for it.
After creating Namespace to cover the functionality your post exposes, I had no need for subtypes. It seemed as if everything was elegantly handled by Namespace.
You didn't specify your requirements, but hopefully this answer will guide you towards determining them (based on how you're using the getter) and implementing them in an object oriented manner.
As #MadProgrammer pointed out:
if I have to type getTag("name") a few hundred times, I'm bound to make a mistake.
If you find yourself needing to type "name" quite often, then you may wanna include a type-safe way for performing that behavior.
In a situation like this, you could prefer composition over inheritance. Instead of having subtypes extend Namespace, you could create types that reference a Namespace to perform what you want to do.
public final class Bar {
private final Namespace namespace;
public Bar(Namespace namespace) {
this.namespace = namespace;
}
public void appendNameTo(StringBuilder builder) {
namespace.appendTo(builder, "name");
}
}
You may say "Wait! I wanna pass Bar to where a Namespace is expected!"
This would be pointless. If code relies on Namespace, there would be no type safety to be expected, even in your code. For example:
void doSomething(Namespace namespace) {
}
Unless you casted or declares appendNameTo to Namespace, you wouldn't have access to any methods defined in Bar anyways. You said subtypes may have different tags. This means if you're going for type safety, your subtypes would all have different public interfaces, hence why I didn't extend Namespace.
I have multiple services (in Spring MVC) that are children of a global Service. So I need to know about the best practice (or your opinions) with multiple methods with this example:
//Domain classes
public class MyParentObject{}
public class MyObj extends MyParentObject{}
//Services
public class MyParentObjectServiceImpl implements MyParentObjectService{
#Override
public MyParentObject findObjectByProp(String prop, String objectType){
//myCode (not abstract class)
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl implements MyObjectService{
private myObjType = "MyObj";
#Override
public MyObj findMyObjByProp(String prop){
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
And in this approach, I use calls like this:
MyObj foo = myObjService.findMyObjByProp(prop);
So I need to know if this approach is "better" or more apropiate that calling directly the parent method with the second parameter. E.g:
MyObj foo = (MyObj)myParentObjectService.findObjectByProp(prop, "MyObj");
..and avoiding the creation of second methods, more specific. It is important to know that the children services will be created anyway, because we have lot of code that is specific of a domain objects.
I have the idea that the first approach is better, because is more readable, but I need to support that decision with some documents, blog, or opinions to discuss this designs with my colleagues.
This looks like a tagged class hierarchy. It's difficult to comment on the value of this design in general without knowing the details. However, a slightly different approach that I would recommend is to generify your base class to gain a little bit of type safety.
In particular:
public /* abstract */ class MyParentObjectServiceImpl<T extends MyParentObject>
implements MyParentObjectService{
MyParentObjectServiceImpl(Class<T> type) { this.type = type; }
private final Class<T> type; // subclasses provide this
#Override
public T findObjectByProp(String prop){
//you can use type for object specific stuff
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl<MyObj>
// You might not need this interface anymore
// if the only method defined is findMyObjByProp
/* implements MyObjectService */ {
MyObjServiceImpl() {
super(MyObj.class);
}
#Override
public /* final */ MyObj findMyObjByProp(String prop) {
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
You definitely gain in type safety (casting will only appear in the base class), you get rid of the "tags" (the strings that identify the different objects) and possibly reduce the number of classes/interfaces required to implement the whole hierarchy. I successfully used this approach several times. Note that this works best if the base class is abstract. Food for thoughts.
//Interface DAO
public abstract class BaseDAO<T extends BaseDTO> {
public void update(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to update database object academic or event
}
public Integer create(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to create academic or event in database
}
}
//Concrete DAOs
public class AcademicDAO extends BaseDAO<AcademicDTO> {
//provide implementation
}
public class EventDAO extends BaseDAO<EventDTO> {
//provide implementation
}
//Transfer object
public class AcademicDTO extends BaseDTO {
String title;
String surname;
//getters and setters
}
public class BaseDTO {
protected Integer ID;
public Integer getID() {
return ID;
}
public void setID(Integer ID) {
this.ID = ID;
}
}
Hello Guys, I have a sample code on me that follows the above structure to create a small java application to manage academics and events. It is leniently following this pattern
1- You experts are familiar with this pattern more than me. I would like to understand why generics are used in this case so DAOs can extend and implement a generic base class. It would be great if one can show how generics here may be advantageous using an example.
2 - I have also witnessed the use of java Fields. Is there a link between generics and Fields?
I would like to document DAO pattern in an academic report, but I am finding difficult to understand how Generics and Reflect Field play a part here. Do they support flexibility and loose coupling?
The code you've provided is reusable set of logic to load and persist entities. Many times, in an application of non-trivial size, you'll wind up persisting many different types of objects. In this example, you can define as many objects as necessary, but only define the logic to actually save and load once. By asking the DTO what Field objects are there, it can get at the data to help construct queries for loading and saving.
Generics allow you to use this pattern while maintaining type safety. AcademicDAO can only handle AcadmeicDTO. You can't use AcademicDAO to store EventDTO. Generics allow the instance of the class to rely on a more specific type when dealing with the Field objects. If you didn't have generics, the BaseDAO would take Object, and you wouldn't be able to access any methods except those that Object provides because the JVM wouldn't know what class is provided, so it has to limit it's knowledge to that of Object. Using getClass().getDeclaredFields() bypasses that limitation because getClass() returns the actual class of the Object parameter.
Field is just a way to use reflection to access the values of the properties in each DTO. If you had to access the fields directly, with getTitle(), you couldn't reuse a generic base class to do your persistence. What would happen when you needed to access EventDTO? You would have to provide logic for that. Field allows you to skip that logic.
Edit:
To explain what I mean by accessing getID, you could do the following within BaseDAO because T is known to be a BaseDTO with a getID() method defined:
public abstract class BaseDAO<T extends BaseDTO> {
public boolean update(T t) throws DBException {
Integer id = t.getID();
Field[] fields = t.getClass().getDeclaredFields();
// Assuming you have a db object to execute queries using bind variables:
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
}
If you had this instead (in a non-generic class):
public boolean update(Object o) throws DBException {
// This line doesn't work, since Object doesn't have a getID() method.
Integer id = t.getID();
Field[] fields = o.getClass().getDeclaredFields();
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
You'd have to look through those Field objects, or ask for the ID field and assume it existed.
For question 1. The use of generics allows the same implementations of update and create to be used regardless of the type of the DTO. Consider if you didn't use generics. Then the best you could do for the parameter type of update would be BaseDTO, but then you could call
academicDAO.update( eventDTO )
which doesn't make sense. With the code as you have it, this would be a type error. So the main advantage is: better type checking.
For question 2. The use of Fields allows a single implementation of update and create to work on DTO object of various concrete types.
Apologies in advance. This seems like a simple task, but hours later on Google and with guess/check, I still can't figure it out.
I'm writing a Java convenience wrapper library for an API my company provides. One of the classes looks something like this:
class View extends Model<View>
{
List<Column> columns;
Column primaryColumn;
}
However, our API actually wants a primaryColumnId integer, not an actual Column object. I want to maintain the strongly-typed getPrimaryColumn() and setPrimaryColumn(Column) in the library to reduce developer error, but I'm having significant difficulty writing some sort of translation between the getter/setter that we need to ser/deser to/from JSON.
I'm using the standard Bean serialization strategy. I'd like to avoid the wholly-custom approach because in reality View has dozens of fields. Here's what I've figured out so far.
I think (haven't tested yet) that I can handle the serialization case simply by creating a custom JsonSerializer that looks something like:
public static class ColumnIdSerializer extends JsonSerializer<Column>
{
#Override
public void serialize(Column column, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeFieldName("primaryColumnId");
jsonGenerator.writeNumber(column.id);
}
}
And then assigning the annotation to the appropriate place:
#JsonSerialize(using = Column.ColumnIdSerializer.class)
public Column getPrimaryColumn() { /* ... */ }
This allows me to serialize the id rather than the whole class, and rename the key from primaryColumn to primaryColumnId.
Now, we get to deserialization. Here I run into three problems.
The first is that in order to successfully deserialize the column from the id, we have to first have the list of columns. This is solvable using #JsonPropertyOrder on the class. Great, that's done.
The second is that I need to tell Jackson to look under primaryColumnId rather than primaryColumn for the value. I don't know how to do this; the JsonDeserializer appears to kick in after the key has already been found, so it's too late to modify it. JsonSchema looks like it might be relevant but I can't find any documentation or internet chatter on how to use it.
The third is that from the custom JsonDeserializer class I'll have to be able to reference the View that's being deserialized in order to ask it for a Column in return for my id int. There doesn't appear to be a way to do that.
Should I just cave and add a public getPrimaryColumnId() and setPrimaryColumnId(Integer), or is there a way to overcome these obstacles?
So I'd propose something like this:
class CustomView
{
private final View parent;
public CustomView(View view){
parent = view;
}
// Jackson needs a no-arg constructor
public CustomView(){
parent = new View();
}
// ...
public List<Columns> getColumns(){ ... }
public void setColumns(List<Columns> columns){ ... }
public int getPrimaryColumn(){
return parent.getPrimaryColumn().getColumnId();
}
public void setPrimaryColumn(int column){
parent.getPrimaryColumn().setColumnId(column);
}
//...
// don't use `get` in the method name here to avoid serialization
public View rawView(){
return parent;
}
}
If needed this can be written to extend View, but be careful to mask methods where appropriate.
Turns out that since Jackson does nasty reflection, it can see through private methods. So, the trick ended up simply being along the lines of:
private void setPrimaryColumnId(Integer id) {...}
private Integer getPrimaryColumnId() {...}
public void setPrimaryColumn(Column column) {...}
#JsonIgnore
public Column getPrimaryColumn() {...}