sesam developers tutorial – würzburg february 2003 1 sesam spring symposium sesam developers...
TRANSCRIPT
SeSAm developers tutorial – Würzburg February 2003 1
SeSAm Spring SymposiumSeSAm Developers Tutorial
Rainer Herrler, University of Würzburg
SeSAm developers tutorial – Würzburg February 2003 2
Overview
• Prerequisites and aims of this tutorial• Steps to load SeSAm into your Workspace• General things about plugins
– Classification of Plugins– Integration of Plugins
• Examples of Plugin Development
– Example 1: Primitive ATan2– Example 2: Type 3Dimensional Point– Example 3: Focus Feature– Example 4: Simple entry in the Menubar– Example 5: The Focus Finder– Example 6: Panel for FocusFeature
• Tipps and Tricks
SeSAm developers tutorial – Würzburg February 2003 3
Prerequisites and aims of the Developer-Tutorial
• We presume you have:– Modeling experience in SeSAm
– JAVA-Knowledge
• Afterwards you should have: – Knowledge about important Interfaces
– Competence to develop plugins
– Ability to program addional features
SeSAm developers tutorial – Würzburg February 2003 4
Getting SeSAm into your workspace
• Start Eclipse– Free Java-IDE (www.eclipse-org)– Other Java-IDE‘s are also possible but the description below has
to be adapted– Install „CVS SSL Plugin“ (http://home.arcor.de/rolf_wilms/)
• Select „File – Import – Team Project Set“ and open „sesam.psf“– Ask for lastest „sesam.psf“– It contains a description about the basic CVS-Server-data the
required projects
• Enter your user-name and password– We will create a repository account on request– Afterwards the necessary projects are gooing to be downloaded
automatically.
• Run SeSAm– SeSAm Application/de.uniwue.ki.gui.mas.application.SeSAm.java
SeSAm developers tutorial – Würzburg February 2003 5
SeSAm Project Dependencies
JUnit
Various Utils Various GUI Utils
Info6Utils Info6GUIUtils SeSAm Graph Library (MCGE)
SeSAm
SeSAm XML SeSAm Model PrintSeSAm GUI
SeSAm Application
User Interface Layer
Kernel
Utilities Layer
SeSAm developers tutorial – Würzburg February 2003 6
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
SeSAm developers tutorial – Würzburg February 2003 7
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
• Definition:• Defines new Functions or Actions for an Agent
• Existing Examples: • GetFirst(Iterator<T>)• Print(String)
• Typical indicators for application:• Appclicable function/action by all agents• Independent of the agents state• Very generic time-consuming User Function
• New thinkable example:• Mathematical Function „atan“• ….
SeSAm developers tutorial – Würzburg February 2003 8
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
• Definition:• Defines new data types
• Existing Examples: • Specific Types (Boolean, String, Image,..)• Generic Types (List, Number,..)
• Typical indicators for application:• Data type is needed by hardcoded primitives• Data type cannot be represented by any primitive type
• New thinkable examples:• 3dimensional Position• DataBaseConnection
SeSAm developers tutorial – Würzburg February 2003 9
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
• Definition:• Defines a new feature for an agent• Features provide states and functions for agent
• Existing Examples: • Spatial Info, Evolution• Database Feature
• Typical indicators for application:• Functions are dependent of the agents state• Feature cannot be realized by a user feature
• New thinkable example:• 3-dimensional spatial info• ….
SeSAm developers tutorial – Würzburg February 2003 10
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
• Definition:• Defines an entry in the plugins menu• An action can be assigned to the entry
• opening a window• changing the model
• Existing Examples: • Model print (html)• Protegé
• Typical indicators for application:• Export and Import purposes• Configuration of Features
• New thinkable example:• Java Code Generation from the model
SeSAm developers tutorial – Würzburg February 2003 11
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
• Definition:• Specialized panels for certain types of declarations
• Existing Examples: • Spatial Info• Spatial Map
• Typical indicators for application:• A feature class needs to be configured
• New thinkable examples:• Scheduling feature showing a time table• ….
SeSAm developers tutorial – Würzburg February 2003 12
Kinds of Plugins and Examples
o Additíonal Primitive
o New Data Type
o Feature Plugin
o Menu Entries
o Declaration Panels
o Context-Menue
• Definition:• Context Actions on certain declarations
• Existing Examples: • Find References • Inline Method
• Typical indicators for application:• Refactorings• …
• New thinkable examples:• Extract Superclass (for User Types)• Move User Function to Feature…
SeSAm developers tutorial – Würzburg February 2003 13
How to add Plugins…
• …to a SeSAm Installation (Deployment)– Create a plugin.ini
– Bundle plugin.ini and needed .class-files to a single jar
– Put it to ../SeSAm/pulgins
– Start SeSAm
• …when running SeSAm from eclipse (Development)– Create plugin.ini
– Put it to ../SeSAm Application/plugins/
– Extend Classpath of Run-Configuration with plugin projects
SeSAm developers tutorial – Würzburg February 2003 14
Where do I find the „ini“-Files in eclipse
• Locations– Active Ini-Files are stored in
„plugins“
– Inactive Ini-Files are stored in „pluginsOff“
• To add a plugin do the following:– create „plugins“
– move your desired plugins
SeSAm developers tutorial – Würzburg February 2003 15
Example „spatialPlugin.ini“-File
<plugin> <featureSection> <feature className="de.uniwue.ki.mas.basics.feature.spatial.SpatialMapFeatureClassDeclaration" singletonMethodName="getInstance"/> <feature className="de.uniwue.ki.mas.basics.feature.spatial.SpatialInfoFeatureClassDeclaration" singletonMethodName="getInstance"/> </featureSection>
<objectActionSection> <objectAction
className="de.uniwue.ki.gui.mas.basics.feature.spatial.SpatialMapObjectFeatureInstDeclPanelActionFactory"/> <objectAction className="de.uniwue.ki.gui.mas.basics.feature.spatial.SpatialMapObjectFeaturePanelAndActionFactory"/> <objectAction className="de.uniwue.ki.gui.mas.basics.feature.spatial.WriteableHasSpatialInfoDeclPanelActionFactory"/> </objectActionSection> <typeSection> <type className="de.uniwue.ki.mas.basics.feature.spatial.SpatialInfoType" singletonMethodName="getInstance" variableType="true"
argumentDeclarationEditorClass="de.uniwue.ki.gui.mas.basics.feature.spatial.SpatialInfoTypeArgumentEditorPanel"/> <type className="de.uniwue.ki.mas.basics.feature.spatial.position.Position2DType" singletonMethodName="getInstance" variableType="true"
argumentDeclarationEditorClass="de.uniwue.ki.gui.mas.basics.feature.spatial.Position2DArgumentDeclarationEditor"/> </typeSection></plugin>
SeSAm developers tutorial – Würzburg February 2003 16
The found plugins are loaded at startup…
SeSAm developers tutorial – Würzburg February 2003 17
Example One: Programming Mathematical Functions
syntax: atan2(x, y)
where: x - x coordinate of the point. x - y coordinate of the point.
return: number - an implementation-dependent approximation to the arc tangent of the quotient, y/x, of the arguments y and x, where thesigns of the arguments are used to determine the quadrant of theresult.=atan(y/x)
description: It is intentional and traditional for the two-argument arc tangentfunction that the argument named y be first and the argument namedx be second. The return value is expressed in radians and rangesfrom -pi to +pi.
Suppose we want to add a new primitive “atan2” with arguments x and y, that is defined like this:
SeSAm developers tutorial – Würzburg February 2003 18
Steps to realize this function
1. Create the Function– Describes effects of the function (semantics)– Important at runtime– Function must implement IFunction
2. Create a FunctionDeclaration– Describes input and output of a function (syntax)– Important at modelling time– FunctionDeclaration must implemet IFunctionDeclaration
• Stategy for beginners:– Look for a similar Function (same or similar output and input
parameters)– Copy and modify this FunctionDeclaration and Function
SeSAm developers tutorial – Würzburg February 2003 19
Choose abstract superclass for Function Atan2
– Choose superclass accoring to the return value• void AbstractFunctionAction• boolean AbstractBooleanFunction• int AbstractIntegerFunction• double AbstractDoubleFunction
– Otherwise choose• AbstractFunction - If the return value is definitly not one of the above• AbstractFunctionDynamic – If the return value might be one of the above, but it is uncertain
which one
SeSAm developers tutorial – Würzburg February 2003 20
Creating the Function
public class FunctionATan2 extends AbstractDoubleFunction { private final IFunction argument1; private final IFunction argument2; public FunctionATan2(IFunction arg1, IFunction arg2) { super(); argument1 = arg1; argument2 = arg2; } public double executeForDouble(IExecuteFunctionArgs executeFunctionArgs) throws SimulationRuntimeException {
double x = ((Double)argument1.execute(executeFunctionArgs)).doubleValue();double y = ((Double)argument2.execute(executeFunctionArgs)).doubleValue();return Math.atan2(x,y);
}
}
SeSAm developers tutorial – Würzburg February 2003 21
Backgroundknowledge about Function
• What happens when?– constructor is called when simulation run is created
(compilation from the model declarations)– execute() is called at runtime
• Notify that there might be constant Functions– RandomInteger(1,10) is not constant– +(10,20) is constant– +(10,GetVariable(myVar)) is not constant
• What are ExecuteFunctionArgs ? – Contain a reference to the world– Reference to the active agent
SeSAm developers tutorial – Würzburg February 2003 22
Choose abstract superclass for FunctionsDeclaration Atan2 - Examples
• SetVariable• DoWith
• +• Not
• Append• Or
SeSAm developers tutorial – Würzburg February 2003 23
Choose abstract superclass for FunctionsDeclaration Atan2 - Rules
– Classify your FunctionDeclaration• specific if all output and input parameters are specified
• generic if at least one output- or input- parameter has to be specified by the modeler
– If „specific“ classify subtype• Args if a fixed number of input types can be given
• UnlimitedArgs if any number of input parameters of one specific type can be given
SeSAm developers tutorial – Würzburg February 2003 24
FunctionDeclaration Atan2
public final class FunctionDeclarationATan2 extends AbstractSpecificFunctionArgsDeclaration {
public FunctionDeclarationATan2() {super(
"atan2",DoubleType.getInstance(),CollectionsHelper.createList(
DoubleType.getInstance(),DoubleType.getInstance()),
false);setDocumentation(
"This calculates the value atan2(x,y)");}
...}
SeSAm developers tutorial – Würzburg February 2003 25
FunctionDeclaration Atan2
public IFunction createFunction(ICreateFunctionArgs createFunctionArgs, IFunctionList functions) {
if (Assert.ASSERTION_ON)Assert.assertEquals(2, functions.size());
return new FunctionATan2((IFunction) functions.get(0),(IFunction) functions.get(1));
}
• We still have compile-errors because we haven’t implemented the abstract function createFunction(..)
SeSAm developers tutorial – Würzburg February 2003 26
Create „Atan2Plugin.ini“
<plugin> <!--This ini-File has to be placed in the SeSAm/plugins-Directory and the according classes have to be in the classpath-> <functionSection> <function className="sesam.math.FunctionDeclarationATan2"/> </functionSection> <!--The following sections are not used in the example <typeSection> </typeSection> <featureSection> </featureSection> <objectViewerSection> </objectViewerSection> <menuPluginSection> </menuPluginSection> --></plugin>
SeSAm developers tutorial – Würzburg February 2003 27
Add plugin projects to the classpath
SeSAm developers tutorial – Würzburg February 2003 28
And now we have the new function available
SeSAm developers tutorial – Würzburg February 2003 29
Example Two: Three-dimensional position and functions
• And now we want to – Create a new type with a plugin– Create functions for this type
• Steps– Defining a class to represent the types value– Declaring an according SeSAm Type (ISpecificType)– Defining two functions operating on that type.
SeSAm developers tutorial – Würzburg February 2003 30
Defining the representing class for
a threedimensional point
package sesam.threedim;public class Position3D {
public Position3D(int x,int y,int z) {this.x=x;this.y=y;this.z=z;
}
public double distanceTo(Position3D pos) {return Math.sqrt(Math.pow(Math.sqrt(Math.pow
(Math.abs(x-pos.x),2)+ Math.pow(Math.abs(y-pos.y),2)),2)+
Math.pow(Math.abs(z-pos.z),2));}
public int x;public int y;public int z;
}
SeSAm developers tutorial – Würzburg February 2003 31
Choose abstract superclass for Type Position3D
• List<T>• Number
• Position2D• String
SeSAm developers tutorial – Würzburg February 2003 32
Declaring a SeSAm type
public class Position3DType extends AbstractSpecificType implements ISpecificType {private final static Position3DType _instance = new Position3DType();
public Position3DType() {super();ObjectType.getInstance().addSubType(this);}
public static Position3DType getInstance() {return _instance;}
public boolean equals(Object obj) {return (obj instanceof Position3DType);}
public boolean isArgumentDeclarationValueOk(Object value) {return ((value == null) || (value instanceof Position3D)); }
public String getName() {return "Position3D"; }
}
SeSAm developers tutorial – Würzburg February 2003 33
Creating 3DPlugin.ini
<position3d> <typeSection> <type className="sesam.threedim.Position3DType"/> </typeSection></position3d >
SeSAm developers tutorial – Würzburg February 2003 34
Next step would be … defining Functions and FunctionDeclarations
• Type is known in SeSAm but at the moment:– values cannot be created, and
– no existing function could deal with the values.
• Two possibilities for creation:– Defining argument editors
– Defining constructor primitives
• Signatures of possible primitives:– Position3D CreatePosition3D(IntegerType x, IntegerType y,
IntegerType z)
– DoubleType Distance3D(Position3D pos1, Position3D pos2)
• Creating functions is analogous to Example 1
SeSAm developers tutorial – Würzburg February 2003 35
Example 3. Programming a SeSAm builtin Feature
• Focus-Feature Description– Select one single SimObject (Ressource or Agent) as target
– Referencing the target and retargeting shall be possible
• Provided Methods– SimObject GetFocusObject()
– Void FocusObject(SimObject)
• Provided Variables– No Variables used in this example
• Internal State– Stores a SimObject
– Is not accessible from outside
SeSAm developers tutorial – Würzburg February 2003 36
1
n
n
1
FeatureDeclarations according to the different levels of agent declarations
AgentClassDeclaration
AgentInstanceDeclaration
Agent (at Runtime)
1
1
n
n
FeatureClassDeclaration
ObjectFeatureClassDeclaration
ObjectFeatureInstanceClassDecl.
ObjectFeature
1
n
SeSAm developers tutorial – Würzburg February 2003 37
FeatureDeclaration..
public final class FocusFeatureClassDeclaration extends AbstractFeaturePlusAllDeclaration {private static final FocusFeatureClassDeclaration _instance = new FocusFeatureClassDeclaration();private IFunctionDeclarationList _functionDeclarationList;
private FocusFeatureClassDeclaration() {super("Focus");
}
public static final FocusFeatureClassDeclaration getInstance() {return _instance;
}
public IObjectFeature createObjectFeature(IObjectCreateFunctionArgs createObjectFunctionArgs) {
return new FocusObjectFeature();}
public Iterator getFunctionDeclarations() {if (_functionDeclarationList == null) {
_functionDeclarationList = new FunctionDeclarationList();_functionDeclarationList.add(new FocusObjectFunctionDeclaration());_functionDeclarationList.add(new GetFocusObjectFunctionDeclaration());
}return _functionDeclarationList.iterator();
}public Iterator getVariableClassDeclarations() {
return CollectionsHelper.EMPTY_ITERATOR;}
SeSAm developers tutorial – Würzburg February 2003 38
ObjectFeature.. holds the state at runtime
final class FocusObjectFeature extends AbstractObjectFeature {private IObject _focusedObject;public FocusObjectFeature() {
super();}public void remove() {
setObject(null);super.remove();
}public void reset(IExecuteFunctionArgs executeFunctionArgs)
throws SimulationRuntimeException {setObject(null);
}public final String getName() {
return "focus " + ((getObject() == null) ? null : getObject().getName());}void setFocusedObject(IObject object) {
_focusedObject = object;}IObject getFocusedObject() {
return _focusedObject;}
}
SeSAm developers tutorial – Würzburg February 2003 39
Example Feature Function…
final class GetFocusObjectFunctionAction extends AbstractFunction {private GetFocusObjectFunctionAction() {
super();}
public Object execute(IExecuteFunctionArgs executeFunctionArgs) throws SimulationRuntimeException {
IObject activeAgent = ((IAgentExecuteFunctionArgs)executeFunctionArgs).getObject();
FocusObjectFeature feature = (FocusObjectFeature)activeAgent.getObjectFeature(FocusObjectFeature.class);
return feature.getFocusedObject();}
public String getName() {return "Focused Body";
}}
•Analogous you can create the action SetFocusedObject(SimObject)
SeSAm developers tutorial – Würzburg February 2003 40
FocusPlugin.ini and the effect
<focus> <featureSection> <feature className=“...FocusFeatureClassDeclaration" singletonMethodName="getInstance"/> </featureSection></focus>
SeSAm developers tutorial – Würzburg February 2003 41
Example 4: New simple menu-entry
public class MenuPlugin extends AbstractSeSAmMenuPlugin {public void initMenuItem(JMenuItem item) {
item.setText("Where are you?");}
public void doit() {System.out.println("Hello here I am!");
}
}
<plugin>
<menuPluginSection>
<className>....MenuPlugin</className>
</menuPluginSection>
</plugin>
SeSAm developers tutorial – Würzburg February 2003 42
Watching the effect
SeSAm developers tutorial – Würzburg February 2003 43
Example 5: FocusFinder
• And now we want to – Create derive information from the model– Find and show all agents equipped with the focus feature
• Steps– Defining a menu entry– Searching in the model representation– Opening a window
SeSAm developers tutorial – Würzburg February 2003 44
-FrameFactory-figMapper-seSAmDeclaration
GUISeSAMDeclaration
-seSAmModelDeclaration-experimentListAndFactory-seSAmDeclarationTreeModel
SeSAmDeclaration1 1 -agentClassDeclarationListAndFactory
-ressourceClassDeclarationListAndFactory-seSAmModelBasicsDeclaration-simulationElementsDeclaration-worldClassDeclarationListAndFactory
SeSAmModelDeclaration
1 1
SeSAmModelBasicsDeclaration
1
1
AgentClassDeclarationListAndFactory
1
1
AgentClassDeclarationList
11 1 1
AgentClassDeclarationFactory
UserFeatureClassDeclarationListAndFactory
UserFunctionClassDeclarationListAndFactory
UserTypeDeclarationListAndFactory
1
1
1
1
1
1
The root of the model representation
SeSAm developers tutorial – Würzburg February 2003 45
Similarities to the model tree help understanding the structure….
-FrameFactory-figMapper-seSAmDeclaration
GUISeSAMDeclaration
-seSAmModelDeclaration-experimentListAndFactory-seSAmDeclarationTreeModel
SeSAmDeclaration1 1 -agentClassDeclarationListAndFactory
-ressourceClassDeclarationListAndFactory-seSAmModelBasicsDeclaration-simulationElementsDeclaration-worldClassDeclarationListAndFactory
SeSAmModelDeclaration
1 1
SeSAmModelBasicsDeclaration
1
1
AgentClassDeclarationListAndFactory
1
1
AgentClassDeclarationList
11 1 1
AgentClassDeclarationFactory
UserFeatureClassDeclarationListAndFactory
UserFunctionClassDeclarationListAndFactory
UserTypeDeclarationListAndFactory
1
1
1
1
1
1
SeSAm developers tutorial – Würzburg February 2003 46
FocusFinder code….
public class FocusFinder extends AbstractSeSAmMenuPlugin {public void initMenuItem(JMenuItem item) {
item.setText("FocusFinder");}public void doit() {
AgentClassDeclarationList agentList = getGUISeSAmDeclaration() .getSeSAmDeclaration()
.getSeSAmModelDeclaration() .getAgentClassDeclarationListAndFactory()
.getAgentClassDeclarationList();
JPanel panel = new JPanel();
Iterator it = agentList.iterator();while (it.hasNext()) {
IAgentClassDeclaration agent = (IAgentClassDeclaration) it.next();if (agent.getObjectFeatureClassDeclarationList().contains(
FocusFeatureClassDeclaration.getInstance())) {panel.add(new JButton(agent.getName()));
}}
openWindow(panel, "FocusFinder");}
}
SeSAm developers tutorial – Würzburg February 2003 47
Example 6: Focus Panel at Runtime
• And now we want to – Show the Featues state at runtime– Add a new GUI-Element to SeSAm
• Steps– Defining a Renderer Panel for the FocusObjectFeature– Defining a IObjectPanelFactory to generate the
Renderer Panel– Wrapping this into a IObjectPanelActionFactory
SeSAm developers tutorial – Würzburg February 2003 48
Step 1. Defining a Renderer Panel
class FocusFeatureRenderer extends JDisposeablePanel implements ChangeListener {
final JLabel label = new JLabel();final FocusObjectFeature feature;
FocusFeatureRenderer(FocusObjectFeature feature) {this.feature = feature;stateChanged(null);add(label);feature.addChangeListener(this);
}public void stateChanged(ChangeEvent e) {
if (feature.getFocusedObject() != null)label.setText(feature.getFocusedObject().getName());
elselabel.setText("nothing in focus");
}}
SeSAm developers tutorial – Würzburg February 2003 49
Step 2. Defining the Panel Factory
class FocusFeaturePanelFactory implements IObjectPanelFactory {public JDisposeablePanel createObjectPanel(Object anObject) {
return new FocusFeatureRenderer((FocusObjectFeature) anObject);}public String getObjectTitle(Object anObject) {
return "Focus";}
}
SeSAm developers tutorial – Würzburg February 2003 50
Wrapping PanelFactory in PanelActionFactory
public class FocusFeaturePanelAndActionFactory extends AbstractActionFactory implements IObjectPanelAndActionFactory {public IObjectPanelFactory getPanelFactory(Container parent, Object anDeclaration) {
return new FocusFeaturePanelFactory();}
public FocusFeaturePanelAndActionFactory(IGUISeSAmDeclaration guiSDecl) {super(guiSDecl);
}
public boolean getCanProduceActions(Container parent, Object anObject) {return (anObject instanceof FocusObjectFeature);
}/* Kontextmenü */public Iterator getImportantActions(Container parent, Object anObject) {
return null;}public Iterator getMoreActions(Container parent, Object anObject) {
return null;}public AbstractBoundAction getPropertyAction(Container parent, Object anObject) {
return null;}
}
SeSAm developers tutorial – Würzburg February 2003 51
SeSAm Programming Tipps
• Use Inspect to find classes– Inspect in the context-menu on any declaration
– Inspect also available on Panels (if switched on)
• If a required class is not public, there is usually a Interface– Name convention: Interfaces start with „I“
• Use Assertions– Assertions help to identify inconsitencies– Set breakpoint in Assert.fail()
• Strategy to repair corrupt models– Switch Assertion off, repair, save, switch Assertions on– Load with breakpoint in fail(), look at stack trace, edit model in
texteditor.
SeSAm developers tutorial – Würzburg February 2003 52
Freely guided tutorial, next points…
• SeSAm XML File format– Castor
– Format described by XML-Shema