Using GWT-Editors without UiBinder - java

I wanted to improve the code of my gwt-project by using editors to bind the POJOs, which I used to manually parse to the widgets back and forth. However I find the documentation confusing, mostly because it references ui binder, another feature I haven't figured out yet.
Does it make sense to use editors without ui binder? My ParentDTO contains a number of childDTOs. The following snippet shows how I am trying to nest some ChildEditors extended by TextArea into my ParentEditor (tried to strip it down to the essentials):
public class MyEditorPage {
// editors
class ParentDTOEditor implements Editor<ParentDTO> {
Integer dataBaseId;
List<ChildDTOEditor> childs;
public void attach(RootPanel rootPanel) {
for (ChildDTOEditor widget : childs) {
rootPanel.add(widget);
}
}
}
class ChildDTOEditor implements Editor<ChildDTO> extends TextArea {}
// driver
interface Driver extends SimpleBeanEditorDriver<ParentDTO, ParentDTOEditor> {}
Driver driver = GWT.create(Driver.class);
// load set widgets to the root panel
public void loadPage(RootPanel rootPanel) {
// get pojos from server
myService.getSuff(...
...
public void onSuccess(ParentDTO result) {
ParentDTOEditor editor = new ParentDTOEditor();
driver.initialize(editor);
driver.edit(result);
editor.attach(rootPanel);
}
}
// save
public void save() {
ParentDTO dto = driver.flush();
... // call myService.saveStuff(dto,...
}
}
Do I even need separate editors or just a parent editor of type ListEditor directly holds the child dtos?

Does it make sense to use editors without ui binder?
Yes, the features are independent and each can be used without the other.
Do I even need separate editors or just a parent editor of type ListEditor directly holds the child dtos?
You could create a ListEditor implementation direcly, but GWT can do that for you if you tell it how to create and destroy an Editor<ChildDTO> by extending EditorSource<ChildDTOEditor> and using ListEditor.of(new YourChildDTOEditorSourceImpl())
There's a decent example here but I'll call out a minimum implementation here.
public class FooEditor extends Composite implements Editor<Foo> {
// Implement one of uibinder+fields, fields, methods, or LeafValueEditor.set/getValue()
public FooEditor() {
initWidget(/* root widget or call to uiBinder.createAndBindUi(this) */)
}
}
public class FooListEditor extends Composite implements IsEditor<ListEditor<Foo, FooEditor>> {
private class FooEditorSource extends EditorSource<FooEditor> {
#Override
public FooEditor create(int index) {
FooEditor subEditor = new FooEditor();
// any additional per-item config can go here, e.g wiring up delete handler
listPanel.insert(subEditor, index);
return subEditor;
}
#Override
public void dispose(FooEditor subEditor) {
subEditor.removeFromParent();
}
#Override
public void setIndex(FooEditor subEditor, int index) {
listPanel.insert(subEditor, index);
}
}
// FlowPanel or anything else you want to use to hold the sub-editors.
// Instantiated explicitly or through uibinder.
FlowPanel listPanel = new FlowPanel();
// Let GWT handle the ListEdiotr implementation
ListEditor<Foo, FooEditor> editor = ListEditor.of(new FooEditorSource());
public FooListEditor() {
initWidget(listPanel /* or uiBinder.createAndBindUi(this) */);
}
#Override
public ListEditor<Foo, FooEditor> asEditor() {
return editor;
}
}
Now you can create an editor driver and use it as you would a normal editor, but pass it a list instead.
interface Driver extends SimpleBeanEditorDriver<List<Foo>, ListEditor<Foo, FooEditor>> {}
Driver driver = GWT.create(Driver.class);
FooListEditor fooListEditor = new FooListEditor();
/* snip */
driver.initialize(FooListEditor);
driver.edit(someListOfFoo);

Related

Unchecked cast warning with abstract method providing specific return value

I'm writing selenium tests for an app that has very standard pages that can easily be modeled by a generic structure as the base for the pages, with only a few base types (mostly list pages containing a list of records, and edit pages where one can edit one record). To model this I have these two classes:
public abstract class AbstractListPage<E extends EditPage> extends AbstractSelfOpeningPage implements ListPage {
// Provides the specific object for the edit page when it's opened
protected abstract E editPageHook();
public E getEditPage() {
return editPageHook();
}
public E openEditPage(String key, boolean search) {
//Do page opening stuff like clicking buttons
// Return new object for the page that has been opened
return getEditPage();
}
}
// Implementation class
public class DossiersListPage extends AbstractListPage<DossierPage> {
#Override
protected DossierPage<DossiersListPage> editPageHook() {
return new DossierPage<>(driver, this);
}
}
// Usage in test, this shows an unchecked cast warning
DossierPage<DossiersListPage> dossierPage = new DossiersListPage(driver).openPage().openEditPage("3905");
I would like to know if there is a good way to fix this, and what am I missing? I'm not having any issues currently, but the warning all over my test code is making me feel a bit iffy.
The reason for the generics here is so I can model elements on my page that return the page they belong to in a fluent way:
public abstract class AbstractPageElement<P extends Page> implements PageElement<P> {
#Override
public P click() throws TimeoutException {
// Do click
return page;
}
}
// DossierPage
public class DossierPage<L extends ListPage> extends AbstractEditPage<L> {
public OrderDate<DossierPage<L>> orderDate = new OrderDate<>(driver, this);
public OrderType<DossierPage<L>> orderType = new OrderType<>(driver, this);
public Status<DossierPage<L>> status = new Status<>(driver, this);
}
// Test
dossierPage.orderDate.click()
.orderType.click()
.status.click();
I could reverse-engineer the problem. The DossierPage must look something like this:
public class DossierPage<E extends AbstractListPage> extends EditPage {
//...
}
So now we're getting the problem. You can solve it by specifying more type arguments:
public class DossiersListPage extends
AbstractListPage<DossierPage<DossiersListPage>> { // this is the tricky part
#Override
protected DossierPage<DossiersListPage> editPageHook() {
return new DossierPage<>();
}
//...
}
Just add the following line above the line giving the warning:
#SuppressWarnings("unchecked")

Set the list of acceptable values in a GWT ValueListBox based on an EnumSet?

Given that I have this entity as part of an editor chain:
public class Commission implements Serializable
{
private EnumSet<CommissionType> commissionTypes;
private CommissionType type; // must exist in commissionTypes
private String value;
public Commission()
{
}
}
and this editor for it:
public class CommissionEditor extends Composite implements Editor<Commission>
{
private static CommissionEditorUiBinder uiBinder = GWT.create(CommissionEditorUiBinder.class);
interface CommissionEditorUiBinder extends UiBinder<Widget, CommissionEditor>
{
}
#UiField(provided = true)
ValueListBox<CommissionType> type = new ValueListBox<CommissionType>(new AbstractRenderer<CommissionType>()
{
#Override
public String render(CommissionType object)
{
return object == null ? "" : object.toString();
}
});
#UiField
TextBox value;
public CommissionEditor()
{
type.setAcceptableValues(Arrays.asList(CommissionType.values()));
initWidget(uiBinder.createAndBindUi(this));
}
}
At the moment the ValueListBox renders all possible options for CommissionType, like this:
The EnumSet could contain between 1 and 4 of the possible options, depending on the particular entity. Is there a way to make the ValueListBox only render the options in the EnumSet and then save the value in commissionType?
Bear in mind that I want to set the value of commissionType as well.
There are two ways to solve it:
1.) If you have a direct access to the CommissionEditor then create a setter in it call it when you edit the entity:
public void setAcceptableValues(List<CommissionType> values) {
type.setAcceptableValues(values);
}
And call it like this when you call driver.edit(entity);:
commissionEditor.setAcceptableValues(commission.getCommissionTypes());
2.) Instead of extending the Editor interface you can extend the ValueAwareEditor and in the setValue() method call setAcceptableValues with the corresponding values.
Approach 2 is probably the cleaner approach.

