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

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));

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")

Java: abstract or generic list that all derived classes must implement

I am making a component-based system for a game engine in Java.
I have different system classes to take care of different things, e.g., PhysicsSystem, RenderSystem, EditorSystem and so on. All classes inherits from BaseSystem, which in turn implements an interface ISystem.
I would like all of my system classes to have an ArrayList, but the type in each of them may differ, meaning that the RenderSystem might have a list of RenderComponents, while the PhysicsSystem has a list of PhysicsBodyComponents.
Is it possible to define a generic or abstract list in either the BaseSystem class or the ISystem interface that all the derived classes then implements? I have little experience with generics, so I am a bit confused by this.
This is my current code. As you can see, I created a second list for the derived class, which is kind of a waste.
interface ISystem
{
boolean AddToSystem(Component c);
}
abstract class BaseSystem implements ISystem
{
// can I make this list generic, so it can store any type in derived classes?
// e.g., Component, IRenderable, IPhysics, etc.
protected List<Component> _componentList;
}
class RenderSystem extends BaseSystem
{
// need to make a second list that stores the specific render components
List<IRenderable> _renderList = new ArrayList<IRenderable>();
void Update()
{
for (IRenderable r : _renderList)
r.Render(); // this code is specific to the IRenderable components
}
#Override
public boolean AddToSystem(Component c)
{
boolean succesfullyAdded = false;
if (c instanceof IRenderable)
{
succesfullyAdded = true;
_renderList.add((IRenderable) c);
} else
throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");
return succesfullyAdded;
}
}
Sure, assuming that all your components implement IComponent use something like this:
interface ISystem<ComponentType extends IComponent> {
public boolean AddToSystem(ComponentType c);
}
If you do not want to have a hard type dependency, you can remove the extends IComponent, but it will make handling lists of systems harder.
I think you need something like this
private static abstract class AbstractClass<T> {
final List<T> objects = new ArrayList<T>();
}
private static class ComponentHolder extends AbstractClass<Component> {
public void add(final Component c) {
objects.add(c);
}
public Component getComponent(final int index) {
return objects.get(index);
}
}
In your example, it would be something like this:
abstract class BaseSystem<T> implements ISystem
{
protected List<T> _componentList = new ArrayList<T>();
}
class RenderSystem extends BaseSystem<IRenderable>
{
void Update()
{
for (IRenderable r : _componentList)
r.Render(); // this code is specific to the IRenderable components
}
#Override
public boolean AddToSystem(Component c)
{
boolean succesfullyAdded = false;
if (c instanceof IRenderable)
{
succesfullyAdded = true;
_componentList.add((IRenderable) c);
} else
throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");
return succesfullyAdded;
}
}

Creating generic GWT Events: is this a good approach?

