Cross-Activity references using GWT with Gin - gwt

I have a GWT MVP application using Activities and Places. This is inspired by Mauro Bertapelle's sample (in this thread), apparently based on some of Thomas Broyer's work.
Here's the problem: I have LoginActivity make an RPC call, which for a successful login, returns a User. This user has a role (e.g., admin, regular user, guest). Several Views and Activities, including a NavigatorView, depend on this role for what they show or do. How do I get this User instance to the other Activities?
I do not have a ClientFactory; injection (Gin) is used for instantiating the Views in the ActivityProviders which provide my Activities/Presenters, and the ActivityProviders are injected into my ActivityMapper. So this may reduce to a Gin question: how do I get the user reference where it's needed? This seems to be similar to this SO question about global references in MVP.
Consider me a Gin newbie, this is my first attempt at using it. I'm guessing there is a "Gin way" to make this happen, but I don't know Gin well enough to know the best way to do this (if Gin should be used at all).
Much thanks.
Edit 1: Despite my best efforts searching SO for a similar question, I just found this question which is pretty much identical to mine (is the SO algorithm for finding "Related" links better than the search?). I'm thinking that the Gin answer by David is on the right track.
I don't think that an EventBus solution is possible. I'm following the Google guidelines which involve instantiating Activity at every Place change, so a single Event by itself will not suffice.