FEST: Getting a component by his class (inherited from a basic component)

I have this code:
//FrameFixture frame = (...got it from window, main frame...)
JTableFixture table = frame.table(new GenericTypeMatcher<JTable>(JTable.class) {
#Override protected boolean isMatching(JTable table) {
return (table instanceof myTreeTable);
}
});
Isnt there any better kind of syntactic sugar for fetching a component by his .class (inheriting from a basic component)?
If you need implementation of ComponentMatcher then TypeMatcher can do matching based on type.
However TypeMatcher cannot be used in case of ContainerFixture.table methods as they require GenericTypeMatcher.
TypeMatcher and GenericTypeMatcher both implement ComponentMatcher but aren't in the same hierarchy.
GenericTypeMatcher is abstract, so you have to provide an implementation. You could get away with your own extension if needed, ie:
class ConcreteTypeMatcher<T extends Component> extends GenericTypeMatcher<T> {
Class<T> type;
public ConcreteTypeMatcher(Class<T> supportedType) {
super(supportedType);
this.type = supportedType;
}
#Override
protected boolean isMatching(T arg) {
return type.isInstance(arg);
}
}
And use it like this:
JTableFixture table = frame.table(
new ConcreteTypeMatcher<myTreeTable>(myTreeTable.class));

Separating Service Logic from Data

