How to create Event & handler correctly - event-handling

I have property:
private bool isAuthenticated;
And I need to intercept when this property is changed to execute some code.
I create event:
public event EventHandler Authenticated;
and handler:
public void OnAuthenticated(EventArgs e)
{
EventHandler handler = Authenticated;
if (handler!= null)
{
handler(this, e);
}
}
But I have no idea how I can fix my task with it.
Sorry for my bad english...

Why dont you rather make use of a property, and do what ever checks you wish, or raise the event if you have to, in the setter?
Have a look at How to: Implement Property Change Notification

Related

Setting a User Attribute in Event Listener SPI - Keycloak

I'm trying to set a user's attribute after they register in my custom Keycloak extension. My event listener implementation looks as follows:
#AutoService(EventListenerProviderFactory.class)
public class EventListener implements EventListenerProvider {
private final KeycloakSession session;
public EventListener(KeycloakSession session) {
this.session = session;
}
#Override
public void onEvent(Event event) {
if (event.getType() != EventType.REGISTER)
return;
RealmModel realm = session.realms().getRealm(event.getRealmId());
UserModel user = session.users().getUserById(realm, event.getUserId());
user.setSingleAttribute("hello", "world");
}
#Override
public void onEvent(AdminEvent event, boolean includeRepresentation) {
}
#Override
public void close() {
}
}
My extension is recognized by Keycloak and successfully triggers onEvent() when an event occurs (hence why I didn't include the factory class).
However, the attribute isn't added to the user. How do I actually persist the changes to the user?
While searching for a solution to the above, I came across this discussion of a very similar issue. Extending RegistrationUserCreation instead of EventListenerProvider and using the solution given by #dvlpphb did actually manage to solve my problem; however, the solution only worked when overriding the RegistrationUserCreation's validate() method, which is called every time the user attempts to register.
If anyone knows a way to set a user attribute without EventListenerProvider through RegistrationUserCreation's success() callback, that would also solve my issue.
Thank you!

MVVM: OnBindingContextChange: PropertyChanged not firing in new view model

I am coding a Xamarin app and doing my best to adhere to MVVM, which I actually really like
I commonly have ContentPages containing references to Views.
I set the binding context to a VM in the Page, and then make use of OnBindingContextChanged in the view
This allows me to use PropertyChanged method to then respond to display logic conditions for my View
I've used it several times successfully but I am baffled why an additional implementation isn't working
Page looks like this
public partial class BindingTextPage : ContentPage
{
public BindingTextPage()
{
InitializeComponent();
this.BindingContext = new ViewModels.LocationsViewModel();
}
}
View looks like this
private LocationsViewModel_vm;
public BindingTestView()
{
InitializeComponent();
System.Diagnostics.Debug.WriteLine("Debug: Initialised BindingTesView view");
}
protected override void OnBindingContextChanged()
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: OnBindingContextChanged: Context " + this.BindingContext.GetType());
_vm = BindingContext as LocationsViewModel;
_vm.PropertyChanged += _vm_PropertyChanged;
}
private void _vm_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
try
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Method called");
System.Diagnostics.Debug.WriteLine("Debug: BindingTest: Property " + e.PropertyName);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Debug: BindingTestView: Error changing context " + ex.Message);
}
}
Extract of view model, very simply in this case setting a string and hence changing a property, which I would have expected would then cause PropertyChange to fire?
public LocationsViewModel()
{
tempMessage = "this is from the view model";
}
public string tempMessage
{
get
{
return _tempMessage;
}
set
{
_tempMessage = value;
OnPropertyChanged(nameof(tempMessage));
}
}
My debug statements when it boots up shows that OnBindingContextChange is being called, but in this one instance _vm_PropertyChanged never fires? I'd expect tempMessage being set to do so?
The order of events in your code is the following
Constructor of LocationsViewModel is called
From your constructor, you are setting tempMessage
The setter of tempMessage calls OnPropertyChanged, since the event is null at the time being, it's not fired
Constructor of LocationsViewModel is left
Page.BindingContext is set
OnBindingContextChanged is called
LocationsViewModel.PropertyChanged is subscribed by your page
Since the event is raised (or it's tried to) before your page subscribes to, your page simply does not get informed about the event being raised. If you set the value after the event has been subscribed to, the handler will be called as expected.
e.g.
protected override void OnBindingContextChanged()
{
_vm = BindingContext as LocationsViewModel;
_vm.PropertyChanged += _vm_PropertyChanged;
_vm.tempMessage = "Hello, world!"; // clichée , I know
}

Register multiple EventHandlers for one portlet

I would like to register more than one EventHandler in a Portlet in my portlet.xml.
Right now it looks like this:
When trying to add a second block of init-param i get an error:
Than i tryed to add multiple EventHandler in one init-param block, but i get this error:
Can i register more than one EventHandler classes?
if yes, how is it done correctly?
The bridge is expecting only one event handler, but you can create one that delegates to both instances:
public class BridgeEventHandler {
private BridgeEventHandler eventHandler1 = new ...;
private BridgeEventHandler eventHandler2 = new ...;
public EventNavigationResult handleEvent(FacesContext facesContext, Event event);
EventNavigationResult result = eventHandler1.handleEvent(facesContext, event);
if (result != null) {
return result;
}
return eventHandler2.handleEvent(facesContext, event);
}
}

