Introduction
Kiyaa was created in the process of building my online accounting software Clarity Accounting, which is currently the best demonstration of this toolkit's usefulness.
The name: "Kiyaa!" is a sound a code ninja can use to focus his ki while crushing bugs with his bare hands.
Template System
Kiyaa templates allow you to define a view using an XHTML+XML file to define the "appearance" of the view, plus a class which provides actions and bindings for that view. These files are theoretically editable by someone who only know XHTML+CSS, but not java.
Features include:
- EL-style binding syntax for Widget/View properties - "#{obj.prop}" for a read/write property or "${obj.prop}" for a read-only property.
- Multi-level asynchronous fetching for properties - ${a.b.c.d} works even if b, c, and d are all Asynchronous properties (getB(AsyncCallback callback).
- Method calls are allowed within EL expressions, and you can omit the get/set/is prefix or empty () at the end if you want to
- Any method that takes an Action will have an action automatically generated if the value is not an EL expression
- Supports onclick, onKeyPress, onEnterPress, onfocus, onblur events on widgets implementing SourcesXXXEvents; pretend they have methods like setOnfocus(Action x)
- You can define multiple serial actions seperated by semicolons, each of which can be asynchronous
- Custom tag libraries can be added as their own XML namespace in a facelets-like manner
- Any widget or view can be inserted using <ui:customView viewClass="com.yourwidgets.Widget"/> tag
Asynchronous Operations
You'll also find some useful AsyncCallback utility classes, including:
- AsyncCallbackProxy - Wraps another callback and allows you to intercept the onSuccess and/or onFailure methods. Useful for implementing asynchronous actions where you want to fetch a result and store it somewhere.
- AsyncCallbackGroup - Provides a series of AsyncCallback instances and calls your provided callback when all of them are complete. Useful for multi-stage operations.
- AsyncCallbackShared - Accumulates a list of AsyncCallback instances and call them all when it is called. Useful for caching, or at least not fetching the same piece of data multiple times in parallel.
- AsyncCallbackWithTimeout - Calls onFailure() after a set period of time, allows you to put a timeout on callbacks. Useful for debugging code that forgets to call the callback, or if you want to use a shorter timeout on RPC calls than the default.
- AsyncCallbackFactory - Used as a central place to create callbacks for actions; you can install your own factory that handles onFailure() to display an error, or adds a timeout for debugging.
- RetryingOperation - Allows you to define an operation that automatically retries if it gets a temporary network error; used with the ServiceRetryingAdapter this can make the application more robust to network issues, redeploys, and also bugs in IE7's SSL implementation.
Shared Localization Classes
Kiyaa includes a class which can use javassist to generate an implementation of your Messages and Constants interfaces for any Locale that uses ResourceBundle and honors the GWT annotations.
This is very handy for sharing some localization class between client or server, or just to take advantage of the convenience and type-safety of the GWT system compared to some more cumbersome alternatives.
Note: It doesn't use UTF-8 properties files like GWT does (yet) - I'd need an implementation of ResourceBundle that supports this - GWT's own implementation is in gwt-dev-XXX.jar, which I don't want a dependency on.
It also includes the LocalizedParser interface and a server and client-side implementation of these to use for formatting numbers and dates for the current locale. This allows shared code to do localization; previously you had to use different classes on the client and server because GWT has its own date and number formatters that don't work on the server.
Caching Classes
It includes a set of classes to help add some client-side caching to your RPC services.
DateJs
There's a wrapper for the DateJs javascript date parser that you can use for flexible date input parsing.
Calendar Widget
There's a calendar implementation you can use based on the code for jscalendar, but re-written. However, it'll still work with their CSS, I think.
Custom Combo Box and Popup
There's a somewhat sophisticated combo box and popup system that allows you to implement rich popups with a table or list of choices inside, some actions, and it with the combo box filters the list as you type, to find what you are looking for.
Generator Baseclass
The templating system uses a Generator and I also abstracted some of the Generator logic into a base class you can use to help create your own generators.
PopupPanel patch
Includes a subclass of PopupPanel that hides itself when focus moves to a widget outside the popup. This means that popups will hide correctly if the user uses keyboard navigation to leave the popup instead of clicking.
EJB Access
This includes a Servlet base class you can subclass to provide your GWT code with access to an EJB (either stateful or stateless). The EJB has to implement the interface you want to call (which must be a subclass of RemoteService), and then the Servlet redirects calls to the EJB instead of calling methods on itself. You implementation provides a method getBean() which returns the EJB that you want to direct method calls to.
Other Utilities
In the com.habitsoft.kiyaa.util package ...
- Tracking class to help submit dynamic events to analytics, currently Google Analytics and Clicky are supported
- ScrollPositionManager is used to save/restore the vertical scroll position when using the History class for navigation (no more AJAX updates going to the wrong part of the screen!)
- HoverStyleHandler helps with adding/removing CSS classes to things when you hover over them - needed for browsers with limited :hover support
- FocusGroup help moving focus between widgets programmatically, in the right order
- Cloner automated deep copies using a generator
- DictionaryConstants a combination of Dictionary and Constants which also allows you to put Serializable objects into the Dictionary - useful for pre-loading data into the host page for fast loading, skinning, or runtime (instead of compile-time) localization
Support
If you post to the Google Group I created for the project I'll get an email and answer you at my own leisure. Who knows, one day there may be a little community of people to answer your questions in that group.
Example Application
I've just released a new open source project that uses this code - a live log and stats viewer for glassfish (or similar app-servers). Find it here: glassfish-dashboard