I have been looking over a couple of classes I have in an android project, and I realized that I have been mixing logic with data. Having realized how bad this can be to the readability and the test-ability of my project, I decided to do some refactoring in order to abstract away all services logic to separate services modules. However, since I have been relying on Java's polymorphism, I got lost and need some guidance.
Suppose I have this "to-be-changed" layout for a super data class, and two sub-classes:
public class DataItem {
/* some variables */
public saveToDB(/* Some Arguments */) {
/* do some stuff */
}
public render() {
/* render the class */
}
}
public class ChildDataItemA extends DataItem {
#Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemA */
}
#Override
public render() {
/* render logic for ChildDataItemA */
}
}
public class ChildDataItemB extends DataItem {
#Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemB */
}
#Override
public render() {
/* render logic for ChildDataItemB */
}
}
Now, I thought about moving the saveToDB() and render() methods to a service class. However, sometimes I need to be able to call these method into instance of compiled type DataItem without knowing its runtime type. For instance, I might want to make the following call:
List<DataItem> dataList;
for (DataItem item: dataList) {
item.saveToDB();
item.render();
}
Additionally, I thought of doing the following:
public class ChildDataItemB extends DataItem {
#Override
public saveToDB(/* Some Arguments */) {
super.saveToDB();
/* more specific logic to ChildDataItemB */
Service.saveToDBB();
}
#Override
public render() {
/* render logic for ChildDataItemB */
Service.renderB();
}
}
Where I still keep 'dummy' methods in each subclass that would call an appropriate service method. However, I do not think that this really achieves the separation I want since data classes will still know about services (bad!).
Any ideas on how to solve this?
Edit: Note that render() and saveToDB() are just generic examples of what these methods can be, so the problem is not really about choosing an ORM or SQL related techniques.
Visitor pattern to the rescue. Create a visitor interface and have each service implement this interface:
public interface DataItemVisitor {
// one method for each subtype you want to handle
void process(ChildDataItemA item);
void process(ChildDataItemB item);
}
public class PersistenceService implements DataItemVisitor { ... }
public class RenderService implements DataItemVisitor { ... }
Then have each DataItem implement an accept method:
public abstract class DataItem {
public abstract void accept(DataItemVisitor visitor);
}
public class ChildDataItemA extends DataItem {
#Override
public void accept(DataItemVisitor visitor) {
visitor.process(this);
}
}
public class ChildDataItemB extends DataItem {
#Override
public void accept(DataItemVisitor visitor) {
visitor.process(this);
}
}
Note that all accept implementations look the same but this refers to the correct type in each subclass. Now you can add new services without having to change the DataItem classes.
So you want to do:
List<DataItem> dataList;
for (DataItem item: dataList) {
service.saveToDB(item);
service.render(item);
}
For this you need to setup a system for your service to know more details from your DataItem subclass.
ORM's and serializers usually solve this via a metadata system, e.g. by finding an xml file with name matching the subclass, containing the properties to save or serialize.
ChildDataItemA.xml
<metaData>
<column name="..." property="..."/>
</metaData>
You could get the same result via reflection and annotations.
In your case, an application of the Bridge pattern could also work:
class DataItem {
public describeTo(MetaData metaData){
...
}
}
class Service {
public void saveToDB(DataItem item) {
MetaData metaData = new MetaData();
item.describeTo(metaData);
...
}
}
Your metadata could be decoupled from saving or rendering, so you can the same for both.
I would clean the "data" classes of render and saveToDB methods.
Instead, I would create a hierarchy of wrappers for DataItem (it does not have to mimic exactly the DataItem hierarchy). These wrappers will be the ones implementing those methods.
Additionally, I suggest that (if you can), you move to some ORM (Object-Relational Mapping) like Hibernate or JPA to get rid of the saveToDB method.
First of all the DataItem class should be clean, only with getters and setter and no logic at all, just like a POJO. moreover- your DataItem maybe should be abstract.
Now- for the logic, like others suggested I would use some ORM framework for the saveToDB part, but you said that it's not helping you cause it's android project and you have other methods like this as well.
So what I would do is to create an interface- IDataItemDAO, with the following logic:
public interface IDataItemDAO<T extends DataItem > {
public void saveToDB(T data, /* Some Arguments */);
... other methods that you need ...
}
I would create an abstract DAO for the DataItem and put it all the similar code of all DataItems:
public abstract class ChildDataItemADAO impelemets IDataItemDAO<DataItem> {
#Override
public void saveToDB(DataItem data, /* Some Arguments */); {
...
}
}
than I would create a DAO for each DataItem class that you have:
public class ChildDataItemADAO extends DataItemDAO impelemets IDataItemDAO<ChildDataItemA> {
#Override
public void saveToDB(ChildDataItemA data, /* Some Arguments */); {
super(data, ...);
//other specific saving
}
}
the other part is how to use the correct DAO for the correct instance, for this I would create a class that will bring me the correct DAO for the given instance, it is a very simple method if an if-else statements (or you can do it dynamically with a map of class and the DAO)
public DataItemDAO getDao(DataItem item) {
if (item instanceof ChildDataItemA) {
//save the instance ofcourse
return new ChildDataItemADAO();
}
}
so you should use it like this:
List<DataItem> dataList;
for (DataItem item: dataList) {
factory.getDao(item).saveToDB(item);
}
If you want separate logic from data you may try the following approach
Create your data class DataItem,ChildDataItemA, ChildDataItemB without the method operating on the data
Create an interface for some operations on you data class something like
public interface OperationGroup1OnDataItem {
public void saveToDB(DataItem dataItem/*plus other params*/) {
}
public void render(DataItem dataItem/*plus other params*/) {
}
......
}
Create a factory for implementing an OperationGroup provider
public class OperationFactoryProvider {
public static OperationGroup1OnDataItem getOperationGroup1For(Class class) {
....
}
}
Use it in you code:
List<DataItem> dataList;
for (DataItem item: dataList) {
OperationGroup1OnDataItem provider OperationFactoryProvider.getOperationGroup1For(item.class);
provider.saveToDB(item);
provider.render(item);
}
You can choose to implement the factory with a simple static map where you put the class (or the class fullName) as the key and an Object implementing the interface as the value; something like
Map<String,OperationGroup1OnDataItem> factoryMap= new HashMap<String,OperationGroup1OnDataItem>();
factoryMap.put(DataItem.class.getName(),new SomeClassThatImplementsOperationGroup1OnDataItemForDataItem());
factoryMap.put(ChildDataItemA.class.getName(),new SomeClassThatImplementsOperationGroup1OnDataItemForChildDataItemA());
The implementation of the getOperationGroup1For is:
return factoryMap.get(item.getClass().getName());
This is one example of separating logic from data, if you want separate logic from data your logic methods must be extracted from your data class; otherwise there is no separation. So I think every solution must start from removing logic methods.

