Contribute Inspectors
From PATSWiki
Inspector Overview Composite Inspectors
Note that "checks" or "tests" in Ramses are called "inspectors" in the future, to avoid confusions.
A check is a piece of code that tests some properties of the model created by the user. This can be very easy properties - for example if a name corresponds to a certain convention. But checks can also test more complicated things.
We decided to have an extensible approach for the checks, so that everybody can add new checks simply by adding a new plug-in that contributes to the extension point for checks.
| Table of contents |
Scope of an Inspector
A check works on exactly one element type. This can be a state machine, a class, or any other element of UML 2.0. In addition, checks can run on IRamsesProjects to check properties of an entire project. Therefore, the first decision you have to make:
- On which element does my check run?
Start of Inspectors
Currently checks are started manually by the user by starting the "Inspect All" action on a model element. In this case, the selected element and all its contained elements are checked. As inspectors can run for quite a while, they are running in a thread that has a low priority, so that the user can proceed with editing.
In addition, you can contribute an extra action in the context menu for an element and start an inspector manually. This may be beneficial for inspectors that take a long time to conclude and need only be invoked at some time by the users.
Results
We decided to have three different verdicts for the checks:
- OK - everything is fine, and there is nothing to say
- Warning - something smells wrong. A warning should indicate situations where it is likely that the user specified something without intension.
- Error - something is wrong for sure, usually because the user did something stupid.
The border between "Error" and "Warning" is not so clear. The Java Tooling in Eclipse even allows you to decide for each property if it should be shown as an error or warning. Generally we can say that a warning may be ignored, but the system will still run, while an error most proprably result in failures. Redundant elements that can simply be ignored and cause no harm are usually worth mentioning in a warning.
Additional results of an inspector can be
- ABORTED - some of the assumptions about the element were not met and the inspector aborts. Example: An inspector checking the type of a signal in a trigger may abort if the signal is a proxy and cannot be read. Another inspector will report anyways that the signal is a proxy, so this inspector simply aborts.
In principle, the code in your inspector must be safe and not throw any exception as inspectors should run silently in the background. If nevertheless something unexpected happens and the inspector throws an exception, it will be assigned the value
- FAILED (which is not a real result). In consequence, it will be disabled by the framework and an error message will be presented to the user. This is a sign that you must improve the inspector.
Diagnose
- If the result is Error' or Warning you must provide a message to the user explaining what is wrong in a short sentence.
- Optionally, you can explain an error or a warning with some more description.
- You can suggest some actions to perform to correct a situation
Writing the Inspector
Extend the abstract class "no.ntnu.item.ramses.inspector.Inspector". It defines a method "analyse" that you must overwrite. This method receives the element to inspect. You can cast this element then to the type that the checks works on - later you will register the test in the plug-in so that it receives only this type of element.
What follows then is completely up to you and your test. Simply return your verdict depending on the properties of the element.
import org.eclipse.uml2.StateMachine;
public class ErrorsInJavaCode extends Inspector {
public IResult analyse(Object element) {
StateMachine stateMachine = (StateMachine) element;
...
// we found an error
return Result.createError("The Java code of the state machine contains errors.");
...
// or everything is fine
return IResult.OK;
}
}
Declaring the Extension Point
Define an extension point "no.ntnu.item.ramses.core.check" in the plugin.xml of your plug-in project. Define a category to which your test belongs.
<extension id="inspectors" point="no.ntnu.item.ramses.inspector.inspector">
<category id="javacode" name="Java Action Code"/>
<inspector category = "javacode"
class="no.ntnu.item.ramses.checks.actionfile.internal.ConditionalSignalSending"
objectClass="org.eclipse.uml2.Activity"
name="Conditional Signal Sending"/>
</extension>
- class is the fully qualified name of your class implementing the test. Note that this class must implement IInspector (or extend the abstract class "Inspector", which is recommended).
- object class gives the fully qualified name of the Java class or interface that is the object checked by the test. Typically this is one of the interfaces dedfined in the UML2 repository.
- name should be a descriptive name of the check
- stereotype can optionally specify the full qualified name of a stereotype that must be applied on the (UML) element for the inspector to apply.
Starting your Test
- Start the runtime workbench with your plug-in enabled.
- Look at Window | Preferences | Ramses Core | Model Inspectors if your test is installed.
- Start validation from the context view of the model outline
Efficiency Considerations
The efficiency of an inspector, that means how many resources (time, memory) it needs to come up with a result, is important. We assume that models are correct to a large extend, that means that results other than 'OK' are relatively seldom. For this reason, we should optimize for this case. This means that an inspector should try to give an OK as fast as possible. The code in case of a warning or error is not so critical. In this code we can compute messages and explanations, find quick assistants or all the elements part of the problem.
Context Help
It is recommenrded to add a context help entry for each inspector, which is shown in the Diagnose View.
Add the following extension in the plugin.xml of the plug-in containing the inspector:
<extension point="org.eclipse.help.contexts">
<contexts
file="infopops.xml"
plugin="no.ntnu.item.ramses.checks.actionfiles">
</contexts>
</extension>
Add a file 'infopops.xml' to the plugin:
<?xml version="1.0" encoding="UTF-8"?>
<contexts>
<context id="MissingSignalClass">
<description>Text to the inspector.</description>
<topic href="http://www.item.ntnu.no/lab/pats/wiki/index.php/Missing_Signal_Class" label="Wiki Page for this Inspector"/>
</context>
</contexts>
This file should contain an entry for each inspector of the plug-in. The id-attribute of the context element must have the value of the simple name of the class implementing the inspector. (The Eclipse help system adds the plugin name given in the extension point as prefix. In the example, the Diagnose View requests the context id no.ntnu.item.ramses.checks.actionfiles.MissingSignalClass.)
Troubleshooting
If your inspector does not get executed check the following potential reasons:
- stereotypes must be declared as fully qualified names, like ramses::executable
