Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Creating a new Disease Model Plug-in
Contents
- 1 See the NEW model generator Tool !!
- 2 Prerequisites
- 3 Create a New Project for Your Plug-in
- 4 Creating the Required Packages
- 5 Defining your Disease Model Interface
- 6 Adding Required Dependencies to Your Plug-in MANIFEST
- 7 Generating the EMF Model
- 8 Using the EMF Model to Generate Model Code
- 9 Customizing the Disease Model Implementation Class (your code goes here!!)
- 10 Editing the Autogenerated genmodel file
- 11 Using EMF to Generate the Rest of the Required Code
- 12 Final Configuration of plugin.xml
- 13 Plugging in Your Plug-In
- 14 Providing custom parameters for your disease model
- 15 Implementing your new disease model
See the NEW model generator Tool !!
- You no longer need to follow the steps on this page to create a new model. Please see instead the NEW model generator Tool !!
The page is perhaps interesting as it shows how one would (used to) create a plugin manually.
- We have now made it easier to automatically generate a new disease or population model pluging.
- See the STEM Model Generator page for the new easy to follow instructions.
- See the STEM_Model_Generator/Install page for instruction on how to install the new model generator.
Prerequisites
You must first have your development environment set up and have the STEM sourcecode installed and running. Make sure you have the latest version of EMF installed.
Create a New Project for Your Plug-in
> File>new>other>Eclipse Modeling Framework>Empty EMF Project
The NEW EMPTY EMF PROJECT wizard will open
enter
Project Name: org.eclipse.stem.diseasemodels.yourdiseasemodel
click on the project
right click
Figures 1 & 2: Creating an Empty EMF Project
Creating the Required Packages
and create four new packages:
org.eclipse.stem.diseasemodels.yourdiseasemodel
org.eclipse.stem.diseasemodels.yourdiseasemodel.impl
org.eclipse.stem.diseasemodels.yourdiseasemodel.provider
org.eclipse.stem.diseasemodels.yourdiseasemodel.util
Defining your Disease Model Interface
Select the package:
org.eclipse.stem.diseasemodels.yourdiseasemodel
right click, >New > Interface
Edit the Interface so your model extends the appropriate STEM build in Model (e.g., StochasticSEIRDiseaseModel) as
shown below:
import org.eclipse.stem.diseasemodels.standard.StochasticSEIRDiseaseModel;
/**
* This interface is an EMF Model.
*
* @model
*/
public interface YourDiseaseModel extends StochasticSEIRDiseaseModel {
}
NOTE: The Java doc above the interface declaration is required. This is used by the Eclipse Modeling Framework to generate code for your model.
Figure 3: After Creating the Interface your Workspace will appear as shown above. Click twice to see high resolution screenshot.
Adding Required Dependencies to Your Plug-in MANIFEST
Having now created the Interface, you will see errors (see the red indicators in figure 3) indicating that the class extended cannot be resolved.
To fix this, in the Eclipse Package Explorer, open the META-INF folder and double click the
MANIFEST.MF file to open it.
Below the edit window it will probably open, by default, in the OVERVIEW view. Click on the DEPENDENCIES tab.
you will have to add several dependencies.
Click >add
select org.eclipse.core.runtime
Click >add
select org.eclipse.stem.core
Click >add
select org.eclipse.stem.definitions
Click >add
select org.eclipse.emf.ecore
Select > add
select org.eclipse.emf.ecore.edit
Click >add
select org.eclipse.stem.diseasemodels
This last dependency assumes you are extending a build in disease model (almost certainly the case). If you are extending your own existing extension, then you must also add that dependency.
hit <ctrl S> to save your changes
Figure 4: Required Dependencies in Manifest.mf Click twice to see high resolution screenshot.
Generating the EMF Model
Click on your package
right click
select >new>other>Eclipse Modeling Framework>New EMF Generator Model
in the EMF Model wizard, open the folder org.eclipse.stem.diseasemodels.yourdiseasemodel
and select the model subfolder.
under filename type:
yourdiseasemodel.genmodel
click next
select annoted Java
click Finish
Figure 5: Creating the new EMF model
Using the EMF Model to Generate Model Code
Look at the package explorer.
EMF will have generated two files in the model subfolder
yourdiseasemodel.ecore
and
yourdiseasemodel.genmodel
open yourdiseasemodel.genmodel
right click
you will see a tree appear in the editor window
Figure 6: yourdiseasemodel.genmodel shown in the editor window. Click twice to see high resolution screenshot.
select the top node
right click
select Generate Model Code
Note:
You should now see a file plugin.xml below the 'model' folder in the package explorer for your new EMF project.
Close the MANIFEST.MF file and open plugin.xml
note that they now provide the same information for your plugin.
Figure 7: Having generated your model code the plugin.xml file should appear in the project explorer. The generated code is shown in the editor. Click twice to see high resolution screenshot.
Customizing the Disease Model Implementation Class (your code goes here!!)
open the .impl project and edit the file
YourDiseaseModelImpl.java
Edit the class definition so instead of
public class YourDiseaseModelImpl extends EObjectImpl implements YourDiseaseModel {
have it extend the appropriate STEM built in model. For example,
public class YourDiseaseModelImpl extends StochasticSEIRDiseaseModelImpl implements YourDiseaseModel {
since this is a generated class you must also change constructor the java doc from @generated to @generated NOT
/**
- An implementation of the model object 'Your Disease Model'.
- @generated NOT
- /
change the constructor definition to make it Public (by default EMF makes it Protected).
since this is a generated class you must also change constructor the java doc from @generated to @generated NOT
/**
- @generated NOT
- /
and, if needed, add the import for the STEM built in model. e.g.,
import org.eclipse.stem.diseasemodels.standard.impl.StochasticSEIRDiseaseModelImpl;
Eventually, all of your model code will go in this implementation class by overriding superclass methods such as computeDiseaseDeltas() and/or computeDiseaseDeathDeltas().
Editing the Autogenerated genmodel file
This step ensures that the files we are about to autogenerate will go in the right place.
If it is not already open in your environment, go the the toolbar and select
>Window>show view>Other>General>Properties to open the properties view.
Select the properties view.
Once again, double click on the file yourdiseasemodel.genmodel
The .genmodel tree will appear in the editor and the .genmodel properies will appear in the properties view.
Scroll down to the +Edit section and change the Edit Directory to
/org.eclipse.stem.diseasemodels.yourdiseasemodel/src (removing the .edit from the path)
Scroll down to the +Editor section and change the Editor Directory to
/org.eclipse.stem.ui.diseasemodels.yourdiseasemodel/src (removing the .editor and adding .ui in the path)
Scroll down to the +Tests section and change the Tests Directory to
/org.eclipse.stem.tests.diseasemodels.yourdiseasemodel/src
moving the .tests. from the end of the path to just after .stem.
Using EMF to Generate the Rest of the Required Code
In the model folder double click on yourdiseasemodel.genmodel
click on the top Yourdiseasemodel node in the editor window
right click
select Generate Edit Code
right click
select Generate Editor Code
THE STEP BELOW WERE NOT NEEDED WHEN RECENTLY FOLLOWING THESE INSTRUCTIONS. THE ...EditPlugin CLASS COMPILED OKAY. KEEPING INSTRUCTIONS HERE JUST IN CASE.
Next, Open the file org.eclipse.stem.diseasemodels.yourdiseasemodel.provider.YourDiseaseModelEditPlugin
Eclipse will indicate that the Import
import org.eclipse.stem.definitions.edges.provider.DefinitionsEditPlugin;
"cannot be resolved". Remove it. hit <ctrl S> to save.
Scroll down to the method
YourdiseasemodelEditPlugin()
DefinitionsEditPlugin.INSTANCE,
will show up as "cannot be resolved". Click on DefinitionsEditPlugin, right click, and select
>source>add import to find the import. hit <ctrl S> to save.
The following steps may not be needed - need to double check this.
Go to the file org.eclipse.stem.diseasemodels.yourdiseasemodel.provider.YourDiseaseModelItemProvider
Delete the method public ResourceLocator getResourceLocator()
remove the import import org.eclipse.emf.common.util.ResourceLocator;
The file should now build without errors. The Preceding steps may not be needed - need to double check this.
Final Configuration of plugin.xml
Once again, open plugin.xml file
go to the Runtime tab.
Under Exported Packages click Add
select all of the packages that appear and add them.
save the plugin.xml
On the Right hand side (see figure 8) click the Calculate Uses button.
save the plugin.xml
Figure 8: Configuring the RUNTIME tab in plugin.xml Click twice to see high resolution screenshot.
Next Click on the Extensions tab
Click Add:
add the extension org.eclipse.stem.diseasemodels.diseasemodel
(be careful NOT to select org.eclipse.stem.diseasemodels.disease)
click save
save the plugin.xml
Figure 9: When adding an extension, typing in the Extension Point Filter textbox will narrow the list of features you can select.
Still on the Extensions page click on the extension you just added and
expand it by clicking the (+).
Click on the child node (org.eclipse.stem.diseasemodels.yourdiseasemodel.DiseaseModel1)
On the RHS under Extension Element Details change the class*
to:
org.eclipse.stem.diseasemodels.yourdiseasemodel.impl.YourDiseaseModelImpl
click on the child node (dublin_core)
on the RHS fill in at least the first four entries
Follow the same procedure to Add another extension for org.eclipse.emf.edit.itemProviderAdapterFactories
Click on the extension org.eclipse.emf.edit.itemProviderAdapterFactories
expand it by clicking (+)
click on factory
on the RHS change the uri to
http:///org/eclipse/stem/diseasemodels/yourdiseasemodel.ecore
(note, emf erroneously uses a '.' in the uri. we must be use '/')
IMPORTANT: Be VERY careful to get the URI right here. Observe the three slashes (///). Eclipse uses the URI string in a map to retrieve adapter factories for different purposes, and a typo can be very tricky to debug later. If you are unsure, look at the java class YourDiseaseModelPackage.java and the eNS_URI variable.
under class* change the class to
org.eclipse.stem.diseasemodels.yourdiseasemodel.provider.YourdiseasemodelItemProviderAdapterFactory
Next click on the extension org.eclipse.emf.edit.itemProviderAdapterFactories and move it up until the order of
the extensions, top to bottom, is
- org.eclipse.emf.edit.itemProviderAdapterFactories
- org.eclise.emf.ecore.generated_package
- org.eclipse.stem.dieseasemodels.diseasemodel
THE generated_package EXTENSION WAS MISSING IN A RECENT ATTEMPT TO FOLLOW THESE INSTRUCTIONS. IF IT IS MISSING, MANUALLY ADD IT FOLLOWING THE STEPS ABOVE.
Click on the extension
org.eclipse.emf.ecore.genearted_package
expand it by clicking (+)
click on the child node
on the RHS change the uri* to
"http:///org/eclipse/stem/diseasemodels/yourdiseasemodel.ecore
change the class* to
org.eclipse.stem.diseasemodels.yourdiseasemodel.YourdiseasemodelPackage
make sure the genmodel* is
model/yourdiseasemodel.genmodel
Adding Supported Types
This is done most easily by editing the xml itself.
click on the plugin.xml tab on the bottom of the window. This is an xml view for your
entire plugin.xml configuration.
in the node:
<extension point="org.eclipse.emf.edit.itemProviderAdapterFactories">
change the factory attribute supportedTypes to be:
<factory ... supportedTypes = "org.eclipse.emf.edit.provider.IEditingDomainItemProvider org.eclipse.emf.edit.provider.IStructuredItemContentProvider org.eclipse.emf.edit.provider.ITreeItemContentProvider org.eclipse.emf.edit.provider.IItemLabelProvider org.eclipse.emf.edit.provider.IItemPropertySource"> ... </factory>
Leave all the other attributes under factory unchanged
You should now see a total of three extensions listed.
- org.eclipse.emf.edit.itemProviderAdapterFactories
- org.eclise.emf.ecore.generated_package
- org.eclipse.stem.diseasemodels.diseasemodel
click on the Build tab
under Binary Build select icons by ckecking the check box.
save the plugin.xml
go to the Overview tab again
under General Information
Under Activator click browse and select
org.eclipse.stem.diseasemodels.yourdiseasemodel.provider.YourdiseasemodelEditPlugin$Implementation
set Name: to
%pluginName
set Provider: to
%providerName
click the checkbox to: "Activate this plug-in when one of its classes is loaded"
under Execution Environments (if it is not already there) click add
select J2SE1.5 (or above)
click on the dependencies tab again
order the dependencies top to bottom as follows
- org.eclipse.core.runtime
- org.eclipse.emf.ecore
- org.eclipse.emf.ecore.edit
- org.eclipse.stem.diseasemodel
- org.eclipse.stem.core
- org.eclipse.stem.definitions
- org.eclipse.stem.populationmodels
With the single exception of the org.eclipse.core.runtime dependency, all of these should be Rexported. If they are not (as indicated by a small black arrow), click on each one in turn, click Properties, and then make sure that the checkbox "Re-export this dependency" is selected.
Check the classpath. To do this, open the MANIFEST.MF Tab
If it is missing, under Bundle-Verion: add a line
Bundle-ClassPath: .
make sure the bundle activator line has $Implementation at the end of it.
Bundle-Activator:
org.eclipse.stem.diseasemodels.yourdiseasemodel.provider.YourdiseasemodelEditPlugin$Implementation
Go to the Overview Tab
click on "update classpath settings"
on the RHS select:
Organize the plug-in using "Organize the Manifest Wizard" and configure the wizard as shown in figure 10.
Figure 10: Dialog settings to organize your Manifest.mf Click twice to see high resolution screenshot.
Plugging in Your Plug-In
go to the menu bar
click >run>open run dialog
click on the Plug-ins tab
select (check) your plugin org.eclipse.stem.diseasemodes.yourdiseasemodel
Providing custom parameters for your disease model
You will most likely want to add custom parameters to your disease model. You do this by opening the ecore editor for your new model (yourdiseasemodel.ecore). Select the EMF class representing your new disease model, right click and select "New Child->EAttribute". In the Properties view, specify a name and the EType (e.g. EDouble). Make sure that your new attribute is marked 'editable' in the .genmodel. Next, regenerate the code (open the .genmodel, rightclick and select Generate All
To allow the user to enter values for your new parameter when your disease model is selected from the dropdown provided by the new disease wizard, there are a few steps you need to follow.
First, you need to create the necessary support for national language (NLS) so that the names and descriptions of your parameter are shown on the new disease model wizard. You do this by extending the generated class YourDiseaseModelAdapterFactory and implementing the PropertyStringProviderAdapterFactory as well as the IStartup interface. The easiest way to do this is to copy an existing java class and modify it. For instance, the org.eclipse.stem.ui.diseasemodels.example project has this class:
org.eclipse.stem.ui.diseasemodels.example.presentation.ExamplePropertyStringProviderAdapterFactory
Copy this class to your existing project (IMPORTANT: This is the "editor" project generated by EMF, it has the .ui in the path):
org.eclipse.stem.ui.diseasemodels.yourdiseasemodel.
You can use the package that has already been pre-generated (org.eclipse.stem.ui.diseasemodels.yourdiseasemodel.presentation) or you can create a new (more descriptive) package.
Rename the class to e.g. YourDiseaseModelPropertyStringProviderAdapterFactory
The class won't compile. You need to add a dependency in the plugin.xml to the org.eclipse.stem.ui project. Open the plugin.xml and the Dependencies tab, click Add and select org.eclipse.stem.ui. Also add org.eclipse.stem.ui.diseasemodels to the dependencies.
Next, change the superclass to YourDiseaseModelAdapterFactory. Now change the method "createExampleDiseaseModelAdapter" to "createYourDiseaseModelAdapter" (it MUST override the superclass method)
The class still won't compile, since it needs to be provided a message class that will be used to do the translation of NLS strings for natural language support. You will notice that the class refers to a class ExampleDiseaseWizardMessages. Copy this class from the example disease model project and rename (e.g. to YourDiseaseModelWizardMessages)
Change the BUNDLE_NAME variable in this class to point to a new .properties file that will contain the NLS resources for your new disease model. For instance, set it to:
private static final String BUNDLE_NAME = Constants.ID_ROOT + ".diseasemodels.yourdiseasemodel.presentation.yourdiseasemessages"; //$NON-NLS-1$
Next, create an empty text file yourdiseasemessages.properties in the package (as pointed to by the BUNDLE_NAME).
Now you need to make sure "YourDiseaseModelPropertyStringProviderAdapterFactory" is loaded when the STEM launches. This will register your new string provider (the code in the constructor ensures this) and make it available to do the translation when needed. Open the plugin.xml in your new plugin (the one with .ui in it) and select the Extensions tab. Click "Add..." and enter org.eclipse.ui.startup in the "Extension Point Filter" text box. Pick org.eclipse.ui.startup from the list and then Finish. You'll see the new Extension under in the Extensions tab. Expand org.eclipse.ui.startup and select the (startup) element underneath. On the right side, click Browse and select "YourDiseaseModelPropertyStringProviderAdapterFactory". Save the plugin. If you look at the plugin.xml in a text file, you should see something like:
<extension point="org.eclipse.ui.startup"> <startup class="org.eclipse.stem.ui.diseasemodels.yourdisease.presentation.YourDiseaseModelPropertyStringProviderAdapterFactory"> </startup> </extension>
Now, if you've done everything right and select your new disease model from the STEM New Disease Model wizard dropdown, you will see your new custom attribute displayed and waiting for the user to specify a value. You will also see that the name and the unit strings have exclamation marks (!) around them. This means that an attempt was made to retrieve a translated name and unit (and tooltip) for your attribute but it wasn't found. If your new attribute was named "test", you'll see the strings "!test!", "!testUNIT!" and "!testTT!" (the last one is for the tooltip). This is where you enter those 3 NLS strings in your yourdiseasemessages.properties file, e.g.:
test = Test testUNIT = ms (or whatever the unit is for your new attribute) testTT = Here is a more detailed description shown in the tooltip
Now that you've added the ability for the user to specify values for your new attribute, you also want to validate that such values are valid. To do this, you start by copying (and renaming) 4 files from the example disease model project:
ExampleDiseaseModelAdapter.java (rename to "YourDiseaseModelPropertyEditorAdapter" in your project)
ExampleDiseaseModelPropertyEditor.java (rename to "YourDiseaseModelPropertyEditor" in your project)
ExampleDiseaseModelPropertyEditorAdapterFactory.java (rename to "YourDiseaseModelPropertyEditorAdapterFactory" in your project) ]
ExampleDiseaseModelPropertyEditorAdapter (rename to "YourDiseaseModelPropertyEditorAdapter" in your project)
The files won't compile. Start by editing YourDiseaseModelPropertyEditorAdapterFactory.java and change the superclass so that it is correct (YourDiseaseModelAdapter). Change the "createExampleDiseaseModelAdapter" method to "createYourDiseaseModelAdapter" and make sure it returns a new instance of YourDiseaseModelAdapter.
Next, in "YourDiseaseModelPropertyEditorAdapter", make sure the method "createDiseaseModelPropertyEditor" returns a new instance of "YourDiseaseModelPropertyEditor"
Finally, in YourDiseaseModelPropertyEditor, change the constructor to simply this:
public YourDiseaseModelPropertyEditor(Composite parent, int style, DiseaseModel diseaseModel, ModifyListener projectValidator) { super(parent, style, diseaseModel, projectValidator); }
This will reuse the superclass method for creating the actual widgets needed to enter parameter values for your disease model.
In the populate() method (which is called when it is time to create a new instance of your disease model when the user has finished with the wizard), replace the case statements with the new parameter(s) that are unique for your disease model.
In the validate() method, you add code to validate the values entered by the user for your new disease parameters.
Finally, an important step is needed. In the class YourDiseaseModelEditorPlugin.java, which is a generated class, add a new method in the Implementation inner class that will make sure your new property editor adapter is registered with the factory. This is how the method looks like:
@Override public void start(BundleContext context) throws Exception { super.start(context); new YourDiseaseModelPropertyEditorAdapterFactory(); }
To make sure this method is invoked when the plugin is started, check the plugin.xml and the Overview tab. For activator, YourDiseaseModelEditorPlugin$Implementation should be specified.
Make sure that the two plugins you just created are checked in the run configuration for STEM (org.eclipse.stem.diseasemodels.yourdiseasemodel and org.eclipse.stem.ui.diseasemodels.yourdiseasemodel) and you should be able to create and validate new instances of your disease model, and drag them into your custom models.
Implementing your new disease model
TODO