Refactoring code in Java, alternatives to large if statement

I'm refactoring some code in a project I'm working on and I ran into a large if/else if statement that follows the format:
if (changer instanceof AppleChanger)
{
panel = new ApplePanel();
}
else if (changer instanceof OrangeChanger)
{
panel = new OrangePanel();
}
Now my first impulse was to refactor it using polymorphism to have it appear like
panel = changer.getChangerPanel();
However unfortunately the class package doesn't have access to the panel package.
My next impulse was to create a PanelChooser class with an overloaded method:
PanelChooser.getPanel(changer);
//Overloaded Method
public Panel getPanel(OrangeChanger changer)
{
Panel orangePanel = new OrangePanel();
return orangePanel;
}
public Panel getPanel(AppleChanger changer)
{
Panel applePanel = new ApplePanel();
return applePanel;
}
Is this a good solution or is there a better way to solve this?
The fundamental 'problem' here is that you have parallel class hierarchies. You're not going to be able to replace that if statement without some fairly heavy refactoring. Some suggestions are on c2 wiki.
The best you can do, and possibly a perfectly fine solution, is to move the if statement into a 'factory' class and make sure it's not duplicated anywhere else.
I think its good that your first impulse didn't work :) Otherwise you would couple you changer code (which should be something about logic) to UI code (panel) and its wrong.
Now I can offer you the following solution:
create an interface PanelCreator with method Panel createPanel like this:
interface PanelCreator {
Panel createPanel();
}
Now, provide 2 implementations:
public class OrangePanelCreator implements PanelCreator{
Panel createPanel() {
return new OrangePanel();
}
}
public class ApplePanelCreator implements PanelCreator {
Panel createPanel() {
return new ApplePanel();
}
}
And now come the interesting part:
Create a Map, PanelCreator> this would act like a registry for your panels:
Map<Class<Changer>, PanelCreator> registry = new HashMap<>;
registry.put(OrangeChanger.class, new OrangePanelCreator());
registry.put(AppleChanger.class, new ApplePanelCreator());
And in your code now you can do the following thing:
panel = registry.get(changer.getClass()).createPanel();
I think it will be more elegant since you can easily change implementations of creators given the changer.
Hope this helps
If there is more than one of this if/else constructs in the code dependending on the instance type of a Changer, you can use the visitor pattern like this:
public interface ChangerVisitor {
void visit(OrangeChanger changer);
void visit(AppleChanger changer);
...
}
public class ChangerVisitorEnabler<V extends ChangerVisitor> {
public static <V extends ChangerVisitor> ChangerVisitorEnabler<V> enable(V) {
return new ChangerVisitorEnabler<V>(visitor);
}
private final V visitor;
private ChangerVisitorEnabler(V visitor) {
this.visitor = visitor;
}
public V visit(Charger changer) {
if (changer instanceof OrangeChanger) {
visitor.visit((OrangeChanger)changer);
} else if (changer instanceof AppleChanger) {
visitor.visit((AppleChanger)changer);
} else {
throw new IllegalArgumentException("Unsupported charger type: " + changer);
}
return visitor;
}
}
Now you have a single type check code block and a type safe interface:
public PanelChooser implements ChangerVisitor {
public static Panel choosePanel(Changer changer) {
return ChangerVisitorEnabler.enable(new PanelChooser()).visit(changer).panel;
}
private Panel panel;
private PanelChooser() {
}
void visit(OrangeChanger changer) {
panel = orangePanel();
}
void visit(AppleChanger changer) {
panel = applePanel();
}
}
The usage is very simple:
panel = PanelChooser.choosePanel(chooser);
Perhaps you can do:
public Panel getPanel(Changer changer)
{
String changerClassName = changer.class.getName();
String panelClassName = changerClassName.replaceFirst("Changer", "Panel");
Panel panel = (Panel) Class.forName(panelClassName).newInstance();
return panel;
}
I don't program in Java, but that is what I would try if this were in C#. I also don't know if this would work with your packages.
Good luck!
I don't see enough existing code and design at whole. So probably, first of all I would try to move the code with panel instantiation to the same place where Changer instance is created. Because choosing a Panel is the same decision as choosing a Changer.
If a selected Changer is dynamically selected, you may just create these panels and then show/hide them accordingly.
I'd do the following:
Have an interface PanelChooser with a single method returning a Panel for a Changer.
Have an implementation ClassBasedPanelChooser returning a panel when the Change implements a certain class and null otherwise. The class and the panel to be returned get passed in in the constructor.
Have another implementation CascadingPanelChooser which takes a list of PanelChoosers in the constructor arguments and on call of its method asks each PanelChooser to provide a panel until it receives a not null panel, then it returns that panel.
Your solution will not work, because Java selects the method based on the compiletime type (which here is probably Changer). You could use a Map<Class<? extends Changer>, Panel> (or Map<Class<? extends Changer>, Class<? extens Panel>> if you need to create new instances every time). This solution does require extra work if you need this to work for - yet unknown - subclasses of for example OrangeChanger.
eg for a single instance per Changer subclass
changerToPanel.get(changer.getClass());
or if you need new instances:
changerToPanelClass.get(changer.getClass()).newInstance();
The other option would be to go for your initial hunch, and make Changer know about Panel.
Take a look at the Factory and Abstract Factory Patterns.
The Factory Pattern is a creational pattern as it is used to control class instantiation. The factory pattern is used to replace class constructors, abstracting the process of object generation so that the type of the object instantiated can be determined at run-time.
Abstract Factory Pattern is a creational pattern, as it is used to control class instantiation. The abstract factory pattern is used to provide a client with a set of related or dependent objects. The family of objects created by the factory is determined at run-time according to the selection of concrete factory class.
Do not use instanceof.Why polymorphism fails
The only place to use instanceof is inside equals method.
To answer your question. Follow this link.
Credits to Cowan and jordao .
Using Reflection.
public final class Handler {
public static void handle(Object o) {
for (Method handler : Handler.class.getMethods()) {
if (handler.getName().equals("getPanel") &&
handler.getParameterTypes()[0] == o.getClass()) {
try {
handler.invoke(null, o);
return;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
throw new RuntimeException("Can't handle");
}
public static void handle(Apple num) { /* ... */ }
public static void handle(Orange num) { /* ... */ }
Chain of Responsibility
public abstract class Changer{
private Changer next;
public final boolean handle(Object o) {
boolean handled = doHandle(o);
if (handled) { return true; }
else if (next == null) { return false; }
else { return next.handle(o); }
}
public void setNext(Changer next) { this.next = next; }
protected abstract boolean doHandle(Object o);
}
public class AppleHandler extends Changer{
#Override
protected boolean doHandle(Object o) {
if (!o instanceof Apple ) {
return false;
}
OrangeHandler.handle((Orange) o);
return true;
}
}

Categories

Resources