How to use Assert.assertTrue in anonymous inner class? - java

Im want to test a propertyChangeSupport. For that, I wrote this Test:
private boolean changeRecognized = false;
#Test
public void testAddMapObject(){
Bot testBot = new Bot(UUID.randomUUID(), "test", new GeoPoint(0d, 0d));
PropertyChangeListener listener = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName() == "mapObjekt")
changeRecognized = true;
}
};
testListe.addPropertyChangeListener(listener);
testListe.addMapObjekt(testBot);
Assert.assertTrue(changeRecognized );
}
Is there a way to move the Assert.assertTrue into the PropertyChangeListener? I tried it, but the test passed every Time, even when I didn't call testListe.addMapObject(testBot)

I would suggest creating a named class for this:
class SomeTest ...
static class SpyListener implements PropertyChangeListener {
private boolean changeRecognized = false;
#Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getPropertyName() == "mapObjekt") {
changeRecognized = true;
}
}
public void assertRecognized() {
Assert.assertTrue(changeRecognized);
}
}
#Test
public void testAddMapObject() {
Bot testBot = new Bot(UUID.randomUUID(), "test", new GeoPoint(0d, 0d));
SpyListener listener = new SpyListener();
testListe.addPropertyChangeListener(listener);
testListe.addMapObjekt(testBot);
listener.assertRecognized();
}
...

Related

variable is null although It was set