RxJava (or Rx.NET) equivalent of ReactiveCocoa's RACObserve

Given an arbitrary field on a Java object, I want to create an Observable that will watch that field and push a new result to an Observer every time the value of the field changes. ReactiveCocoa has a macro called RACObserve, which appears to do exactly this.
I want to know how to implement similar functionality using RxJava.
For example, say I had the following simple class:
public class Foo {
enum State {
Idle,
Ready,
Error
}
private State currentState = State.Idle;
//methods that can change currentState
}
I want to create an Observable<State> that will push the new state to an Observer every time something changes the value of currentState.
In ReactiveCocoa, it looks like I would write something sort of like the following (please excuse my pseudo Objective-C):
[RACObserve(self, currentState) subscribeNext:^(NSString *newState) {
NSLog(#"%#", newState);
}];
How would I achieve similar functionality in RxJava? I'm thinking that I may need to wrap all changes to currentState in a setter, but it's not clear to me where I should then call Observable.create and how to feed the changes of currentState to an Observer.
ReactiveCocoa is actually more similar to ReactiveUI (http://www.reactiveui.net) than just plain Rx. And in ReactiveUI, you can use this.WhenAnyValue(x => x.PropName) to do exactly what you want.
I stumbled across this same problem recently, I ended up using PropertyChangeListener, which will emit an object when a property is changed, see the following:
Update Listener:
public class GameUpdateListener {
public static Observable<Object> changed(Game game) {
final BehaviorSubject<Object> subject = BehaviorSubject.create((Object)game);
game.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
subject.onNext( (Object)propertyChangeEvent.getNewValue());
}
});
return subject;
}
}
Some custom object:
public class Game {
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
...
public setSomeField(String field){
this.field = field;
pcs.firePropertyChange("field", this.field, field);
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
pcs.addPropertyChangeListener(propertyChangeListener);
}
...
}
Observe:
Game game = new Game();
GameUpdateListener listener = new GameUpdateListener();
final Observable<Object> gameObserver = listener.changed(game);
gameObserver.subscribe(new Action1<Object>() {
#Override
public void call(Object o) {
Log.e(TAG, "Object Changed");
}
});
game.setSomeField("New value");
This will work fine as long as you don't need to instantiate your object again. Perhaps a solution to this is to create a local setter method and emit a change there.
Since your question title contains "or Rx.NET", here is my suggestion (I dunno bout RxJava, you may find something similar).
You probably will have to leverage some sort of mechanism in the setter. The standard way in .NET is by using the INotifyPropertyChanged interface.
Then by firing the events, you can create an IObservable<T> from this stream by using
Observable.FromEvent<TEvent, TArgs>()
You can find a really good example of what you want to do (.NET) here.
(credits to Rob Foncesa-Ensor)
I think what you are after is a Subject<T>. It implements IObserver<T>, so you can call OnNext(T) to fire a new value, as well as IObservable<T>, which you can expose it as publicly so it can be subscribed to.
If you need it to fire the latest value to new subscribers, you can use a ReplaySubject<T> with a buffer size of 1.
Here's a basic implementation:
public class SomeService
{
private Subject<int> values = new Subject<int>();
public IObservable<T> Values
{
get
{
// AsObservable prevents it from being cast back to Subject
return values.AsObservable();
}
}
// Private; called by some internal mechanism
private void SetValue(int newValue)
{
newValue.OnNext(newValue);
}
}

GWT Multiple Events Handling

I have 3 widgets on my UI side (1 ListBox, 2 TextBoxes). I would like to create an Handler which could handle value change event if any of the three widgets value changes and also if on Blur for ListBox.The skeleton of code would be something like this
registerHandler(new multiWidgetHandler());
private class multiWidgetHandler{
//code for handling onValueChange for 3 widgets and also onBlur for listBox
}
I am not sure how to implement this cleanly. Need help. Some example code would be appreciated.
You can implement multiple Handler interfaces in the same handler, and then add that handler multiple times.
private class MultiWidgetHandler implements ValueChangeHandler<String>, BlurHandler, ChangeHandler
{
protected void handleIt() { Window.alert("These events are so handled right now!"); }
public void onBlur(BlurEvent e) { handleIt(); }
public void onValueChange(ValueChangeEvent<String> e) { handleIt(); }
public void onChange(ChangeEvent e) { handleIt(); }
}
...
MultiWidgetHandler handler = new MultiWidgetHandler();
listBox.addChangeHandler(handler);
listBox.addBlurHandler(handler);
textArea1.addValueChangeHandler(handler);
textArea2.addValueChangeHandler(handler);
Why are you planning such a behaviour? Usually on handler for one event. If you want to channel all 3 events to a single handler you could make your 3 different handlers call a "global" method : HandleAllEvents(). If all events are of the same type you can register the same handler 3 times.