Something that I'm using on the server-side with Guice, and would work just as well on the client-side, is to bind to a custom Provider. In your case though, you'd have to make the provider a singleton and push the value into it from your RPC callback (rather than pulling it from some context).
You'd first need a specific provider:
#Singleton
public class CurrentUserProvider implements Provider<User> {
private User currentUser;
public User get() { return currentUser; }
public void setCurrentValue(User currentUser) {
this.currentUser = currentUser;
}
}
You'd bind User to the provider: bind(User.class).toProvider(CurrentUserProvider.class)
In your RPC callback you'd inject a CurrentUserProvider so you can setCurrentValue but everywhere else you'd inject Provider<User> to keep CurrentUserProvider as an implementation detail. For very short-lived objects, you could directly inject a User value rather than a Provider<User>.
If you need to notify objects of the value change, you could dispatch an event on the global event bus.
Alternately, you could always use the concrete CurrentUserProvider type (which wouldn't have to implement Provider anymore) and possibly make it a HasValueChangeHandlers so you could register listeners on it rather than on the event bus (but you'd have to clean-up after yourself in your activities' onStop and onCancel to avoid memory leaks, whereas it's taken care of automatically if you register handlers on the event bus in onStart).
(if you ask me, I'd rather go away with authenticating from within the app whenever possible)

I had similar requirements on a recent project.
When I get a reply from login (or logout) RPC I send a custom AuthenticationEvent on EventBus. All activities that are interested in this listen for this event. AuthenticationEvent has a reference to AppUser object which is null if user just logged out. AppUser contains all necessary data (privileges, groups, etc..) so that activities can inspect it and act upon it.
About global references: you can have a class with static methods providing data that you need. This class internally holds singleton references to needed instances. In my example I have static method AppUtils.getCurrentUser(). Internally it holds a reference to AppUser and also listens to AuthenticationEvent to set/reset this field.
As a side note: don't rely on client side to enforce access restrictions - you should separate your RPC servlets into two groups: public and private. Public can be accessed by anybody (this is basically login/logout RPC and some other public info RPC), while private RPC requires user to be authenticated. Access restrictions can be set per path/servlet: http://code.google.com/appengine/docs/java/config/webxml.html#Security_and_Authentication
Update:
As you noted, class with static methods is not advisable in this setup, because it is not replaceable and this prevents testing (which is the whole point of using GIN).
The solution is to inject a utility class holding globals (AppUtils) into activities that need the globals. AppUtils should be declared singleton in GIN configuration as one instance is enough for the whole app.
To use Provider or not is just a question if you want to delay the initialization of dependencies (AppUtil is dependency). Since AppUtils is a singleton for the whole app it makes no sense to have it lazy initialized.
Sometimes you will have a situation where you have multiple Activities shown on screen (in my case it was MenuBar and InfoBar). In this case, when user logs in you will need a way to notify them of the change. Use EventBus.

Related

Why keep stores untouchable from the action creator on Facebook Flux?

I'm reading about the Facebook Flux and I liked the pattern, but I don't understand why we need keep the store untouchable from the action creator. Facebook only says that it's part of "concern separation" and only the store should know how modify itself. Facebook disagrees with store setters like "setAsRead", but doesn't triggering an event on the action creator through the dispatcher that are captured on the store almost the same thing? And calling something like "setAsRead" doesn't exposes how the store are modifying itself.
Some guys say it causes coupling between the store and action creator, but triggering events on the dispatcher causes coupling between the pub/sub, store and action creator.
Keeping the stores untouchable from the action creator creates the need of the "waitFor". Wait For chains doesn't create more implicit coupling between stores? If some action need stores interacting on some given order why doesn't already make this on the action creator?
Do you guys know the cons to adopt a dispatchless approach with Facebook Flux?
If you implement setters in your store, you would completely break the uni-directional data flow principle that is arguably the central principle of the Flux pattern. Nothing would stop your components, or any other code, from directly manipulating the store's state. Now data mutations no longer come from only stores reacting to actions, so you have many "sources of truth".
The uni-directional data flow principle is as follows, very simplified for the purpose of this discussion:
Actions ----> Stores ----> Components
^ |
|___________________________|
waitFor actually does create a coupling between stores, and it leaks into the Dispatcher which has to provide the waitFor function. It's arguably one of the more contended points of the "vanilla" Flux pattern, and for example Reflux implements it differently, without a central dispatcher.

asp.net mvc accessing class fields from a custom auth attribute

I am using a custom AuthAttribute to determine whether a user can access a controller and/or actions. The problem is I have to duplicate information and EFx connections in the attribute that already exist on the class that is being adorned.
My question is whether there is a way to access the fields on the adorned class from the custom AuthAttribute? I am trying to avoid having to re-architect the software in a way that would provide a single point of access since that would open up a different can of worms.
I believe I have found an answer that works. I welcome all comments on this solution.
Rather than have the attribute gain access to the properties and fields on the controller it adorns you can share values between them in a thread-safe way through the common HttpContext object. So if you are being extreme like I am and are trying to cut down on duplicate calls to your database in both the authattribute and the adorned controller action then pass the results forward. What that means is the authattribute will be called first and you can stash the retrieved values in the "Items" collection off the HttpContext object passed into the AuthorizeCore(..) method. You can then retrieve the same value in a THREAD-SAFE way through the HttpContext object in the controller.
example to save value within the AuthorizeCore(..) override of the AuthAttribute:
httpContext.Items.Add("fester", "bester");
example to retrieve value inside the subsequent call to the Controller/Action:
this.HttpContext.ApplicationInstance.Context.Items["fester"];
I have to warn you this is only a possible implementation that appears to work in simple testing. Personally it feels like a hack and there has to be a better way. I would also state this is in pursuit of a dubious performance benefit. It should cut down on the number of database and/or network calls by cache'ing retrieved data in the HttpContext so you don't have to repeat the calls in both the authattribute and the adorned Controller/Action. If you don't have a web site that gets a huge volume of calls then I would warn you against this.
I hope someone recommends something better on this page. I will keep an eye on how this works on my web site and let y'all know if it behaves and is truly thread-safe.

Better name for a method than "isThis()"

I have one class called OAuthLogin that supports the login of a user via OAuth. The website supports also a "traditional" login process, without OAuth. The two flows share a lot of code, where I need to differentiate them sometimes.
I have a static method OAuthLogin::isThis() that returns a boolean whether the current login flow is OAuth or not (by checking session variables and URL parameters).
I don't like the name of the method but I can't think of a better one - I guess that is a common concept, therefore there should be some kind of pattern.
I don't like OAuthLogin::isThisOAuthLogin() because is redundant.
I would like to avoid Login::isThisOAuth because I would like to keep all the code in the OAuthLogin class.
Should I go for OAuthLogin::is()? Anything better than that?
Thanks.
Your OAuthLogin class should only have one responsibility, and that is to enable a user to login using OAuth; this class should have no knowledge of the "traditional" login process. A person who sees this class name (e.g. StackOverflow users!) will assume that this class is only responsible for login functionality using OAuth.
As your two login processes share a lot of code, then you really should refactor your code so that you have a base class with the common code, and then have separate classes for OAuth and Traditional login which will both inherit from the base class. When your code executes you should then instantiate the login class that is appropriate for that user's session.
Also as your OAuthLogin class is static then how will it be able to handle many users logging-in at the same time? Hence another good reason to refactor it so that it is not static.
If you absolutely cannot refactor, then without seeing your code, it sounds as if the OAuthLogin class is really a mediator i.e. it encapsulates how a set of classes interact (in this case your login classes). So instead of using the name "OAuthLogin" you could call it "LoginMediator". You could then have the properties:
LoginMediator.isOauthLogin
and
LoginMediator.isTraditionalLogin
to distinguish between the different types of login which the mediator is using for that particular session. Though instead of using the word "Traditional" replace this with the other authentication mechanism you actually use (e.g. HTTP Basic Authentication, HTTP Digest Authentication, HTTPS Client Authentication etc.)
Note how I have chosen intention-revealing names for these properties. If a stranger was to read your code (e.g. me!) they would struggle to understand the purpose of "is()" and "isThis()" from just the method signature.
However, in the long run I really do recommend that you refactor your code so that you have classes with discrete responsibilities, as you will find that naming methods will be far easier as a result.
I would add a method to the base class which just returns the type of the login.
Class (pseudo-code)
class Login
method class
return self.class # Returns the current class.
end
end
Usage would be (also pseudo-code):
if currentLogin.class == OAuthLogin
# ..
else
# ..
end
This would let you add more types later on, without having to add type-specific methods for each login type, leaving the control flow outside of your classes.
I suggest one of:
OAuthLogin::isCurrent()
OAuthLogin::isCurrentLogin()
OAuthLogin::isCurrentFlow()
OAuthLogin::isCurrentLoginFlow()
OAuthLogin::isActive()
OAuthLogin::isActiveLogin()
OAuthLogin::isActiveFlow()
OAuthLogin::isActiveLoginFlow()
How about OAuthLogin::isUsed()?
I suggest OAUthLogin::isLoggedIn().

Common calls handling using GWTP

I have a presenter which makes calls to Handler and get the data from server
same data is needed for another widget which is a miniature version of the existing view, but this will present all time in application.
Here what i have common is calls to handler, same handler and action objects.
What is the best way to design.
My possible solution :
1) Writing one Common class which has access to the dispatcher object (Inject through Ginjector), use the methods to get data.
But as per MVP architecture, dispatcher usage is restricted to presenter only, but this is non-presenter class.
AFAIK there is nothing about MVP which says that everything has to be done in the Presenter. It make sense to encapsulate logic which is common to multiple Presenters in one common class.
MVP is rather a pattern than a rule which is written in stone. So when it makes sense you can deviate a little bit from the pattern.
IMHO the common class is a the right approach.
Using a common class for handling the requests to the backend also makes it easy to implement caching and authentication for example.
There are two ways to do the communication between your Presenters and the common class:
Inject a singleton instance of your common class into all the Presenters that need the data. From the presenter you can call the a method on the common class and register a callback.
Inject the global EventBus into the common class and fire an Event (i.e. LoadDataEvent) from the corresponding Presenters and handle this Event in the common class. When the data is received from the backend you can fire another Event (i.e. DataLoadedEvent) from the common class and handle it in the corresponding Presenters.
Solution 1 is probably easier to implement but you have some coupling between the common class and the Presenter (it's not that bad if you use dependency injection).
Solution 2 requires a little bit more code (you have to define the Events) but provides a lot of flexibility and de-coupling. For example if you create a new Presenter that is also interested in the data you just need to register a Handler for the DataLoadedEvent in the Presenter and you are done.
If you are using event bus, your presenter(which makes calls to Handler) can fire events with new data and your miniature widget can register with event bus to receive them. This way only one presenter would call to server and anything on client can be notified using events.

Zend 2 Event Listeners in classes not loaded

Does the Zend 2 event manager have the ability to fire listeners in classes that are not loaded?
If I understand you correctly, then I believe that you can register listeners using the StaticEventManager (see Event Manager Quick Start).
In this case, you do not need to have an instance of the target class (just the name), but you can register listeners for events (typically methods) on future instances of that target class that may occur.
Of course, in order to be useful, the target class should actually compose an EventManager instance (probably via an events() method, as described on the same Quick Start page) and actually fire the events.
I confess that I am still trying to wrap my own head around the ZF2 EventManager, so if I have totally boned it up here, please feel free to correct me.