I build a that contain some objects like that:
public class TestThis implements Listener{
private EventsManager eventsManager;
private ConfigManager configManager;
public TestThis() {
eventsManager = new EventsManager();
eventsManager.addListener(this);
configManager = new ConfigManager(this);
}
public ConfigManager getConfigManager() {
return configManager;
}
#Override
public void configLoadedSuccessfully(Event event) {
System.out.println(this.configManager); //OUTPUT NULL
System.out.println(this.getConfigManager());//OUTPUT NULL
}
}
There is problem with the configManager object.
In the construct everything is ok but is configLoadedSuccessfully event the configManager is null and its null evrywhere.
The Listener Code:
public interface Listener{
public void configLoadedSuccessfully(Event event);
}
I add a function that start loading the config and change the order of the var`s create.
public class TestThis implements Listener{
private EventsManager eventsManager;
private ConfigManager configManager;
public TestThis() {
eventsManager = new EventsManager();
configManager = new ConfigManager(this);
eventsManager.addListener(this);
configManager.load();
}
public ConfigManager getConfigManager() {
return configManager;
}
#Override
public void configLoadedSuccessfully(Event event) {
System.out.println(this.configManager);
System.out.println(this.getConfigManager());
}
}

Is there a "clean" way to automatically un-register a listener in Java?

I believe I've seen variants of this question, but no "definitive answer". In the code below, I understand that SomeEventManager holds a reference to someImplClassTwo.myEventListenerA and someImplClassTwo.myEventListenerB, and that this does not allow for someImplClassTwo to be garbage collected, and this results in the output generated the second time someEventManager.notifyListeners() is invoked.
But, I'd really like for users of SomeImplClass not to have to know that there are listeners involved in the implementation, and that these listeners need to be manually un-registered (i.e., SomeImplClass.releaseListeners()) before releasing the SomeImplClass object.
Is there a clean/accepted way of doing this?
p.s. I've already played with finalize(), just for fun, and confirmed that GC is not even attempted in this case, for either instance of SomeImplClass. So, that seems to be a non-starter as a potential solution.
Test Driver
public class TestDriver {
public static void main(String[] args) {
SomeEventManager someEventManager = SomeEventManager.getInstance();
SomeImplClass someImplClassOne = new SomeImplClass("One");
SomeImplClass someImplClassTwo = new SomeImplClass("Two");
someEventManager.notifyListeners();
someImplClassOne.releaseListeners();
someImplClassOne = null;
someImplClassTwo = null;
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
}
someEventManager.notifyListeners();
}
}
Event Interface
public interface SomeEventListener {
public void handleSomeEvent();
}
Event Manager
import java.util.ArrayList;
import java.util.List;
public class SomeEventManager {
private static SomeEventManager eventManager = null;
private List<SomeEventListener> listeners = null;
private SomeEventManager() {
listeners = new ArrayList<SomeEventListener>();
}
public static SomeEventManager getInstance() {
if (eventManager == null) {
eventManager = new SomeEventManager();
}
return eventManager;
}
public void addListener(SomeEventListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
public void removeListener(SomeEventListener listener) {
listeners.remove(listener);
}
public void notifyListeners() {
for(SomeEventListener listener : listeners) {
listener.handleSomeEvent();
}
}
}
Event Listener Implementation
public class SomeImplClass {
private InnerEventListener myEventListenerA = null;
private InnerEventListener myEventListenerB = null;
private String id = null;
public SomeImplClass(String id) {
this.id = id;
myEventListenerA = new InnerEventListener(id + "_A");
myEventListenerB = new InnerEventListener(id + "_B");
}
public void releaseListeners() {
myEventListenerA.unregisterListener();
myEventListenerB.unregisterListener();
}
private class InnerEventListener implements SomeEventListener {
private SomeEventManager someEventManager = null;
private String id = null;
public InnerEventListener(String id) {
someEventManager = SomeEventManager.getInstance();
this.id = id;
registerListener();
}
public void registerListener() {
someEventManager.addListener(this);
}
public void unregisterListener() {
someEventManager.removeListener(this);
}
public void handleSomeEvent() {
System.out.println("InnerEventListener->" + id);
}
}
}
The solution we use is to have the listener automatically unregister itself if it gets called and the thing it's updating has been collected.
It looks a bit like this:
private static class InnerEventListener implements SomeEventListener {
private final WeakReference<ThingToUpdate> thingRef;
public InnerEventListener(ThingToUpdate thing) {
thingRef = new WeakReference<>(thing);
}
#Override
public void handleSomeEvent(SomeEvent event) {
ThingToUpdate thing = thingRef.get();
if (thing != null) {
thing.updateSomehow();
} else {
((SomeEventedThing) event.getSource())
.removeSomeEventListener(this);
}
}
}
//...
SomeEventedThing eventedThing;
ThingToUpdate thingToUpdate;
//...
eventedThing.addListener(new InnerEventListener(thingToUpdate));
I wouldn't say it's a perfect solution because the listener sticks around until it gets an event, and it's still somewhat dependent on garbage collection. We've been trying to replace it with explicit removal where possible, usually on addNotify/removeNotify on GUI components.

How to properly convert Listeners to Reactive (Observables) using RxJava?

I'm using a multiplayer Game Client that's called AppWarp (http://appwarp.shephertz.com), where you can add event listeners to be called back when event's happen, let's assume we'll be talking about the Connection Listener, where you need to implement this interface:
public interface ConnectionRequestListener {
void onConnectDone(ConnectEvent var1);
void onDisconnectDone(ConnectEvent var1);
void onInitUDPDone(byte var1);
}
My goal here is to mainly create a Reactive version of this client to be used in my Apps Internally instead of using the Client itself directly (I'll also rely on interfaces later instead of just depending on the WarpClient itself as in the example, but that's not the important point, please read my question at the very end).
So what I did is as follows:
1) I introduced a new event, named it RxConnectionEvent (Which mainly groups Connection-Related events) as follows:
public class RxConnectionEvent {
// This is the original connection event from the source client
private final ConnectEvent connectEvent;
// this is to identify if it was Connection / Disconnection
private final int eventType;
public RxConnectionEvent(ConnectEvent connectEvent, int eventType) {
this.connectEvent = connectEvent;
this.eventType = eventType;
}
public ConnectEvent getConnectEvent() {
return connectEvent;
}
public int getEventType() {
return eventType;
}
}
2) Created some event types as follows:
public class RxEventType {
// Connection Events
public final static int CONNECTION_CONNECTED = 20;
public final static int CONNECTION_DISCONNECTED = 30;
}
3) Created the following observable which emits my new RxConnectionEvent
import com.shephertz.app42.gaming.multiplayer.client.WarpClient;
import com.shephertz.app42.gaming.multiplayer.client.events.ConnectEvent;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;
public class ConnectionObservable extends BaseObservable<RxConnectionEvent> {
private ConnectionRequestListener connectionListener;
// This is going to be called from my ReactiveWarpClient (Factory) Later.
public static Observable<RxConnectionEvent> createConnectionListener(WarpClient warpClient) {
return Observable.create(new ConnectionObservable(warpClient));
}
private ConnectionObservable(WarpClient warpClient) {
super(warpClient);
}
#Override
public void call(final Subscriber<? super RxConnectionEvent> subscriber) {
subscriber.onStart();
connectionListener = new ConnectionRequestListener() {
#Override
public void onConnectDone(ConnectEvent connectEvent) {
super.onConnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_CONNECTED));
}
#Override
public void onDisconnectDone(ConnectEvent connectEvent) {
super.onDisconnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_DISCONNECTED));
}
// not interested in this method (for now)
#Override
public void onInitUDPDone(byte var1) { }
private void callback(RxConnectionEvent rxConnectionEvent)
{
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(rxConnectionEvent);
} else {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
};
warpClient.addConnectionRequestListener(connectionListener);
subscriber.add(Subscriptions.create(new Action0() {
#Override
public void call() {
onUnsubscribed(warpClient);
}
}));
}
#Override
protected void onUnsubscribed(WarpClient warpClient) {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
4) and finally my BaseObservable looks like the following:
public abstract class BaseObservable<T> implements Observable.OnSubscribe<T> {
protected WarpClient warpClient;
protected BaseObservable (WarpClient warpClient)
{
this.warpClient = warpClient;
}
#Override
public abstract void call(Subscriber<? super T> subscriber);
protected abstract void onUnsubscribed(WarpClient warpClient);
}
My question is mainly: is my implementation above correct or should I instead create separate observable for each event, but if so, this client has more than 40-50 events do I have to create separate observable for each event?
I also use the code above as follows (used it in a simple "non-final" integration test):
public void testConnectDisconnect() {
connectionSubscription = reactiveWarpClient.createOnConnectObservable(client)
.subscribe(new Action1<RxConnectionEvent>() {
#Override
public void call(RxConnectionEvent rxEvent) {
assertEquals(WarpResponseResultCode.SUCCESS, rxEvent.getConnectEvent().getResult());
if (rxEvent.getEventType() == RxEventType.CONNECTION_CONNECTED) {
connectionStatus = connectionStatus | 0b0001;
client.disconnect();
} else {
connectionStatus = connectionStatus | 0b0010;
connectionSubscription.unsubscribe();
haltExecution = true;
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
fail("Unexpected error: " + throwable.getMessage());
haltExecution = true;
}
});
client.connectWithUserName("test user");
waitForSomeTime();
assertEquals(0b0011, connectionStatus);
assertEquals(true, connectionSubscription.isUnsubscribed());
}
I suggest you avoid extending the BaseObservable directly since it's very error prone. Instead, try using the tools Rx itself gives you to create your observable.
The easiest solution is using a PublishSubject, which is both an Observable and a Subscriber. The listener simply needs to invoke the subject's onNext, and the subject will emit the event. Here's a simplified working example:
public class PublishSubjectWarpperDemo {
public interface ConnectionRequestListener {
void onConnectDone();
void onDisconnectDone();
void onInitUDPDone();
}
public static class RxConnectionEvent {
private int type;
public RxConnectionEvent(int type) {
this.type = type;
}
public int getType() {
return type;
}
public String toString() {
return "Event of Type " + type;
}
}
public static class SimpleCallbackWrapper {
private final PublishSubject<RxConnectionEvent> subject = PublishSubject.create();
public ConnectionRequestListener getListener() {
return new ConnectionRequestListener() {
#Override
public void onConnectDone() {
subject.onNext(new RxConnectionEvent(1));
}
#Override
public void onDisconnectDone() {
subject.onNext(new RxConnectionEvent(2));
}
#Override
public void onInitUDPDone() {
subject.onNext(new RxConnectionEvent(3));
}
};
}
public Observable<RxConnectionEvent> getObservable() {
return subject;
}
}
public static void main(String[] args) throws IOException {
SimpleCallbackWrapper myWrapper = new SimpleCallbackWrapper();
ConnectionRequestListener listner = myWrapper.getListener();// Get the listener and attach it to the game here.
myWrapper.getObservable().observeOn(Schedulers.newThread()).subscribe(event -> System.out.println(event));
listner.onConnectDone(); // Call the listener a few times, the observable should print the event
listner.onDisconnectDone();
listner.onInitUDPDone();
System.in.read(); // Wait for enter
}
}
A more complex solution would be to use one of the onSubscribe implementations to create an observable using Observable.create(). For example AsyncOnSubscibe. This solution has the benefit of handling backperssure properly, so your event subscriber doesn't become overwhelmed with events. But in your case, that sounds like an unlikely scenario, so the added complexity is probably not worth it.

How to use non static method (observer method) in static main

want to use non static method in static main, but i cant. I know this problem but, because i use INotificationObserver, i cant make registerObserver as static. So i could solve my problem.
How can i solve this problem ?? Thanks .
non-static variable this cannot be referenced from a static context
Test
public class PushTest implements INotificationObserver{
NotificationService ns = NotificationService.getInstance();
public static void main(String[] args) {
try {
ns.registerObserver(this); // How can i register ???
Interface
public interface INotificationSubject {
public void registerObserver(INotificationObserver o);
public void removeObserver(INotificationObserver o);
public void notifyObserver(PushedNotification notification);
}
*NotificationService *
public class NotificationService implements INotificationSubject{
protected static final Logger logger = Logger.getLogger(NotificationService.class);
private volatile static NotificationService uniqueFactory;
private ArrayList observers;
private NotificationService() {
observers = new ArrayList();
}
public static NotificationService getInstance() {
if (uniqueFactory == null) {
synchronized (NotificationService.class) {
if (uniqueFactory == null) {
uniqueFactory = new NotificationService();
}
}
}
return uniqueFactory;
}
public static INotification GetNotificationObject(DeviceTypes Types) {
INotification messageSender = null;
if (Types == Types.IOS) {
messageSender = new IosNotification();
}
return messageSender;
}
public void registerObserver(INotificationObserver o) {
observers.add(o);
}
public void removeObserver(INotificationObserver o) {
int i =
observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
public void notifyObserver(PushedNotification notification) {
for (int i = 0; i < observers.size(); i++) {
INotificationObserver observer = (INotificationObserver) observers.get(i);
observer.update(notification);
}
}
public void messageSendInfo(PushedNotification notification) {
notifyObserver(notification);
}
public void showSentInfo(PushedNotification notification) {
messageSendInfo(notification);
}
}
You need an instance:
INotificationObserver ino = new PushTest();
ns.registerObserver(ino);
Therefor, you don't need the ns attribute.
typical solution for this is initialize your class in the main method:
public class PushTest implements INotificationObserver{
NotificationService ns = NotificationService.getInstance();
public static void main(String[] args) {
PushTest pushTest = new Pushtest();
...
etc etc

Obtain object from overriden method

public class Job_GUI extends javax.swing.JFrame {
private JobDTO jdto;
public Job_GUI() {
initComponents();
}
private void menuEditJobActionPerformed(java.awt.event.ActionEvent evt) {
editJob.setVisible(true);
//here I want to obtain the updated dto.
}
}
public class JobDTO extends BaseDTO {
//setters and getters
}
class ListDataUI {
private void initListeners() {
summaryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
summaryTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final int selectedRowIndex = summaryTable.getSelectedRow();
if (selectedRowIndex != -1) {
BaseDTO dto = data.get(summaryTable.convertRowIndexToModel(selectedRowIndex));
} else {
}
}
}
});
}
}
I am not sure how to obtain the BaseDTO object dto to menuEditJobActionPerformed method so I can display all the values of the object. How do I pass this from valueChanged when event occurs? I'm simply using a table, when a row is selected, the dto state changes, need to pass this new state to the class Job_GUI actionperformed method
Declare dto right after your class GUI { declaration.
That way it will have global scope so all your functions can see it.
class GUI {
BaseDTO dto;
private void menuEditJobActionPerformed(java.awt.event.ActionEvent evt) {
editJob.setVisible(true);
//Now you can access "dto"
}
}
class ListDataUI {
private void initListeners() {
summaryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
summaryTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final int selectedRowIndex = summaryTable.getSelectedRow();
if (selectedRowIndex != -1) {
/*BaseDTO */dto = data.get(summaryTable.convertRowIndexToModel(selectedRowIndex));
//not declaring a new object
} else {
}
}
}
});
}
}

Categories

Resources