I am trying to create a GWT Editor for a bean Object, which has two fields of another Object type, therefore I want sub-editors for those fields. The problem is that I am quite new to the editors framework, and I don't really get the idea of all those Editor interfaces out there.
Please advise of the best solution. My ideas were the following: using drivers of sub-editors to pass data to main editor driver; or use some sort of CompositeEditor (but I didn't know what to do with overridden methods...).
Here's a sample code:
public class A {
String s1, s2;
Integer i;
Double d;
B ba, bb;
}
public class B {
BigDecimal a, b;
}
//sub-editor
public class BEditor extends Composite implements Editor<B> {
interface BDriver extends BeanEditorDriver<B, BEditor> {
}
//implements HasEditorErrors interface
ValueBoxEditorDecorator<BigDecimal> a, b;
}
//main editor
public class AEditor extends Composite implements Editor<A> {
interface ADriver extends BeanEditorDriver<A, AEditor> {
}
private ADriver driver = GWT.create(ADriver.class);
ValueBoxEditorDecorator<String> s1, s2;
ValueBoxEditorDecorator<Integer> i;
ValueBoxEditorDecorator<Double> d;
BEditor ba, bb;
public AEditor() {
driver.initialize(this);
driver.edit(new A());
}
//called when the editor form is submitted
public void onSubmit() {
driver.clearErrors();
A a = driver.flush();
// A has both B fields = null
// AEditor successfully displays validation errors,
// but BEditors do not display errors, nor does
// ADriver get any errors from BEditor
}
}
}
When you create the VehiculeDTO, also create B subclasses :
A a = new A();
a.setBa(new B());
a.setBb(new B());
driver.edit(a);
Here are some guidelines from my experiences using the Editor Framework, both personally, and also in industry. I have tried my best to make them relevant to your example.
Identify your "top-level" editor. In your case, it would be AEditor - in most other cases, it would be a view. Have the designated widget implement the Editor interface, with type param = your backing object (which you have done correctly).
Ensure your backing object A includes getters and setters and the fields are private. You have left them with default access which I don't think is a good idea.
Ensure your top level widget contains a sub-editor for each of the fields in A. They should share the same name as the corresponding field in A, or be annotated with #Path to indicate which field they relate to.
Your sub-editors should never have their own driver interface. They should either implement LeafValueEditor, ValueAwareEditor etc or an adapter interface such as IsEditor
In the constructor for your top level editor (here, AEditor), you need to initialise the driver and backing object:
ADriver driver = GWT.create(ADriver.class);
public AEditor {
driver.initialize(this);
driver.edit(new A());
}
When you save, you should be calling driver.flush() to move the data from the top level editor into the backing object. Conversely, when you load, you should be calling driver.edit() with the backing object you wish to load
I have put up some Gists to demonstrate LeafValueEditor and IsEditor, in case you need help changing your sub-editor:
LeafValueEditor
IsEditor
Related
I am trying to wrap my mind around how I would go about implementing this specific problem. We have an external API that performs some logic and returns back the result of that logic. Unfortunately, the API returns a new object as the result as opposed to just the part that I am interested in. For example, the code would look something like this:
public class ComplexObject {
//lots of fields
}
public interface LogicApplier {
LogicResult applyLogic(ComplexObject obj);
}
public class LogicResult {
ComplexObject result;
public ComplexObject getResult();
}
public class FirstImplementation {
private LogicApplier _applier;
public Implementation(LogicApplier applier) {
_applier = applier;
}
public ComplexObject mainImplementation (ComplexObject apply) {
LogicResult logicResult = _applier.applyLogic(apply);
ComplexObject newComplexObject = logicResult.getResult();
//Do some other stuff with new ComplexObject
}
}
So question is: what would be the best way to put a limit on LogicApplier's "power" over FirstImplementation? For example, our motivation to call logic in the first place is to derive a missing field, let's say "name". This field could potentially be different in, say, SecondImplementation where that implementation is now looking to derive "street address" from LogicApplier API. However, there is nothing to stop LogicApplier from changing some other field, say "idNumber".
Is this best solved by a adding an interface for our specific implementations and manually mapping fields? Something like:
public interface SecondImplementationLogicApplier {
public String deriveAddress(ComplexObject o);
}
public class LimitedImplementationLogicApplier implements FirstImplementationLogicApplier, SecondImplementationLogicApplier {
LogicApplier _applier;
public LimitedImplementationLogicApplier(LogicApplier applier) {
_applier = applier;
}
public String deriveFirstName(ComplexObject o) {
LogicResult res = _applier.applyLogic(o);
return res.firstName;
}
public String deriveFirstName(ComplexObject o) {
LogicResult res = _applier.applyLogic(o);
return res.address;
}
}
I think you are on right track with your LimitedImplementationLogicApplier. You should guard objects in your domain from possible corruption from the outside. Only update fields that you need.
It looks like your ComplexObject is mutable. I'd consider hiding it behind the immutable interface (that don't have any setters or way to change the object exposed) and pass immutable interface into your LimitedImplementationLogicApplier so its got no chance of mutating ComplexObject.
If your API requires ComplexObject type and you can't change that, to prevent mutation you could:
Option 1
Create a clone of your base ComplexObject instance and pass it into the API. After you've got the result back, you update the needed fields on untouched base instance. This will work nicely if ComplexObject is "thing in itself" and changes in its state does not have side effects outside of the class instance, like changing databases or affecting other state.
If mutation of ComplexObject has side effects or may have them in future then its a real trouble.
Option 2
Inherit a ReadonlyComplexObject class from ComplexObject and pass that into the API. In ReadonlyComplexObject you will suppress all the behavior of the parent to prevent modification.
This is hacky in my opinion and will create more work later - if ComplexObject will be extended with new properties later you will need to make changes to ReadonlyComplexObject otherwise mutation will still occur.
Okay this is my first post here so bear with me..
I'm working on a small side project about genetic programming and I'm using generics.
These are small code snippets:
public class BinaryGenome<C extends BinaryEncodeable<C>> {
public BinaryGenome(C encodable){
setGenome(encodable.encode());
setSpecification(encodable);
}
public BinaryGenome(BitSet encoding) {
setGenome(encoding);
//What comes here???
}
}
public interface BinaryEncodeable<C extends BinaryEncodeable<C>> {
public BitSet encode();
public C decode(BitSet encoding);
}
The BinaryGenome represents a genome, it contains the object it represents and the bit representation. I'm able to use the first constructor, but I'm having troubles with the second one. Is it possible to create an object C in the second constructor from the encoding, given that each class implementing BinaryEncodable has a decode method.
I know "new C()" doesn't work because of type errasure but is there some kind of factory I can use?
You could pass a supplier as an argument:
public BinaryGenome(BitSet encoding, Supplier<C> supp) {
setGenome(encoding);
C c = supp.get();
//...
}
BinaryGenome<SomeClass> bg = new BinaryGenome<>(encoding, SomeClass::new);
But really, the decode method is better as a static factory method on SomeClass.
class SomeClass implements BinaryEncodeable<SomeClass> {
public static SomeClass decode(BitSet encoding) {...}
}
BinaryGenome<SomeClass> bg = new BinaryGenome<>(SomeClass.decode(encoding));
Both scenarios require you to know the specific subtype anyways.
The second one even allows you to get rid of the type parameter.
The reason why BinaryGenome can't just construct an object of type C, is a lack of information.
At runtime, due to erasure, the only type BinaryGenome knows is BinaryEncodable and BinaryEncodable knows nothing about it's own subclasses.
Without an instance of C that holds this kind of information, there is no way for BinaryGenome to know what decode method to call.
i have a class that is used widely in my project as some sort of field holder. Something like:
class A
{
private String field = null;
private String field2 = null;
private String field3 = null;
// and its generic Getters and Setters
}
In certain part of code i need add additional fields to this class. So i did this
class B extends A
{
private String fieldInB = null;
// and its Getters and Setters
}
in my function i thought i could easily do
public void foo( A a )
{
B b = (B)a;
}
And i could have all the fields written in aobject and i could easily set only field in b and use it. This seams like a common problem, but i just don't know how to do it except with an very ugly approach:
public B( A a )
{
// copy all the fields one at the time
}
You areconfusing different parts of Java:
B b = (B)a;
this is classical class cast, but to work with B class object you need:
1. be sure that a is of B class (check it with instanceof java keyword:
if (a instanceof B) {
B b = (B) a;
}
2. or wrap a in B class object (create B class object with copying fields from a).
PS in most of Java coding conventions it is recommended to fill fields by concrete values only (and not fill with default JavaVM values - nulls)
Comfortable way to copy A class fields to new instance:
public A (A a) {
this.field = a.field;
this.field2 = a.field2;
this.field3 = a.field3;
}
and for B class:
public B (A a) {
super(a);
}
Another way - some libraries that will work with A class and B class as with beans. Sample of this libraries you can find in Toilal's answer
You could use Dozer. It allows to map bean property values from one bean class to another.
Hai john Actually i didn't get your exact requirement. I recon the way you have written this code is not right.
Private variable cant be inherited.If you need to extend values to your subclass you should have declared those variables as public.
public B(A a)
{
super.field=a.field;
super.field2=a.field2;
super.field3=a.field3;
}
I m beginner in java, so need your professional suggestions.
Short description:
I have some classes A1, A2, A3 .. B1 ..
I need one magic generic class or method that creates CompositeA CompositeB ...
These composite classes, have defined generalized behavior, what to do with what kind of methods
The kind of methods, could be set by annotations
The methods itself are different for A, B ..
I want to avoid writing CompositeX class every time I have new class X.
The question: Is it possible? If yes, how to?
Long description:
Our problem now:
There are 2+ data sources, like DB, files, libs.
From this data sources we get similar information. For example IDs.
The information is in objects (like hibernate entity), that extends one interface/abstract class.
For example if the content we need is in Foo class, so we have FooDB, FooFile, FooLib. All implementing/extending Foo.
And we create some CombinedFoo, to work with combined data of all this sources.
to update CombinedFoo data source (insert or change some information), only one source will be really used,
for retreiving the data from CombinedFoo all the sources will be used
(see CompositeFoo constructor later)
For example I have a Foo object, that has data (in this case IDs) from DB, another Foo from files and another Foo from some lib.
All this Foo's, implements same Foo interface.
Now I need all the sources in one combined object (that implements Foo interface too).
By initialization of combined foo I do
CompositeFoo compFoo = new CompositeFoo(fooDB, fooFILE, fooLIB)
compFoo.addId("value") calls only fooDB.addId("value").
compFoo.getIds() gets all the ids from all the data sources
(fooDB.getIds() + fooFILE.getIds() + fooLIB.getIds()).
If I want not only Foo, but for example Bar, I need to implement again new CompositeBar, with its own methods (this I want to avoid). But in the end all I need is: to make sure what methods are only for retrieving (get_methods) and what for changing information (set_methods).
now the question:
Is it possible to create such magic generic class, that is written once, and can be applied to every object class, I want to combine?
Here some example for more understanding:
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
//interface used for composite class and data classes
public abstract class Foo {
abstract Set<String> getIds();
abstract void addId(String id);
}
//data source from file
class FooFromFile extends Foo {
#Override
Set<String> getIds() {
//loads data from file
}
#Override
void addId(String id) {
//changes file, add there one id
}
}
//data source from DB
class FooFromDB extends Foo {
#Override
Set<String> getIds() {
//loads ids from DataBase
}
#Override
void addId(String id) {
//adds id to database
}
}
//class i use now, combines all Foo's
//gets info from all, updates only main data source
//this one i want to make generic
class CompositeFoo extends Foo {
private Foo mainFoo;
private Set<Foo> others;
public CompositeFoo(Foo mainSource, Foo ...otherSources ) {
mainFoo = mainSource;
others = new HashSet<>();
Collections.addAll(others, otherSources);
}
#Override
Set<String> getIds() {
HashSet<String> result = new HashSet<>();
//load from main source
result.addAll(mainFoo.getIds());
//and from other sources
for (Foo otherFoo : others ) {
result.addAll(otherFoo.getIds());
}
//ids from all the sources
return result;
}
#Override
void addId(String id) {
//uses only main source, we don't want to add ID to all the sources
mainFoo.addId(id);
}
}
Now it works so:
public static void main(String[] args) {
FooFromDB dbFooMain = new FooFromDB();
FooFromFile fileFoo = new FooFromFile();
CompositeFoo compFoo= new CompositeFoo(dbFooMain, fileFoo);
compFoo.add("new id"); //adds to dbFooMain only
compFoo.getIds(); //gets from all sources (dbFooMain + fileFoo)
}
This magic I want to realize but don't know how:
It should work somehow in this example
public static void main(String[] args) {
FooFromDB dbFooMain = new FooFromDB();
FooFromFile fileFoo = new FooFromFile();
//something like this:
MagicComposite<Foo> compFoo = new MagicComposite<>(dbFooMain, fileFoo);
//or something like this:
Foo compFoo = AnyCompositeFactory.createComposite(Foo.class, dbFoo, fileFoo);
//than this should work
//adds to dbFooMain only. dbFoo.add("new id") called
compFoo.add("new id");
//gets ids from all sources so dbFoo.getIds() + fileFoo.getIds() called and combined
compFoo.getIds();
//-----------------------------------------
//for Bar the same magic class should do
MagicComposite<Bar> compBar = new MagicComposite<>(dbBarMain, fileBar);
//or
Bar compBar = AnyCompositeFactory.createComposite(Bar.class, dbBar, fileBar);
}
So I want to avoid the creating of Composite%ClassName% for every %ClassName% data class.
I need some dynamic, generic CompositeMagic<Class> or whatever.
What I imagine..
If I have Bar class, than I somehow annotate it, what methods are to be combined to get all information, and what methods are just for changing information.
abstract class Bar{
#Magic(Type = retrieveInformationOnly)
Set<String> getSomething();
#Magic(Type = addInformation)
void addSomething(String id);
}
In this case the if I initialize the CombinedBar with some other Bars, and call addSomething() of this composite object, than only main (first arg in constructor) data source should add information, if I call getSomething(), all the initialized classed are called, and combined result is returned. (see CompositeFoo implementation)
The implementation could be something else. Code examples here are just to clarify what I need.
I am developing an API allowing users to transfer data using a certain protocol. Throughout the communication, two events - EventA and EventB occur. B is optional, but strongly related to A. They occur in the sequence (AB?)*. This events are exposed to the user as a hook call to an interface:
interface IEventHandler {
void eventAOccured(EventAData aData);
void eventBOccured(EventBData bData);
}
Now I want the user to be able to pass some data about event A to the hook of event B while keeping the interface stateless. First I thought something like
interface IEventHandler<U> {
U eventAOccured(EventAData aData);
void eventBOccured(EventBData bData, U userData);
}
Unfortunately, as generics do not offer runtime information (not without reflection, at least) the API has no way to call eventBOccured, as the type of its second parameter is not known at compile time. Introducing a markerinterface and U extends IMarker solves this, but does not spare the upcast I wanted to avoid. IMHO if I would go with the upcast I could simply pass Object and get the same thing.
I am pretty sure (Java) generics are the wrong tool here. Am I missing something? How would you tackle the problem?
I will do that way :
package com.stackoverflow.user3590895.questions24098455;
//-------------------------------
package com.stackoverflow.user3590895.questions24098455;
public class EventData implements IEventData{
//default is type A
private int type=IEventData.TYPE_A;
#Override
public int getType() {
System.out.print("Event [type:"+type+"]!");
return type;
}
}
//-------------------------------
package com.stackoverflow.user3590895.questions24098455;
public interface IEventData {
public static char TYPE_A='A';
public static char TYPE_B='B';
public int getType();
}
//-------------------------------
package com.stackoverflow.user3590895.questions24098455;
public interface IEventHandler<U> {
U eventOccured(IEventData data);
}
Use case:
- make a call of event (with event of you choice
- api catch event and can know his type by calling function getType.
- if you are an eventData B, you can herit of EventData and make a new EventData for B Type. You can add some specific function for EventDataB, and specific datas also.
give me feedback.
If I correctly understand, you could use a wrapper around you data containing its class definition. Something like
class Wrapper<U extends IMarker> {
U data;
Class<U> clazz;
// constructor, getters and setters omitted
}
Your event interface would be
interface IEventHandler<U extends IMarker> {
Wrapper<U> eventAOccured(EventAData aData);
void eventBOccured(EventBData, Wrapper<U> user data);
}
That way, Wrapper class is known, and API can call it without problem. And in eventBOccured you have the right type for your upcast.