AWACS is written in Java, using the Play! framework. A few notes on Play! based applications:
- Java files are compiled on the fly — you can edit and change files without starting/stopping or recompiling the application.
- The "app" directory of the application or its modules contains executed code.
- Modules are basically miniature Play! applications which can be transparently grafted into a another application: they can have their own 'app', 'lib', etc and those paths are simply searched after the main application's paths when loading files.
A few notes on the dashboard application:
- The app uses its database to store WidgetInstances which are a specific configurations of a Widget
- A Dashboard is a collection of WidgetInstances, arranged in columns, optionally with parameters specific to that dashboard (stored as an Assignment).
- Bundles of widgets are packaged as Play! modules so that company-specific widgets are kept separate from distributed widgets.
- The main app has a few "raw" widgets builtin for rendering HTML or Images.
- A Widget is Java class which implements the Widget interface, contained within a package in the widgets package of the application or an added module.
- A Widget can include CSS and JS files in its package directory, to be linked in the
<head>
of any pages which include an instance of it. - A Widget controls rendering of its HTML and can setup AJAX/JSON end-points to do server-side processing.
Use your package manager or see Play! documentation for more up-to-date examples, but as of writing, this was one option:
curl -O "http://download.playframework.org/releases/play-1.0.3.1.zip"
unzip play-1.0.3.1.zip
sudo cp -r play-1.0.3.1 /usr/local/play
rm play-1.0.3.1.zip
echo "export PATH=\$PATH:/usr/local/play" >> ~/.profile
source ~/.profile
play
http://localhost:9000/widgets
displays a gallery of installed widgets as well configured instances, along with links to the sandbox to play with them.
Appending ?repair=all
to gallery will delete orphaned instances who's providing widget code is no longer available.
Appending ?rescan=all
to the gallery will freshen the widget cache.
Checkout widget module(s) and add to the application. For example:
cd ~/dashboard
git clone <path-to-awacs-widgets-local>
echo "module.awacs-widgets-local=`pwd`/awacs-widgets-local" >> awacs/conf/application.conf
mkdir sandbox && cd sandbox
/path/to/awacs/examples/widget.sh
cp -r <package> <widget bundle>/app/widgets/<package>
When developing a widget, a simple action is available to render a specific widget for testing without needing to create a WidgetInstance or add it to a Dashboard:
http://localhost:9000/sandbox/{className}/{configString}
-
Rendering HTML
When rendering a widget, the dashboard will call the
render
method of the widget to generate HTML.BaseWidget
's implementation will search first for a .html file with the same name as the widget class, then forwidget.html
, in the widget's package. In the example widgetmywidget.MyClass
andmywidget.SomeClass
will both render frommywidget/widget.html
whilemywidget.OtherClass
with render frommywidget/OtherClass.html
-
JS and CSS resources
The dashboard will check every widget on a given dashboard for
behavior.js
andstyles.css
before rendering a dashboard. If found, these are linked in the<head>
tag, and are served using/styles/<WidgetPackageName>.css
and/scripts/<WidgetPackageName>.js
. In the example widget/styles/mywidget.css
and/scripts/mywidget.js
. -
AJAX callbacks
The method
endpoint(endpointName, params)
of a widget is invoked by the dashboard to reply to requests made to/endpoint/<widgetPackage>.<WidgetClass>/<endpointName>
. TheObject
it returns is rendered to the client as JSON usingGson().toJson()
. In the example, an a request to/endpoint/mywidget.MyClass/getDataPoints
which would result in a call tomywidget.MyClass("getDataPoints", params)
. See the Play! docs for details on theparams
argument, but it exposes request parameters. -
Available Javascript Methods:
Dashboard.register(somethingToRun)
: Drop this in a widget's HTML, and somethingToRun'sstart()
method will be called after everything has loaded. The Dashboard will start widgets gradually to maintain performance.Dashboard.warn(message)
: displays message to the user briefly (i.e. an ajax call timed out).Dashboard.fatal(message)
: displays message and reloads the dashboard. Use this only when recovery from an error is not likely (i.e. malformed JSON indicates potential version change).
app/
widgets/
mywidget/
behavior.js
MyClass.java
OtherClass.html
OtherClass.java
SomeClass.java
styles.css
widget.html
myOtherWidget/
OtherWidget.java
widget.html