Download Code Generation

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Code Generation
Why and how
Why generate code
• Manufacturer’s claims
– Higher productivity in terms of quantity and conformity of code
– Higher flexibility in that the developer is not afraid to repeat the
process several times and is therefore more adventurous
– Achieves better quality due to higher level of abstraction of
specification
– Controlled replication of specification information - I.e. if the code
is required more than once, the fact that the requirements are
tied at a higher level means that the code is correctly replicated
only when necessary.
– Correctness and consistency of generated code
Reality
• Code generated is skeletal only
• Code that is added to generated code can
be ignored or misinterpreted by the
reverse engineering tool
• Code generation, while useful, is still not
advanced enough to be a perfect solution
code generation schemes
• database schema generator
– transforms the Physical Data Design
into Data Definition Language (DDL) for
the target database.
• screen generator
– converts the CASE tool screen
definitions into the target system screen
definition language.
• code generator
– expands high level pseudo-code
statements into more detail
– incorporates definition information from
screens, data items, records etc.
– converts the results into the target
language (e.g. C++, Visual Basic,
Cobol, Java)
Generator incompatibilities
• Generator not integrated with the CASE
design database
–
–
–
–
different vendor
different priorities
different design constructs
run on a different hardware platform
• May need interface software
– to bridge to a different environment
– to convert the CASE output format into the
generator input format
Conceptual model of scheme
• What data entry produces favourable results?
– understand how a code generation scheme can
improve productivity in software construction
– analyse the way that each generator maps CASE
design objects onto generated construction objects.
Use these to assess the extent to which CASE
information is lost or its integrity reduced during the
generation process
– evaluate the code generation scheme in terms of a
range of factors that influence its contribution to
productivity
Conceptual model of scheme
• What do you need to generate?
– draw an architecture diagram to show the main
blocks of processing and stores and flows in the
generation scheme
• What happens when you want to reengineer?
– analyse the strategy used by the generation
scheme to deal with the regeneration issue
• Test it
– perform a pilot development using the scheme, to
identify any problems, and explore the most
effective patterns of use
Project construction plan
• Evaluate project priorities
• maximise productivity
• work within the constraints imposed by the
system architecture and the generation scheme.
• To achieve this, the project manager needs to:
–
–
–
–
assess project priorities
analyse system component dependencies
review partitioning options in the generation scheme
assess the feasibility of incremental regeneration
Steps in Generation for each
increment
• Validate Design against Generation
scheme
• Elaborate design
• Run the generator
• Compile, test and debug the generated
code
• Progressively refine design and
regenerate.
1: Validate Design against
Generation Scheme
• check for information loss and construct
compatibility before starting physical design
– comes from the class editor
• a declaration and inheritance list extracted
from the name of the class and its
inheritance hierarchy
• data members, generated from the
associations, aggregations and attributes
2: Elaborate Design ready for
Generation
• add pseudocode statements, local
variables etc. to the module pseudocode
• make final modifications to CASE design
objects (e.g. physical data items names,
physical item storage etc)
• set mapping options - I.e. what modules
are compiled together
Step 3: Run the Generator
• provide actual parameters
• - e.g.
–
–
–
–
input object libraries to use,
input objects to generate from,
output library to generate to,
generate only, or generate / compile / link.
Steps 4 and 5.
• 4: Compile, Test and Debug Generated
Code
– The effectiveness of testing depends on the
Traceability of the code generator
– - I.e.
• What line in my design generated this error?
• How can I change it?
• 5: Progressively Refine Design and
Regenerate
Generating code in Rose
• Code generation (also called forward engineering) is the
process of generating Java source from one or more
classes in a Rose model.
• Forward engineering in Rose is component-centered.
– This means that the Java source generation is based on the
component specification rather than on the class specification.
– To do this,
• you create a class and then
• assign it to a valid Java component.
– Or, Rose creates the component for you when your model’s
default notation is Java.
Result
• When you forward engineer a Java model
element, its characteristics are mapped to a
corresponding Java-language construct.
– a Rose class forward-engineers, through its
component, to a .java file;
– a Rose package forward-engineers to a Java
package, and so on.
– when you forward engineer a package, a .java file is
generated for each component belonging to the
package.
– Each .java file contains the definitions for any classes
assigned to that component.
• Auto-synchronization mode:
– automatically initiates code generation any time you
create or modify any Java element in your model.
Default is off.
– Because Auto Synchronization is normally off, Rose
generates RoseIDs for Java methods. This feature
allows Rose to track method name changes in the
code. When Auto Synchronization is turned on,
Generate Rose ID should be turned off (on the Code
Generation tab of the Project Specification).
RoseID
The RoseID is a Java comment that takes the form:
@roseuid <string>
E.g.
public class HelloWorldApp {
public HelloWorldApp() {}
/**
@roseuid 364597B40046
*/
public static void main(String[] args) {
To Generate Code
• What to will do before, during, and after
generating code:
– Assign Java Classes to Java Components in Your
Model
– Check Syntax (optional)
– Check the Classpath
– Set the Project Properties that affect Code Generation
(optional)
– Backup Your Source
– Generate Java Source Code from Your Model
– View (browse) and Extend the Generated Source
Steps taken
• I devised a new package in the Logical view.
• I populated the package with classes, giving all attributes
and operations data types and parameters.
• I made all entity classes persistent.
• In the component view, I created a new package.
• I dragged the package from the logical view onto the
package in the Component view.
• I returned to the Logical View, opened a class diagram,
dragged the classes from the logical view into the
diagram and added associations. (If there were
generalizations, I nested the classes).
• I selected and right clicked each class in the diagram
and generated code.
Practical generation
• Generating SQL
• Generating Java Code
Generating tables from classes
• Converting classes to tables. Remember:
– You must define the database in your
component view (see below).
– You can only generate tables from
PERSISTENT classes (see below).
– To generate tables, there must be a defined
schema (see below).
– The schema must be associated with a
database in the component view (see below).
In the component view:
• Set up a database (Right click on logical
view, choose data modeler, new,
database).
• Open the specification for the database
and associate it with whichever
implementation route suits (e.g. SQL
Server 7)
In the logical view:
•
•
•
•
Classify the classes, using a 3-tier system
Set up a new Schema
Transform the objects into Data
Generate (and optionally execute) SQL
(a) Classify the classes
• (To do this, tick the
‘Three-tier diagram’
box in the tools options menu in
Rational Rose.)
• Move all persistent
classes into one
package.
For each persistent class:
– Open the standard specification
– Select the ‘detail’ tab
– Turn on the ‘persistent’ radio button.
– If you have not already given the attributes
data types, do so now.
(b) Set up a new Schema
• (Right click on logical
view, choose data
modeler, new,
schema.)
• Open the schema
specification.
• Associate it with the
database you have
created.
(c)
Transform the objects to data.
• Right click on the
package that holds the
classes in the Logical
view.
• Choose data modeler
• Choose ‘Transform to
data model’
• Fill in destination schema
and target database that
you have set up. Execute
the transformation.
Data Model
• To see your tables, expand the schema.
– If they aren’t there, maybe you didn’t make
them persistent?
• To see your data model, right click on the
schema, choose data modeller, new, data
model diagram
Sample data model diagram
T_Expert
Expert name : INT
Expertise : INT
Contact details : INT
T_Expert_ID : INT
T_Claim_ID : INT
PK_T_Expert13()
FK_T_Expert6()
TC_T_Expert301()
T_Accident
Accidentdatetime : SMALLINT
AccidentLocation : VARCHAR(255)
AccidentDescription : VARCHAR(255)
BusRegistration : VARCHAR(255)
status : CHAR(1)
T_Accident_ID : INT
T_Claimant
Claimant name : INT
Claimant address : INT
DateOfBirth : INT
T_Claimant_ID : INT
PK_T_Accident10()
0..*
<<Non-Identifying>>
<<Non-Identifying>>
PK_T_Claimant8()
1
<<Non-Identifying>>
1
0..*
0..1
T_Expert Report
eport date : INT
eport content : INT
ate requested : INT
_Expert Report_ID : INT
K_T_Expert Report7()
T_Assessor
Username : INT
Password : INT
T_Assessor_ID : INT
PK_T_Assessor12()
T_Claim
claim reported date : INT
claim state : INT
claim type : INT
T_Claim_ID : INT
T_Claimant_ID : INT
T_Accident_ID : INT
PK_T_Claim9()
FK_T_Claim7()
FK_T_Claim4()
TC_T_Claim303()
TC_T_Claim297()
1..*
T_Payment
Payee : INT
Payment amount : INT
<<Non-Identifying>>
Payment status : INT
Payment reason : INT
Authoriser : INT
1
0..* Issuer : INT
T_Payment_ID : INT
T_Claim_ID : INT
PK_T_Payment11()
FK_T_Payment5()
TC_T_Payment299()
(d) Generate (and optionally
execute) SQL.
• Right click on the schema; choose data
modeller, forward engineer…
• This results in your tables being generated into
your database.
• The example below shows new tables created
as part of the ‘Generated Claims’ database.
– Note: You can only create tables in databases of
which you are the owner or have create table access.
Generating to my laptop
Results in SQL Server browser
Generating Java Code
• Before commencing code
generation, it is advisable to
have packaged your classes.
• The example shown below is
from a class that is part of a
package called ‘OM_Claim’.
• In the class diagram window,
choose a class and open its
specification.
• Type in ‘This is my
documentation for <substitute
your own class name>’ Click
on the attributes tab.
Accident
Cl
Accident date/time ...
: Integer
claim report
Accident location : ...
Integer
claim state :
Accident description
... : Integer
claim type :
Bus registration : Integer
...1
0..*
Report Accident()
Cerify Accident()
GetStatus()
getDetails()
UpdateStatu
Report Claim
Assess Claim
0.
Expert Report
Report date : Integer
Report content : Integer
...
Date requested : Integer
...
Request Report()
Submit Report()
ReportSubmittedYN()
...
Assessor
Username : Integer
Password : Integer
0
E
Expert na
Expertise
Contact d
Register
Expert by
Specifying the attributes
•
Right click in the
attributes table and
choose ‘Specification’.
• Give the attributes the
correct type, initial value
and export control. Click
OK to return to the class
specification window.
• Repeat this for all
attributes, ending on the
class specification
window.
Specifying the operations
• Click the Operations tab.
• Select one of the
operations, right click and
select ‘Specification’.
• You are now ready to
generate the Java code
for this class. Click the
class.
• The documentation for
this class is now
displayed in the
‘Documentation’ panel.
• In the Tools menu,
select Java / J2EE and
Generate Code for the
selected class.
• (You may get a warning
that not all units are
loaded. This is only
significant for a
completed project.).
• Code generation for this
yields errors (see next
slide).
Initial code generation errors
• :10:44:57| Starting Code Generation
10:44:57| WARNING: Class Logical View::OM_claim::Accident the name of attribute Accident date/time is not a valid Java
identifier.
10:44:57| ERROR: Class Logical View::OM_claim::Accident - a
name which is a valid Java identifier cannot be constructed for
attribute Accident date/time
10:45:16| Starting Code Generation
10:45:16| WARNING: Class Logical View::OM_claim::Accident the name of attribute Accident date/time is not a valid Java
identifier.
10:45:16| ERROR: Class Logical View::OM_claim::Accident - a
name which is a valid Java identifier cannot be constructed for
attribute Accident date/time
• Note, these are errors due to an incompatibility between the given
names and the Java language.
– i.e. you cannot call a field “Accident date / time”.
Error handling
•
•
•
•
•
•
Return to the class diagram and fix the
problems.
Generate again. This dialogue is
displayed:
Insert a new classpath as shown on
the next slide
Returning to the Classpaths dialogue,
click on the component and click
‘Assign’.
The component then disappears from
the RHS of the screen.
When the code generation is
complete, hopefully you will get
‘Code generation completed
successfully’
The following code has been
generated into the folder:
C:\Contents\Rational
Rose\Claims\JavaCode\OM_claim
//Source file: C:\\Contents\\Rational
Rose\\Claims\\JavaCode\\OM_claim\\Accide
nt.java
package OM_claim;
/**
* This is documentation for the Accident class
*/
public class Accident
{
private Date Accidentdatetime = 01012004;
private String AccidentLocation = None;
private String AccidentDescription = None;
private String BusRegistration = 00 D 00000;
public Claim theClaim[];
public Boolean ReportAccident()
{
return null;
}
/**
* @return Boolean
* @roseuid 418A4EE5020F
*/
public Boolean CerifyAccident()
{
return null;
}
/**
* @return String
* @roseuid 418A4EE90124
*/
public String GetStatus()
{
return null;
}
/**
* @roseuid 418F4FF20390
*/
public Accident()
{
}
/**
* @return Boolean
* @roseuid 418A4EDF0242
*/
}