![]() ![]() |
||||
|
||||
To
use our model statistics collection class we need to do several things:
To
make an Eclipse action we need to create a new class and to extend the plugin.xml file.
The model traversal will be invoked and the model results reported from a method in the new
action class. Of particular importance is reporting the results of the analysis performed by the
plug-in. We have several options for making the results available:
In
this example we will illustrate the first and last options. Section 7 discusses these methods
in
more detail. |
||||
We
must implement an Eclipse action to make our model statistics functionality available to the
user. We do this in two parts:
The
interface IWorkbenchWindowActionDelegate declares methods that allow Eclipse to
manage the lifecycle of the action. In particular, the method run(IAction) is invoked to
actually
execute the action. OSATE provides an abstract class AaxlReadOnlyAction, in package
edu.cmu.sei.osate.ui.actions, that provides default implementations for all the action
methods. The run implementation performs various sanity checks on the currently selected
object and ensures that the necessary Eclipse resources are initialized before delegating to the
abstract method doAaxlAction(AObject), which is passed the selected model object. The
intent is that to implement an action, the programmer needs only to extend
AaxlReadOnlyAction and override the doAaxlAction method. See the Javadoc for more
information.
Class AaxlReadOnlyAction
gets its name from the fact that any changes made to any models
as a side effect of the action will not be saved. This allows actions to make temporary changes
to the model to facilitate analyses. OSATE also provides the abstract class
AaxlModifyAction that is the same as AaxlReadOnlyAction except that it saves any models
modified by the action. Actions implemented as subclasses of either of these classes are
triggered by first selecting a .aaxl file in the resource navigator
or an AADL model element in
an editor window, and then by executing the action by clicking on its icon in an Eclipse toolbar
or by selecting the actions menu item. When an .aaxl file is selected, doAaxlAction
is
passed the root element of the model contained in the file. |
||||
We
define the DoModelStatistics class as a subclass of AaxlReadOnlyAction because it
does not modify the model. Our action is applicable to all AADL model objects. If it is
invoked on a declarative model object then the statistics of all the declarative model objects in
the Eclipse workspace are computed. That is, all the declarative specifications, packages, and
property sets in all the open projects will be analyzed. If the action is invoked on an instance
model object then the statistics of the containing system instance only will be computed.
The
first thing the action does is get the root object of the model containing the object obj
passed to the action using the method AObject.getAObjectRoot(). This method returns an
AadlSpec, SystemInstance, AadlPackage, or PropertySet object depending on
whether
the object is contained in an AADL specification, a system instance model, an AADL package
definition, or an AADL property set definition, respectively. Our action attaches markers to
this object.
The
action next tries to get the SystemInstance, if any, that contains obj using
AObject.getSystemInstance(). When obj comes from an instance model this is the same
object as the models root object. When obj comes from a declarative model, package
declaration, or property set declaration this method returns null. Our use of this method
is
redundant: we could have performed a type test using instanceof on the object referenced by
root. We include it here, however, for pedagogical purposes.
The
action then creates a new ModelStatistics object. If the si is non-null we have
a system
instance so we compute the statistics of the instance model. Otherwise, we use the method
processPreOrderAllDeclarativeModels() to analyze all the AADL specifications, property
set declarations, and package declarations in the workspace. The ModelStatistics object
now contains the counts of the various elements in the model.
As
mentioned above, we report the results using both Eclipse markers and a dialog box. To
create a marker we simply invoke reportInfo(AObject, String). This creates an informative
marker attached to the given model element with the given message. In this case we attach the
results to the root model element. We create one marker for each category of model statistics.
We can also create warning and error markers using the methods reportWarning
and
reportError. Creating and managing markers is further described in Section 8 Persistent
Markers with AADL Models.
Finally,
we report the results in a dialog box. We use the Eclipse convenience method
openInformation(Shell, String, String) in class org.eclipse.jface.dialogs.MessageDialog
to create and display the modal dialog box. The first parameter is the shell to use as the parent
of the dialog box; we get this using the method AaxlReadOnlyAction.getShell(). The
second parameter is the title of the dialog box. The final parameter is the message to display.
In our case, the message is our accumulated list of model statistics results, so we use
msg.toString() to convert the string buffer into a string. In general, you are free to
use SWT
to build any kind of window or dialog box you would like to display the results. A description
of how to do so is beyond the scope of this document. The MessageDialog class provides
many additional convenience methods, e.g., openError, that are suitable for reporting various
kinds of analysis results.
package edu.cmu.sei.osate.statistics;
import org.eclipse.jface.dialogs.MessageDialog;
import edu.cmu.sei.aadl.model.core.AObject;
import edu.cmu.sei.aadl.model.instance.SystemInstance;
import edu.cmu.sei.osate.ui.actions.AaxlReadOnlyAction;
public class DoModelStatistics extends
AaxlReadOnlyAction {
public void doAaxlAction(AObject
obj) {
// Get the root
object of the model
final AObject root
= obj.getAObjectRoot();
// Get the system
instance (if any)
final SystemInstance
si = obj.getSystemInstance();
/* Create a new
model statistics analysis object. Run it over the
* instance
model if it exists. Otherwise, run it over all the
* declarative
models in the workspace.
*/
final ModelStatistics
stats = new ModelStatistics();
if (si != null)
{
stats.processPreOrderAll(si);
} else {
stats.processPreOrderAllDeclarativeModels();
}
/* Accumulate
the results in a StringBuffer, but also report them
* using
info markers attached to the root model object.
*/
final StringBuffer
msg = new StringBuffer();
if (si != null)
{
final
String appStats = stats.getApplicationResult();
final
String epStats = stats.getExecutionPlatformResult();
reportInfo(root,
appStats);
reportInfo(root,
epStats);
msg.append(appStats);
msg.append(epStats);
} else {
final
String modelStats = stats.getModelResult();
final
String flowStats = stats.getFlowResult();
reportInfo(root,
modelStats);
reportInfo(root,
flowStats);
msg.append(modelStats);
msg.append(flowStats);
}
// Also report the
results using a message dialog
MessageDialog.openInformation(
getShell(), "Model Statistics", msg.toString());
}
} |
||||