GWT: DefaultHistorian vs Mapper Objects? - java

The GWT JavaDocs for the PlaceHistoryHandler#DefaultHistorian are vague and cyclic:
Default implementation of PlaceHistoryHandler.DefaultHistorian.
This doesn't really tell us what it is, or what it does!
Then we have the PlaceHistoryMapper and the ActivityMapper objects. My understanding is that the PlaceHistoryMapper's job is to map URL tokens to Place, and that ActivityMapper maps those Places to Actvitity implementations.
So I ask: if these two Mappers take care of binding a URL token to a specific Activity, then what role does the DefaultHistorian play in all of this?

Javadoc is easy to correct at read time: DefaultHistorian is the default implementation of Historian.
To understand how they all play together, you first have to understand that places can work without history, and also without activities.
So, in the central place are places: PlaceController keeps a current Place (getWhere), which can be modified by goTo and broadcasts change events to an EventBus. Listeners can ask the user to confirm (PlaceChangeRequestEvent's setMessage) through Delegate (whose default implementation uses Window.confirm).
Built on top of PlaceRequestChangeEvent and PlaceChangeEvent are activities. You can have several ActivityManagers, each one with its ActivityMapper and a display region, displaying a different activity each for the same given/current place.
And on the other side, based on goTo and the above-mentioned events is history. PlaceHistoryHandler listens to events on both sides and either updates the history (through the Historian) or updates the places (through PlaceController's goTo). The PlaceHistoryMapper maps between both worlds. The default implementation of the Historian (DefaultHistorian) uses com.google.gwt.user.client.History and com.google.gwt.user.client.Window#addWindowClosingHandler. You could provide your own implementation that uses HTML5's pushState and onpopstate for instance.
See:
http://blog.ltgt.net/gwt-21-places/
http://blog.ltgt.net/gwt-21-places-part-ii/
http://blog.ltgt.net/gwt-21-activities/
http://blog.ltgt.net/gwt-21-activities-nesting-yagni/

Related

How to model parent-child relationship in Android MVVM VMs?

I'm working on an Android piano "quiz" app - users tap on the piano keys and then click the yellow "check" button to submit the answer for evaluation and see the correct answer drawn on the piano. The main QuizActivity has this layout:
The upper part of the screen hosts a couple of controls (Text, submit buttons, etc.).
The lower part of the screen is occupied by a custom PianoView component, that handles drawing of the piano keyboard.
According to the MVVM principles, the PianoView should have its own PianoViewModel, that stores its state (i.e. currently pressed keys, highlighted keys, etc...) in a KeysStateRepository.
The enclosing QuizActivity should also have a QuizActivityViewModel, that handles the various controls (submitting an answer, skipping a question...).
The QuizActivityViewModel needs to be able to query the selected keys from the PianoView (or rather from its KeysStateRepository), submit them to the Domain layer for evaluation and then send the results back to the PianoView for visualization.
In other words, the QuizActivity's ViewModel should own/be a parent of the PianoView's ViewModel to facilitate communication and data sharing.
How can I model this parent-child relationship to communicate between the ViewModels?
AFAIK a ViewModel cannot depend on another ViewModel (What would I pass as the ViewModelStoreOwner to obtain a ViewModel in another Viewmodel?). I don't think it's possible to achieve with Dagger-Hilt at least.
Three solutions to work around this problem came to mind, all of them unusable:
1 - The official way of sharing data between Views
The Android dev docs recommend using a shared ViewModel to facilitate sharing of data between two Fragments / Views. However, this does not fit my use-case. The PianoView (or its ViewModel) should be the sole owner of its state with a Repository scoped to its ViewModel. Otherwise, the PianoView component would not be reusable. Consider for example another Activity, where I'd like to have two independent PianoView instances visible:
Reusing a Shared ViewModel from the quiz activity would be obviously wrong, because it contains irrelevant methods and logic (i.e. submitting quiz answers) and would not fit the two-keyboard scenario.
2 - Application-scoped repository
A similar problem was tackled on Reddit with a proposed solution of using a shared instance of the repository. However, using a #Singleton KeyStateRepository would once again prevent the two independent keyboards to display different data.
3(EDIT) - 2 duplicate repositories replicated by an Event Bus
I could in theory create 2 independent ViewModels and 2 KeyStateRepository instances. The ViewModels would subscribe to an event bus. Each time a ViewModel invokes a mutable operation on its repository, it would also fire an event and the operation would get replicated via the other ViewModel subscribed to the same event bus.
However, this feels like a fragile & complicated hack. I'd like to have a simple MVVM-compatible solution. I can't believe a simple parent-child relationship for two UI components is something unattainable in MVVM.
I think you got a decent answer from Pavlo up there, I'll just clarify what he meant with other words.
KeyStateRepository is a storage for the state of piano keys. There's nothing stopping you from making it to support N number of Pianos at the same time, this would solve the scenario where you have NNN Pianos on Screen, each with different keys pressed.
The PianoView should be contained in a Fragment, that should be your "unit". Why? Because you want a ViewModel to handle the state and events coming to/from the view. And a Fragment is the Android artifact provided for that regard. Think of it as an annoying piece of baggage you need. Android Devs used to call these things "Policy Delegates" because you delegate to these (a Fragment/Activity) some things you cannot do without "the framework" (the Android Framework, that is).
With this in mind, you have an Activity whose viewModel/State is handled independently. What State/Events do this viewModel handle? Things that are not in the PianoFragment/View(s). E.g. if you wanted to handle the back navigation, or a "record" button at the top, this is the activity's domain. What happens inside the "PianoView/Fragment" is not this activity's problem.
Now the Fragment that will contain the actual PianoView can be designed to contain "more than one" or just one. If you go for more than one, then the PianoContainerFragment will be designed with a ViewModel designed to handle more than one PianoView (so each view will have a "name/key") and the KeyStateRepo will be able to handle the "CRUD" operations of any Piano View you throw at. The ViewModel will sit in between, dispatching events for different "subscribed" views.
If you elect to go for "one fragment contains one piano view", then it's a similar architecture, but now handling the multiple "fragments" in one "activity" is now responsibility of the Activity (and its view model). But remember, the PianoViews (via a Fragment either shared or not) talk to a ViewModel that can be shared among piano views, that talks to a common KeyState Repo. The activity coordinates the views and other Android things (navigation, etc.) but the views operate independently, even of each other.
You don't really need a shared viewModel I think, in fact, I wouldn't do it until really needed, the more you separate things, the less the chances of "violating" one of the fancy patterns... but if you elect to use the PianoViewModel as a shared among all views, that's perfectly acceptable, you're going to have to include the Piano "Name" to differentiate whose events are for whom.
In other words (showing with ONE PianoViewModel for ASCII Simplicity),
// One QuizActivityViewModel, Multiple Fragments:
Activity -> PianoFragment (PianoView)|
| <-> PianoViewModel <-> KeyRepo
PianoFragment (PianoView)| /
-> QuizActivityViewModel <----------------------/
Here the QuizActivity creates N fragments (in a list maybe?). These fragments internally initialize their pianoView and connect to a PianoViewModel (can be shared like in the graph above) or each can have its own. They all talk to the same Repo. The repo is your "single source of truth about what each "piano". What keys are pressed, and anything else you can think of (including a name/key to make it unique).
When QuizActivity needs to evaluate the state of these, it will ask (via its own viewModel) for the state of NN pianos.
Or
// 1 Act. 1 Frag. N Views.
Activity -> PianoFragment (PianoView)|
(PianoView)| <-> PianoViewModel <-> KeyRepo
-> QuizActivityViewModel <---------------------------/
With these, the QuizActivity (which created the pianos to begin with as well), also knows the keys of the pianos that will/are displayed. It can talk to its viewModel that talks to the same KeysRepo (you only have one of these and that's fine). So it can still handle the "nav" buttons and it can ask (via its QuizActVM) what the current state of the Keys are (for all involved pianos). When a Piano key event is fired in a PianoView, the PianoViewModel will receive the event (what key was touched, in what piano); the KeyStateRepo will record this, and perhaps update a flow {} with the events coming from the pianos...
The Flow will be expressed in a sealed class which will contain enough information for both QuizActivity + VM (to perhaps perform a real-time validation), and to the PianoViewModel to update the state and push a new state to the PianoFragment (Which will update the state of its view(s)).
This is all common to either method. I hope this clarifies the sequence.
Does this make sense to you?
Edit
In a multiple architecture activity if you wan't PianoViews to have ViewModels and your ActivityViewModel to know about them - don't use Dagger injection with them but create PianoViewModels inside an ActivityViewModel and assign some callback to them on the stage of creation - thus you will have an access to them and will be able to listen to their events and influence their behaviour as well as save their state, from inside the ActivityViewModel. It is not an uncommon and in some cases even a correct approach. Dagger - is a mere instrument that is not intended to be used everywhere, but only there were it is needed. It is not needed to create PianoViewModels - you can inject all the needed stuff into the ActivityViewModel and pass all the needed elements to PianoViewModels constructors.
Also you don't need to wrap your Views into Fragments if you don't want to.
Edit end
You are making wrong assumptions based on a flawed architectural approach.
I am curious why do you need ActivityViewModel at all. View model should exist only for the elements that have some View. Current android development suggests that the Activity should not have a view representation and serve as a mere container of other views(Single activity principle). Depending on your architecture Activity may handle showing the loading state(progress bar) and some errors, but once again it should not contain anything that is being handled by other views. Thus PianoView should be a PianoFragment with its own ViewModel that handles access to its repository on the data layer via interactor on the domain layer.
The shared view model would work in case you would need one, and you would be using the Single activity principle with multiple fragments. Because Jetpack Navigation has the support of the shared view model out of the box. In the case of a shared view model - each fragment would have its own view model along with a shared one for communication. Each navigation graph could have a separate shared view model only for the fragments it contains.
Also regarding KeyStateRepository - you need only one of those(or a Dagger #Scoped multiple copies - but I do not recommend it). The only change should be - the addition of an extra key for each separate PianoView - to distinguish them inside a KeyStateRepository. To easily achieve that you may be using Room or some other file/memory/database cache mechanism.
Hence the initial problem of your app is not an inverted dependency of ActivityViewModel on a PianoViewModel, but a flawed architecture of the app and its inner interactions. If you want to continue work with your current architecture - there is no easy answer to your question, and almost every chosen solution would not be 'clean' enough to justify its usage.
I would do the following, if you don't want to tie the PianoViewModel to your ActivityViewModel, I'd just create an interface, which the ActivityViewModel implements, and the PianoVM could have a nullable reference to that interface. This way neither the implementation, nor the existence of the component would be required for the PianoViewModel to work.
How you get the ActivityViewModel is another question. Check out by activityViewModels() implementation for fragments, you probably can do the same with by viewModels() passing in the viewModelStore of the activity instead

Should I pass information inside Observer Events

I have an Event Login. I plan to populate that event with information such as this:
// Class A.
Login login = new Login();
login.setUsername(userName);
observer.notifyEvent(login);
The idea is for class B to get this information.
Is this bad practice? If so why?
The only forseable problem is that some other part of the software will be listening to this for no reason. When in reality only one class should be getting the information.
The only advantage is that all my classes are connected to the Observer object, but not connected to each other. In other words, if I wanted to pass the username I would need to connect A and B. Which I would only do in extreme circumstances.
Not much of a problem. - However, you may want to include the "sender" of the event in the event object so that the listener can identify where it comes from and, if needed, can get further state information from the event source.
The Observer pattern allows you to decouple the source of the event from the consumers of an event.
This is generally a good idea, even if you are only going to register one consumer.
However, I'll recommend you not to use the java.util.Observer which uses plain java.lang.Object as events, which means you must check the event object via instanceof and cast to the appropriate class.
I think its better to use an Observer or Listener implementation which supports generic types, such as Spring's ApplicationListener or Guava's EventBus which allow you to register Listener for events of particular class type, such as Login.class in your example.
Well, you probably need to dive a bit deeper into the original GoF book. For such a situation when a developer cares about different components that might be interested in different types of events the book offers the subjects collection that is maintained by the ChangeManager.
So when a component is interested in a specific type of event it passes a specific subject to the Register method so that this component won’t receive the updates for the events that represent a different subject. Additional advantage is the further decreasing of coupling.
Alternatively you might end up with building the system where any component that is plugged to the wire listens to all the events but that solution is too generic and adds lots of risks to the implementation (e.g. in the runtimes with automatic memory management like .NET the garbage collector won’t collect the subscriber while it is listening to any event – just because the ChangeManager still maintains a reference to it). It adds an additional responsibility to the subscriber - it has to do the additional filtering of events analyzing their type.
The rule of thumb is that you don’t need to subscribe for a specific event if you’re not interested to be notified when it occurs.
Referring to your example it is much better to introduce the Login subject and not to subscribe to it any component that is not interested in this specific subject.

How to approach JMX Client polling

recently I dove into the world of JMX, trying to instrument our applications, and expose some operations through a custom JMXClient. The work of figuring out how to instrument the classes without having to change much about our existing code is already done. I accomplished this using a DynamicMBean implementation. Specifically, I created a set of annotations, which we decorate our classes with. Then, when objects are created (or initialized if they are used as static classes), we register them with our MBeanServer through a static class, that builds a dynamicMBean for the class and registers it. This has worked out beautifully when we just use JConsole or VisualVM. We can execute operations and view the state of fields all like we should be able to. My question is more geared toward creating a semi-realtime JMXClient like JConsole.
The biggest problem I'm facing here is how to make the JMXClient report the state of fields in as close to realtime as I can reasonably get, without having to modify the instrumented libraries to push notifications (eg. in a setter method of some class, set the field, then fire off a JMX notification). We want the classes to be all but entirely unaware they are being instrumented. If you check out JConsole while inspecting an attribute, there is a refresh button at the bottom of the the screen that refreshes the attribute values. The value it displays to you is the value retrieved when that attribute was loaded into the view, and wont ever change without using the refresh button. I want this to happen on its own.
I have written a small UI which shows some data about connection states, and a few field on some instrumented classes. In order to make those values reflect the current state, I have a Thread which spins in the background. Every second or so the thread attempts to get the current values of the fields I'm interested in, then the UI gets updated as a result. I don't really like this solution very much, as its tricky to write the logic that updates the underlying models. And even trickier to update the UI in a way that doesn't cause strange bugs (using Swing).
I could also write an additional section of the JMXAgent in our application side, with a single thread that runs through the list of DynamicMBeans that have been registered, determines if the values of their attributes have change, then pushes a notification(s). This would move the notification logic out of the instrumented libraries, but still puts more load on the applications :(.
I'm just wondering if any of you have been in this position with JMX, or something else, and can guide me in the right direction for a design methodology for the JMXClient or really any other advice that could make this solution more elegant than the one I have.
Any suggestions you guys have would be appreciated.
If you don't want to change the entities then something is going to have to poll them. Either your JMXAgent or the JMX client is going to have to request the beans every so often. There is no way for you to get around this performance hit although since you are calling a bunch of gets, I don't think it's going to be very expensive. Certainly your JMXAgent would be better than the JMX client polling all of the time. But if the client is polling all of the beans anyway then the cost may be exactly the same.
You would not need to do the polling if the objects could call the agent to say that they have been changed or if they supported some sort of isDirty() method.
In our systems, we have a metrics system that the various components used. Each of the classes incremented their own metric and it was the metrics that were wired into a persister. You could request the metric values using JMX or persist them to disk or the wire. By using a Metric type, then there was separation between the entity that was doing the counting and the entities that needed access to all of the metric values.
By going to a registered Metric object type model, your GUI could then query the MetricRegistrar for all of the metrics and display them via JMX, HTML, or whatever. So your entities would just do metric.increment() or metric.set(...) and the GUI would query the metric whenever it needed the value.
Hope something here helps.
Being efficient here means staying inside the mbean server that contains the beans you're looking at. What you want is a way to convert the mbeans that don't know how to issue notifications into mbeans that do.
For watching numeric and string attributes, you can use the standard mbeans in the monitor package. Instantiate those in the mbean server that contains the beans you actually want to watch, and then set the properties appropriately. You can do this without adding code to the target because the monitor package is standard in the JVM. The monitor beans will watch the objects you select for changes and will emit change notifications only when actual changes are observed. Use setGranularityPeriod to tell the monitor beans how often to look at the target.
Once the monitor beans are in place, just register for the MonitorNotifications that will be created upon change.
not a solution per se but you can simplify your polling-event translator JMXAgent implementation using spring integration. It has something called JMX Attribute Polling Channel which seems to fulfill your need. example here

Where is the Server Side in GWT Places & Activities?

If I understand correctly :
an Activity is a User action on widgets
This activity moves the application state in another Place
The url moves along, thanks to anchors (thought modern browsers have an api)
When we share the url, it define a Place, and it's enough to rebuild the State
(As I'm also a javascript guy, this looks much like Backbone's router and other modern JSFrameworks)
But to rebuild the State, we need to fetch some data to the Server. Is there anything in the P&A api to do this ? With RPC, this role is clearly done by GreetingServiceImpl that extends the RemoteServlet. With Backbone, we have the Sync object.
But I never see such code such when I look at A&P tutorials. Where is the Server ? Do we need RPC there ? Does it mix with RequestFactory ?
First, a small note about terminology:
A Place represents where you are in the app. When you look at that screen, it's generally composed of different "blocks", each dedicated to a specific activity, e.g.: a header (let's say with search box and logout link), a navigation menu, the "master" in a master-details view, the "details" in a master-details view. All these can be activities (though not necessarily, things that are never swapped to anything else won't gain anything being activities).
Because activities are by definition displayed on screen, you can interact with them, possibly triggering a move to another place (PlaceController#goTo).
The place is optionally synchronized with the URL (both ways) and generate browser history items; by default using the hash, but you can swap the implementation to use HTML5.
(places are similar to Backbone's router except they're type-checked, activities are a light layer on top with no equivalent in Backbone AFAICT)
Now to answer your question:
GWT is a toolkit, not a framework. That means most building blocks don't force you into using any other building block (places can work without activities, editors can work without widgets, etc.)
Activities start asynchronously, which is where you'd generally get the data from wherever it is. In the spirit of a toolkit, you're free to use whatever fits your needs: GWT-RPC, RequestFactory, RequestBuilder, Errai JAX-RS, Errai Bus, XMLHttpRequest, WebSockets, AppEngine Channels, etc. Some people also post events to their event bus to decouple the activity from how they get their data.
MVP describes the Client-architecture.
M_odel:
The business objects handled by you app.
V_iew:
UI elements, showing a representation of your model.
P_resenter:
A class which handles all userinteractions and modification to your model.
Lets assume you have an application which shows and stores Notes.
You have some Places:
a Place is like an good old HTML page in older days. In MVP it can be described a a set of running Presenter. In our simple application there are two places. Every Place does only have one running Presenter
NotesListPlace -> shows all stored notes
NotesEditPlace -> Creates / Edit a Note
The NotesEditPlace:
There is a View and a Presenter.
The View has an TextArea (for the Note) and a save button.
The presenter has a clickHandler for the save-button (there may be more, but as example it should be enough)
The User select a Note from the NoteList
PlaceChange from NoteListPlace -> NoteEditPlace
The Presenter starts and registers the click-handler at the view. If the button is pressed, the presenter reads the input from the textarea and update the Model (A new Notes-onject)
Now comes the server interaction. You can use every (GWT) transportlayer you want.
The success callback fires a PlaceChange event to the NoteListPlace.
All starts again. The presenter starts, a new server interacction to load the MOdel ( A List of Notes). The view is updated by the presenter...
Update 1
There is no need of a server. The presenter may persist the Model to the localStorage of the browser.
Update 2
You can use every transport mechanism you want. RequestFactory, GWT-RPC. I use RequestBuilder and GWT AutoBeans.

Alfresco - Best practices for custom document lifecycle (Java?)

After talking with some people at the DevCon in London and after looking at Records Management source code I noticed that there's actually no good example of how to implement custom documents lifecycle.
I know there's examples of rules and content modeling and even workflows but that solutions can't be really used to implement something more serious like Records Management.
What I'm wondering is how to effectively map a Java solution (I have more experience with OO and Java than Alfresco) to Alfresco. What should be defined as Java class and what should be type/aspect in content model. When to favor behaviour over rules and when to actually use workflows. In my first few projects I used workflows to implement document lifecycle, I wrote quite a lot of bussines/domain logic in workflow nodes - as actions (JS). I found out later that this is quite hard to maintain since you have some code in workflows, some in repository as scripts (Data Dictionary/Scripts) some Java, ...
Is the Records Management good example to start learning from and see some best practices in implementing full document lifecycle? Are there any other resources?
I'm strugling the most with how to implement full lifecycle in java and how to "centralize" the bussines/domain logic.
The scope of ECM is huge, and therefore it's quite hard to come up with completely general guidelines: you really need to stick with the use case you have to address and find the best solution to it. RM is a great example of how to implement a records management solution on top of Alfresco, but it's absolutely useless when it comes to implementing a web publishing process, for which the WCM QS is what you want to look at as a starting point.
On the whole of APIs Alfresco offers to developers, their inner characteristics are ultimately the best resource to understand when to use them. Let's see if I can make sense of (at least most important among) them.
Content Types
This is where you always need to start implementing an Alfresco project. You need to closely work with someone with deep domain knowledge of the documental processed you need to implement, and define root elements for different document lifecycles. In Alfresco you must assign one and only one content type to a given node. This is done at content creation time, and it's not often changed along the content lifecycle. Thus, content types are normally used to identify content items with radically different lifecycles (e.g. cm:document and ws:article), and defining a content type means to extract the basic meta data properties that will be used or useful along the whole document lifecycle.
Aspects
While content types are basically a static vertical classification and enrichment of documents, aspects are their dynamic cousins. As opposed to content types, you can apply or remove aspects dynamically with lesser-to-none destructive consequences to the content nodes. They can or not enrich the document with more metadata, and can be applied to items regardless of their content types. These characteristics make aspects possibly the most flexible feature of the Alfresco content model: you can use them to to mark content or enable/disable operations shared among different content lifecycles (e.g. cm:versionable, rma:filePlanComponent). By nature, aspects are meant to handle cross cutting concepts that occur in several distinct lifecycles or lifecycle steps.
Behaviors
Here we start an overview of how to add logic in your Alfresco solution. Behaviors are automatic computations that are fired by specific triggers, where triggers are defined as a [type/aspect, policy] pair (e.g. [cm:versionable, onCreateNode]). They are in general executed within the same transaction of the event that fires the trigger, there's no guarantee on the order of execution and there's no coordination or orchestration. This makes them perfect for automatic content generation or handling (e.g. creating a thumbnail or updating some metadata) which needs to be integral parts of the content lifecycle, but that are not strictly part of a formalized process.
They're rather accessory or supplementary operations for normal operations or workflows. They require Java coding, thus forming a rather fixed part of your solution. You normally identify and design behaviors right after finishing the content modeling phase and before starting designing the workflows.
Rules
Similar to behaviors, rules are triggered upon specific events, but they're a much more generic and dynamic than them. You can configure rules only on folders, at runtime, and bind them to events that happen within the folder. This makes them ideal to create special buckets within your content repository (e.g. send an email whenever content is added to a specific folder), where side effects happen when you deal with content within it. They're implemented as hidden nodes within folders, thus being integral parts of an export: you can in theory borrow them in different Alfresco implementations, provided the required pieces are available.
They normally are used when a piece of logic applies to content of several different types, but possibly not all the items of the affected types, and only when you can store all the affected content nodes within a sub branch of the repository. Even if such constraint might sound heavy, rules turn out to be quite a handy tool (e.g. generate a thumbnail for all the png documents with mime type image/png in /images).
Actions
Actions are bundled pieces of logic that can be invoked against a node on demand. They're the building blocks for rules, and often used within workflows (e.g. send an email). They are also handy to be directly bound to UI components/buttons, in order to allow the user to be directly exposed to available features of your application. You normally end up developing an action when you need (of want to enable) reusing the same piece of logic in different contextes, such as a workflow, a rule and/or direct user interaction.
Workflows
This is probably the core business of document management: workflows allow you to build a coordinated process that guides users through a defined sequence of steps, basically implementing a human algorithm. Workflows allow you to write custom code, but for the sake of maintainability you probably want to limit such code to the bare minimum of what the workflow itself needs in order to execute, and externalize more complex operations to actions or scripts.
If you're doing document management, the design and implementation of a workflow can start right after content modeling, possibly spawning several other development activities such as accessory actions and scripts, and they're likely to last until you call your code feature complete, and you start fiddling with all the infinite change requests or leftovers on the UI :-)

Categories