Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Generation and Handcoding
Page 2
Not everything shall and can be generated
• Code is fine, when model would not be more abstract
How to integrate hand written code with generated code
• General principles
• How they apply in DEX
hand
written code
Parameterized
generator
Generator script/template
Map: concept
code
API
generated code
+ included parts
components
components
components
API
model
Predefined
Predefined
Predefined
runtime system
Environment: hardware, GUI, frameworks
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Goals of Handcoding
Page 3
The goal of handcoding
• extend domain model
• add functionality to generated code
• customize generated code
Benefits of handcoding
• Normally re-generation is not needed
• Reuse of existing handwritten code
• Tooling (e.g. editor) for the programming language can be used
DEX supports extensions for
• domain model with attributes and method bodies
• domain model with signatures
• generated GUI code
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Handwritten Code
Page 4
Handcoding (HC) = the process of writing code manually (by hand)
vs. generating code (GC), where the code comes from the generator.
Important questions to decide:
• Artefacts of interest for users?
• What to write, what to read and understand
• Generating and handcoding in which order?
• Repeatable generation?
• Dependences between the forms of code?
• Methodical alignment
• Which knowledge is necessary for
• the developer
• the generating tool
• the compiler, linker and Java virtual machine
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Mixing of HC and Generation in Artifacts
Page 5
Scenario A:
• 1. Let the generator produce code frames in files
• 2. Add code manually, e.g. method implementations
Advantage:
• HC is well integrated inside GC
Disadvantage:
• “One shot” generation only
• Model becomes irrelevant because useless after generation,
• Changes in models impossible
• Doesn’t support evolution
Decision:
• Strict separation of handcoding and generation on artifacts!
• Each artifact (= file) is either handcoded or generated.
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Mixing of HC and Generation in Artifacts -2
Page 6
Scenario B:
• 1. Let the generator produce code frames in files
• Generate explicit markers to protect regions of HC
• 2. Add code manually in protected regions
Advantage:
• Easy to use and easy to identify where to handcode
Necessary:
• Extraction of HC for inclusion in next generation step
Disadvantages:
• Not robust e.g. against editing
• Vulnerable against advanced tools (e.g. beautifiers)
• No clean full generation possible
• Generated code needs to be version controlled
public class Person {
public String getFullname () {
/* [protected GEN#XwgHEge23qp (method getFullname)] */
// to be handcoded
/* [/protected GEN#XwgHEge23qp] */
} }
Java
«gen»
«hc»
«gen»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Separation of HC and GC in Artifacts
Page 7
Each artifact (file) is either HC or GC.
Advantages:
• Only sources (HC and models) need to be versioned
• this greatly reduces conflicts
• and helps understanding progress from the version control logs
• Developers normally don’t read generated code
• just understand the interfaces
• Clean & regenerate always works
Necessary:
• HC needs to be written and integrated
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Alternatives for Integration of HC
Page 8
1. Reference it from the model.
• Ch. 2 for attributes &
• DEX would allow method signatures & bodies in a CD, but that
pollutes the CD (not recommended)
2. Compiler: no that doesn’t work
• We would need “partial classes”, not provided by Java
3. When starting at runtime
• 3a) Write your own main()-function and call HC to configure GC
• that is fine and actually used by many frameworks
• 3b) write static-code pieces: no, because classes are loaded lazy in
Java (and thus static code may be never called)
4. Config file
• Works, but is error prone because it looses type safety.
5. Generator identifies HC and integrates references to it
• HC to follow naming conventions to be identified
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Overview of Product with HC
Page 9
Generated DEX product has this architecture
• HC internal architecture is out of generators control:
• But it is recommended to maintain the architecture
GUI
hand
coded
generated
RTE
standard
components
hand
coded
generated
RTE
standard
components
hand
coded
generated
RTE
standard
components
Application Core
Persistence
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Generator detects HC, the Principle:
Page 10
Approaches DEX uses: (Placeholder X)
1. Extending signature and implementation of domain class X.java
• When XSIG.java exists inherit it in X.java
• When XEIMP.java exists use it in the factory
(assuming it is a subclass of XIMP)
2. Specific Hot Spots documented in the generator handbook.
Extending signature, implementation and hot spots
• is based on naming conventions (e.g. XSIG, XEIMP)
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.1. Extension of Generated Code
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Generated Artifacts in DEX
Page 12
What DEX does:
One class is mapped to
• an interface
• an implementation, and
• a factory for object creation
CD SocNet
class Group extends Profile
{ // …
String purpose;
}
«interface»
Group
+ String getPurpose();
+ void setPurpose(String s)
GroupImpl
Java
…
…
- String purpose;
+ String getPurpose();
+ void setPurpose(String s)
«gen»
GroupFactory
+static Group create()
#Group doCreate()
…
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Extending the Implementation
Page 13
… and adapting generated functionality
by defining HC class XEIMP that inherits GC
«gen»
«interface»
Group
«gen»
«gen»
GroupFactory
Product-CD
+static Group create()
#Group doCreate()
…
GroupImpl
«gen»
handcoded Java class
«hc»
GroupEIMP
import GroupEIMP; …
class GroupFactory …
protected Group doCreate() {
return new GroupEIMP();
}
Generator adapts only the GroupFactory
• now GroupEIMP objects are created
Necessary:
• GroupEIMP is subclass of GroupImpl
• “EIMP” was chosen to prevent occasional use
• “EIMP” = extended implementation
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
adapted Factory
How to add handcoded Java classes
Page 14
Two steps are required to add handcoded Java classes in DEX
• 1. Create handcoded Java class GroupEIMP
• 2. Implement the full and the empty constructor of GroupImpl
Java
public class GroupEIMP extends GroupImpl {
public GroupEIMP() {
super();
}
«hc»
attributes of
class GroupImpl
protected GroupEIMP(String profileName,
boolean isOpen,
Date created,
String purpose) {
super(profileName, isOpen, created, purpose);
}
}
• (3. Override methods and add attributes/methods …)
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to add attributes to the domain model
Page 15
The domain model can be extended by adding attributes
Java
public class GroupEIMP extends GroupImpl {
«hc»
private String newAttribute = "My String";
// ...
}
new domain
model attribute
Properties of these attributes
• not visible in the GUI
• not saved in the database
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to add Methods
Page 16
Application functionality can be extended by adding new methods
• This brings the “meat” to the application
Java
public class GroupEIMP extends GroupImpl {
// ...
public String groupOverview (){
return "Group Overview: " + getPurpose()
+ " " + getHeadcount();
}
}
Limitations
• New methods do not appear in the signature of the
Group interface
«hc»
new method
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to implement derived Attributes
Page 17
Derived attribute does have an empty default
implementation as get/retrieve-method
Add meaning to the derived attribute
using HC by overriding the getter
public class GroupEIMP extends GroupImpl {
// ...
@Override
public int getHeadcount() {
return sizeMembers()+ sizeOrganizers();
}
}
Every generated method can be overwritten
• Incl. ordinary get/setters for attributes
• Association methods
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
DEX Example for Derived Attributes
Page 18
derived attributes are shown in the gui
Model-CD
Group
/int headcount;
…
Java
«hc»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Overwriting Generated Methods
Page 19
Generated methods can be adapted by HC
Java
Model-CD
Group
boolean isOpen
Date created
String purpose
/int headcount
overrride
«hc»
public class GroupEIMP extends GroupImpl {
//constructors ...
public void setPurpose(String pname) {
StatusBar.write("Group "+profileName
+" new purpose "+pname)
super.setPurpose(pname);
}
}
Log result is shown in the bottom line on the GUI
Logging
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Extending the Implementation
Page 20
Advantages:
• relatively little effort to adapt implementation
• adaptable reuse of generated implementation
• smooth integration of HC artefact
Product-CD
«gen»
«interface»
Group
«gen»
Restriction:
• Only one subclass supported
GroupImpl
«hc»
GroupEIMP
Disadvantages:
• IDEs don’t assist when superclass hasn’t been generated yet
• = many false errors are reported after fresh checkout or a clean
• some risk of unwanted occasional detection of “*EIMP”
• re-generation necessary after EIMP-class is created (or deleted)
to get adapted factory
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.2. Extending Data Model Signature
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Extending the Signature of a Class
Page 22
by defining HC interface XSIG that inherits to GC
Product-CD
«hc»
public interface GroupSIG {
String getFullname();
}
«interface»
GroupSIG
«gen»
1. Generator detects XSIG.java
2. Generated code is adapted to implement
the new interface
3. Generator also expects XEIMP.java,
because XImpl is now abstract
«interface»
Group
«gen»
GroupImpl
«hc»
GroupEIMP
Signature extensions (methods) are inherited
to interface X.java and handcoded in XEIMP.java
“Sandwich”-Principle for extension
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
How to add signature extensions
Page 23
Required steps
• 1. Add handwritten Java interface XSIG
• 2. Add handwritten Java class XEIMP
• 3. Implement new methods in XEIMP
Product-CD
«hc»
«interface»
GroupSIG
handwritten
Java interface
Java
«gen»
public interface Group extends dex.socnet.GroupSIG {
//...
}
public abstract class GroupImpl implements dex.socnet.Group
{
//...
}
«gen»
«interface»
Group
«gen»
GroupImpl
«hc»
GroupEIMP
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Mapping Model Inheritance and HC Extension
Page 24
Inheritance and implementation relation is preserved
DEIMP inherits CEIMP indirectly
through DImpl
Model-CD
interface A;
interface B;
class C implements A;
class D extends C implements B;
«interface»
ASIG
«interface»
CSIG
«interface»
A
«interface»
C
«interface»
BSIG
«interface»
DSIG
«interface»
B
«interface»
D
Product-CD
«gen»
«abstract»
CImpl
CEIMP
«abstract»
DImpl
DEIMP
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Signature Extensions Summary
Page 25
Advantages
• Separation of generated and handwritten artifacts
• Signature extensions in HC interfaces
• Supports redefinition of generated functionality
• Supports implementation of internally available methods and
attributes
Disadvantages/problems
• Signature of methods need to be repeated at implementation
• Re-generation is necessary when SIG/EIMP-class is added or
removed
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.3. Hot Spots for the DEX GUI
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Hot Spot
Page 27
A hot spot is a place in the generated code that is planned for
adaptation by handwritten code.
The adaptation is carried out through the generator detecting and
including appropriate HC.
Hot spot documentation needs:
• A) How does a hot spot look like
• e.g. naming conventions for the class
• B) Signature the hot spot has to provide
• C) What is the API the hot spot can use
The approach is similar to framework hot spots.
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Hot Spots in DEX
Page 28
Often the GUI of a DEX product needs adaptation
• More functions, more screens, nicer appearance, …
• GUI can be customized by adding handwritten extensions
DEX has e.g. hot spots prepared for
• Menu Extension
• Home Screen Adaptation
• Panel Extensions
• Startup and TearDown Phases
Adapting a hot spot needs some knowledge about the mechanisms
of the adapted GUI.
Examples of DEX SocNet adaptations:
• see DEX website: http://www.monticore.de/dex/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Hot Spot: Menu Extension
Page 29
Purpose: Add menu items
Hot spot class: MainWindowViewEIMP
Methods to override:
• extendMenu()
Available API:
• addMenuItem(), …
public class MainWindowViewEIMP extends MainWindowView {
//constructors
public void extendMenu() {
JideMenu m = new JideMenu("StatusBar");
JMenuItem item = new JMenuItem("print");
m.add(item);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
StatusBar.write("Menue item print was clicked");
}});
addMenuItem(m);
}
}
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Java
«hc»
How to Adapt the Home Screen
Page 30
Purpose: Customize home screen
Hot spot class: MainWindowPresenterEIMP
Methods to override:
• setHomeTitle()
Available API (see code):
• Swing
public class MainWindowPresenterEIMP extends MainWindowPresenter {
//constructors
public JPanel setHomeTitle() {
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel lblSystem = new JLabel("SocNet System");
lblSystem.setHorizontalTextPosition(SwingConstants.CENTER);
lblSystem.setHorizontalAlignment(SwingConstants.CENTER);
lblSystem.setFont(new Font("Tahoma", Font.PLAIN, 40));
panel.setLayout(new BorderLayout(0, 0));
panel.add(lblSystem, BorderLayout.CENTER);
return panel;
}
}
Java
«hc»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Adapting Panels
Page 31
Purpose: Customize Panel for Specific Domain Class “X”
Hot spot class: XEditPanelViewEIMP
Methods to override:
• getXPanelComponent()
Available API (see code):
• Swing
• Reusable: Methods from XEditPanelView
TagEditPanelView
Product-CD
«gen»
«interface»
ITagEditPanelView
«gen»
TagEditPanelView
«hc»
TagEditPanelViewEIMP
public class TagEditPanelViewEIMP extends TagEditPanelView {
//constructors
public ITagPanelComponentView getTagPanelComponent() {
//...
} }
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
StartUp & TearDown
Page 32
Purpose: Add startup and teardown actions
or takeover control completely
Hot spot class: XControllerEIMP (for model X.cd)
Methods to override:
• startUp()
• tearDown()
Available API (see code):
• Reusable: Methods from AbstractController
public class SocNetControllerEIMP extends SocNetController{
//constructors
protected void startUp() {
//... some startUp actions
}
protected void tearDown() {
//... some tearDown actions
}
}
Java
«hc»
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Summary – Lessons learned
Page 33
Hot spots are HC classes that replace generated classes
• and at the same time inherit their functionality for reuse
Hot spots can be used for various purposes:
• Signature extension
• Method overwriting
• Functionality extension
Hot spots allow to inject HC into a generated system, thus adapting
it for specific needs
Hot spots are filled during the generation process
• and identified through naming conventions
Hot spots are usually model-specific
Farbe!
Generative
Software
Engineering
3. Integrating Handwritten Code
3.4. More Adaptation Mechanisms
Prof. Dr. Bernhard Rumpe
Software Engineering
RWTH Aachen University
http://www.se-rwth.de/
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Class Overriding
Page 35
The principle:
• When X.java exists in handcoded form
just use it and generate nothing
Required:
• HC Java can be distinguished from GC
• e.g. disjoint directories for HC and GC
Advantage:
• Anything can easily be adapted
Disadvantage:
• X.java: nothing is generated anymore; no reuse
• Brittle: adaptations of model need to be tracked manually in HC
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Class Overriding plus Prototypes
Page 36
The principle:
• When X.java exists in handcoded form
use it, but generate XProto.java instead
• Xproto.java can be used as superclass for HC X.Java
Advantage:
• Anything can easily be adapted
• Reuse of generated code possible, which is still there
Disadvantage:
• Brittle: adaptations of model need to be tracked manually in HC
Remark: very similar to the Dex approach using EIMPL
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Use GUI as Framework
Page 37
The principle:
• The generated code may be adaptable by classic programming
techniques, e.g. usable as framework
Required:
• Explicit hot spots (= empty methods) that can be overwritten in
subclasses
• Possibilities to adapt / configure in the generated code
Advantage:
• Traditional form of adaptation, no interaction with generator
Disadvantage:
• Generated code needs to be a framework
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Delegation to HC
Page 38
The principle:
• The generated code uses delegation to hot spots
Similar to the used inheritance approach
Advantage:
• More flexible, e.g. individual delegators for each method
Disadvantage:
• More complex: more objects to manage,
• Objects have substructure
Product-CD
Model-CD
Person
Person
«gen»
delegate
«gen»
«interface»
PersonDelegate
String getFullName()
String getFullName()
String getFullName()
delegator
«hc»
PersonImpl
Delegation
delegate
String getFullName()
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Partial Classes
Page 39
The principle:
• The language allows classes to be distributed over several
artefacts, called “partial classes”
Advantage:
• Generation of classes piecewise is possible
Disadvantage:
• Java doesn’t support this (It can be mimicked by a design pattern)
• Generated functionality cannot be redefined
«gen»
partial class Person{
string firstName;
//…
}
Model-CD
Person
String firstName
C#
classes
have the
same names
String getFullName()
«hc»
partial class Person{
public string getFullname(){
//…
} }
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Aspect Orientation for HC-Injection
Page 40
The principle:
• Use an Aspect-Oriented Language
• Add functionality in form of Aspects
Disadvantage:
• From SE point of view aspects are harmful. Not recommended to
use an AOP language for coding. (Much worse than goto)
Java
public class Person { «gen»
//… generated impl
AspectJ
«hc»
public aspect PersonAspect {
pointcut pcClearMembers(Person p):
execution(* Person.
clearMembers()) && target(p);
public void
clearMembers() {
//… default impl
}
void around(Person p):
pcClearMembers (p) {
// … handwritten impl
}
}
}
p = instance
on which
method shall
be executed
Handwritten
impl. in
advice
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Embed Action Language in Model
Page 41
The principle:
• Embed a language for method implementation within the
modelling language
Advantage:
• We get completely rid of handcoding!
Disadvantage:
• Large model: confusing?
• IDEs are less elaborated for such kind of programming
Examples:
• MontiCore (DEX) provides possibilities to add methods and
method bodies, e.g. in Java and python-style
• UML has its own action language defined
Prof. Dr. B. Rumpe
Lehrstuhl für
Software Engineering
RWTH Aachen
Model Refers to Actions
Page 42
The principle:
• Add references to the implementations in the model
Variants:
• 1) GC calls the referenced HC: like delegation
• 2) Generator weaves the referenced artefact into the GC
Disadvantage:
• Model gets polluted
• Model contains references to artefacts that should be developed
after the model unnecessary
• IDEs are less elaborated for such kind of programming
• For 2: Checking of syntactical correctness is deferred to the
compiler (and thus too late)