Model-based Software Engineering (02341, Spring 2017)
Code snippets (week 2)
Ecore model from T01 3
Generated Code // All comments and imports deleted! package dk.dtu.compute.mbse.petrinet; Interface only (separate interface from implementation)! public interface Petrinet extends EObject { String getname(); void setname(string value); Interface with infrastructure for all (generated objects) EList<Node> getnodes(); EList<Arc> getarcs(); } 4
Generated Code // All comments and imports deleted! package dk.dtu.compute.mbse.petrinet; public interface Petrinet extends EObject { String getname(); void setname(string value); EList<Node> getnodes(); Getters and setters for all features with multiplicty up to 1 NB: Only getters for features with multiplicity greater 1 (no setters) EList<Arc> getarcs(); } 5
Implementation Classes Details of Implementation classes not relevant as of now 6
Factory Interface/Class // All comments and imports deleted package dk.dtu.compute.mbse.petrinet; public interface PetrinetFactory extends EFactory { PetrinetFactory einstance = dk.dtu.compute.mbse.petrinet.impl.petrinetfactoryimpl.init(); Petrinet createpetrinet();... and Package Place createplace(); Token createtoken(); PetrinetPackage getpetrinetpackage(); } 7
Package Interface/Class package dk.dtu.compute.mbse.petrinet; public interface PetrinetPackage extends EPackage { String ename = "petrinet"; String ens_uri = "http://mbse.compute.dtu.dk/petrinet"; String ens_prefix = "pn"; and Package PetrinetPackage einstance = dk.dtu.compute.mbse.petrinet.impl.petrinetpackageimpl.init(); int PETRINET = 0; int PETRINET NAME = 0; int PETRINET NODES = 1; int PETRINET ARCS = 2; int PETRINET_FEATURE_COUNT = 3; 8
Package Interface/Class... EClass getpetrinet(); EAttribute getpetrinet_name(); EReference getpetrinet_nodes(); EReference getpetrinet_arcs(); EClass getnode(); and Package... EReference getplace_tokens(); } 9
Enabledness and Firing a Transition t remove add Transition t enabled: for ALL incoming Arcs a: for ONE source Place p of Arc a: find and reserve a token Fire Transition t: for ALL incoming Arcs a: for ONE source Place p of Arc a: find and remove a token for ALL outgoing arcs a: for ONE target Place p of Arc a: add a new Token 10
Loops Code for checking enabledness of a transition static private boolean isenabled(transition transition){ } for (int i = 0; i < transition.getin().size(); i++) { Arc arc = transition.getin().get(i); Place place = (Place) arc.getsource(); if (place.gettokens().isempty()) { return false; } } return true; 11
Loops: Flaws Not defensive: transition could be null arc.getsource()might be not be of type Place Wrong from of for loop (iterating over index) introduces unnecessary artifacts (variable i) invites index problems (in particular i nest loops) Less efficient 12
Loops Better code for checking enabledness of a transition static private boolean isenabled(transition transition){ if (transition!= null) { for (Arc arc : transition.getin()) { Node node = arc.getsource(); if (node instanceof Place) { Place place = (Place) node; if (place.gettokens().isempty()) { return false; } } } } return true; } 13
Problem: Double arcs t Requires two tokens on the place: one for each arc remove add 14
Loops Compute all needed tokens in a mapping first: Map<Place,Integer> needed = new HashMap<Place,Integer>(); for (Arc arc: transition.getin()) { Node node = arc.getsource(); if (node instanceof Place) { Place source = (Place) node; needed.put(source, needed.getordefault(source, 0) + 1); } } Works for Java8 only Count the number of tokens needed for each place 15
Creating new objects?! Token token = new Token(); or Token token = new TokenImpl(); does not work for creating a new token! 16
Use the generated Factory One of the EMF generated classes! Singleton (only instance available) Token token = PetrinetFactory.eINSTANCE.createToken(); Reasons for using factories: Separate implementation from interface Factory is in control of creating appropriate instances 17
In constructor of CompoundCommand... this.append( new RemoveCommand( domain, place, PetrinetPackage.eINSTANCE.getPlace_Tokens(), token);... Token token = PetrinetFactory.eINSTANCE.createToken(); this.append( new CreateChildCommand( domain, place, PetrinetPackage.eINSTANCE.getPlace_Tokens(), token, null)); 18