Intent API - GeoscienceAustralia/earthsci GitHub Wiki
The Intent API is a system for performing actions and passing messages between components. It is modeled on Android's Intent system. The idea is that one component raises an Intent to perform an action or handle a resource, and another component defines a matching intent filter that passes the Intent to a handler to handle the action.
Life cycle of an Intent
- A component wants to perform an action (for example, a file was dragged into a panel and needs to be opened). The component creates a new Intent object and sets the applicable properties on the object (file URI, content type, expected return type, etc).
- The component calls
IntentManager.start()
, passing in the Intent, and a callback object which is notified of the result. - The
IntentManager
iterates through the registered intent filters (registered using theau.gov.ga.earthsci.intent.filters
extension point). If a match is found, the intent filter's handler class is instantiated. Note that this handler instance is injected with the Eclipse context. - The handler
IIntentHandler.handle()
method is called, passing in the intent and the callback. - The handler then must handle the intent, and notify the callback of the result (or if an error occurs). It can perform this handling asynchronously if required (eg show a UI wizard to handle the data).
- The callback object can now handle the result. If the result is of an unexpected type, it should pass it to the
Dispatcher.dispatch()
method, which will find an appropriate handler for the result.
Dispatcher
Sometimes an intent callback will receive an object with a type that it is not expecting. For example, if the user drags a catalog file into the layer panel, a catalog node may be returned instead of a layer. The layer panel's intent callback should then pass the catalog node to the Dispatcher.dispatch()
method (perhaps after prompting the user for confirmation). This will search for a dispatch handler (registered using the au.gov.ga.earthsci.intent.dispatchFilters
extension point) that is associated with the type of the dispatched object. If a handler is found, the IDispatchHandler.handle()
method will be called on the handler, passing in the dispatched object. The handler can then do something appropriate with the object (in this example, it could add the catalog node to the catalog model).
Intent Handlers that require resource retrieval
An abstract IIntentHandler
implementation called the AbstractRetrieveIntentHandler
is provided. If you want to write an intent handler implementation that requires retrieving the resource pointed to by the Intent's URI, a good start would be to extend the AbstractRetrieveIntentHandler
. This class uses the IRetrievalService
to retrieve the resource, and then passes the result to the handle()
method.
XML Intent Filter
The au.gov.ga.earthsci.core
plugin contains an intent filter that matches on any Intents that contain the XML content type (org.eclipse.core.runtime.xml
). This means that any Intent that points to an XML resource will be handled by this filter's handler, the XmlRetrieveIntentHandler
.
XmlRetrieveIntentHandler life cycle:
- A
XmlRetrieveIntentHandler
instance retrieves the intent's resource using the retrieval service, then parses the retrieved XML data into aorg.w3c.dom.Document
instance. - It then passes the document object to the
XmlLoaderManager
. - The
XmlLoaderManager
iterates through its XML loader filters (registered using theau.gov.ga.earthsci.core.xmlLoaders
extension point) until it finds a filter that can load the document. 4. The filter's loader class is instantiated, and then theIXmlLoader.load()
method is called, passing the document and a callback object. This loader is injected with an Eclipse context object. - The loader can now load the XML document to an object, notifying the callback when complete. This loading can happen asynchronously.
- The
XmlRetrieveIntentHandler
passes the result (or error) back to the original Intent callback.
End-to-end example - XML layer definition loading
- User drags an XML layer definition file into the layer panel.
- Layer panel creates an
Intent
containing the file's URI and XML content type. - This Intent is passed to the
IntentManager.start()
method. - IntentManager finds the filter that matches the intent.
- The filter's handler class (in this case the
XmlRetrieveIntentHandler
) is instantiated and injected with the Eclipse context. - The XmlRetrieveIntentHandler retrieves the resource from the Intent's URI and parses the XML to a document.
- The document is passed to the
XmlLoaderManager.load()
method. - XmlLoaderManager finds a loader filter that can load the document.
- The filter's loader class (in this case the
LayerXmlLoader
) is instantiated and injected with the Eclipse context. - The LayerXmlLoader uses a World Wind Layer Factory to create a layer from the document.
- The Layer instance is passed back to the XmlRetrieveIntentHandler's
IXmlLoaderCallback
. - The XmlRetrieveIntentHandler's callback passes the Layer instance back to the layer panel's
IIntentCallback
. - The layer panel's callback adds the Layer to the layer model.