I'm trying to create a simple way to fire CRUD-type events for different domain classes. I've created the following event class:
public class EntityModifiedEvent<E> extends Event<EntityModifiedEventHandler<E>> {
private E element;
private ModType modType;
private Class<E> clazz;
private static Map<String,GwtEvent.Type<EntityModifiedEventHandler<?>>> types = new HashMap<String, GwtEvent.Type<EntityModifiedEventHandler<?>>>();
public EntityModifiedEvent(ModType modType, E element, Class<E> clazz) {
this.element = element;
this.modType = modType;
this.clazz = clazz;
}
public Type<EntityModifiedEventHandler<?>> getType() {
return getType(clazz);
}
#SuppressWarnings({"rawtypes", "unchecked"})
public static GwtEvent.Type<EntityModifiedEventHandler<?>> getType(Class clazz) {
GwtEvent.Type type = types.get(clazz.toString());
if (type == null) {
type = new GwtEvent.Type<EntityModifiedEventHandler<?>>();
types.put(clazz.toString(), type);
}
return type;
}
public E getElement(){
return element;
}
public ModType getModType() {
return modType;
}
#SuppressWarnings({"unchecked", "rawtypes"})
#Override
public Type<EntityModifiedEventHandler<E>> getAssociatedType() {
return (Type) getType();
}
#Override
protected void dispatch(EntityModifiedEventHandler<E> handler) {
handler.onEntityModified(this);
};
public interface EntityModifiedEventHandler<E> extends EventHandler {
void onEntityModified(EntityModifiedEvent<E> entityModifiedEvent);
}
So, any class can register itself as a listener as follow:
getEventBus().addHandler(EntityModifiedEvent.getType(MyDomainClass.class), this);
And the events will be fired like:
getEventBus().fireEventFromSource(new EntityModifiedEvent<MyDomainClass>(ModType.CREATE, instanceModified, MyDomainClass.class), this);
ModType is just a simple Enum with the different types of modifications.
I have some concerns about having a map with all class.toString->eventTypes in this class itself. Do you think this will bring performance issues?
Also, this approach relies on the EventBus using Type object's hashcode to identify the handlers registered for that type (see getType(Class clazz) function). Do you think it's wrong to rely on it?
Any other suggestion about how to do this? Any comment will be much appreciated!
You have to ask yourself what do you gain from such an approach?
Performance - no. I don't have solid numbers on this (I'd have to be able to profile your application), but it's seems that this offers no measurable performance gains, if any. The number of fired events will be the same, but the number of receivers will be greater than with a more fine-grained approach. Plus, there's the type checking.
The ability to perform some common code when any entity modified event is fired, regardless of its type. This is true, but read on on how to achieve it with specific events.
Using specific events for the exact operation that was performed seems like a better choice:
It makes it clear who listens to what event.
The events can have extra metadata specific to the event (how many records where deleted, do you need to flush the cache, etc.)
I'd recommend looking at gwteventbinder to trim some of the boilerplate and improve your code. It also allows for handling several events in one method:
class SuperEvent extends GenericEvent { }
class EventOne extends SuperEvent { }
class EventTwo extends SuperEvent { }
class FormPresenter {
interface MyEventBinder extends EventBinder<FormPresenter> {}
private final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);
FormPresenter(EventBus eventBus) {
eventBinder.bindEventHandlers(this, eventBus);
}
#EventHandler
void onEventOne(EventOne event) {
// handler for EventOne
}
#EventHandler(handles = {EventOne.class, EventTwo.class})
void onEventOneAndTwo(SuperEvent event) {
// handler for EventOne and EventTwo
}
#EventHandler(handles = {EventOne.class, EventTwo.class})
void onEventOneAndTwo2() {
// handler for EventOne and EventTwo without parameter
}
}

How can I compare objects using instanceof but Interface types (not passing exact class name.)

public interface Component{}
public class AppManager {
public void doWork(){
SomeComponent comp = new SomeComponent ();
AddComponentToList(comp);
}
public void AddComponentToList(Component compo){
componentList.add(compo);
}
/* Give me the component I want. */
public Component getComponent(Component comp){
for (Component component : getComponentList()) {
if (component instanceof comp) {
return component;
}
}
}
private ArrayList<Component> componentList = new ArrayList<Component>();
}
public class SomeComponent implements component {
public void MyMethod() {
appManager.getComponent(SomeComponent );
}
public void setAppMnger(AppManager appm){
this.appManager = appm;
}
private AppManager appManager ;
}
In Above code AppMnger is having a list of components. Components are communicating each other. So if one component want to know another component instance it call the AppMnger getComponent(comp) method. But I get an error when I use instanceof operator. I don't want each component to want compare the list but I want to delegate that task to AppMnger because he is the one who knows about components it created.
Amy thought?
I think you should redesign getComponent to take a Class<? extends Component> rather than a Component. Then you can use isInstance:
public Component getComponent(Class<? extends Component> componentClass) {
for (Component component : getComponentList()) {
if (componentClass.isInstance(component)) {
return component;
}
}
return null; // Or throw an exception, potentially.
}
And SomeComponent would use:
appManager.getComponent(SomeComponent.class);
If you really wanted to use an instance, you could overload the method like this:
public Component getComponent(Component existingComponent) {
return getComponent(existingComponent.getClass());
}
EDIT: If you actually only want to check for the exact class, you don't want instanceof-like behaviour - you just want:
public Component getComponent(Class<? extends Component> componentClass) {
for (Component component : getComponentList()) {
if (componentClass == component.getClass()) {
return component;
}
}
return null; // Or throw an exception, potentially.
}
I would still suggest using this method signature though - it would feel very odd to have to already have an instance of a component in order to find a component of the type you want.
If you want the class to match exactly (List != ArrayList) then use this:
if (comp.getClass().equals(component.getClass())) ...
If you want it to work exactly like instanceof (List => ArrayList) then you can try this:
if (comp.getClass().isInstance(component)) ...
I guess previous answers by Black,max and Jon are sufficient enough for your comparison part , for the "I don't want each component to want compare the list but I want to delegate that task to AppMnger because he is the one who knows about components it created. Amy thought?" you can try using the visitor design pattern .

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