1 / 59

Code Generation

Code Generation. SuperSet Code Generation. Template Definition. A pattern or gauge, such as a thin metal plate with a cut pattern, used as a guide in making something accurately, as in woodworking or the carving of architectural profiles (the free Online Dictionary). Text Template.

reegan
Télécharger la présentation

Code Generation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Code Generation SuperSet Code Generation

  2. Template Definition A pattern or gauge, such as a thin metal plate with a cut pattern, used as a guide in making something accurately, as in woodworking or the carving of architectural profiles (the free Online Dictionary).

  3. Text Template A textual pattern used as a guide the generation of text.

  4. Text Template A textual pattern used as a guide the generation of text. <# foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { } <# } #> public class A1 { } public class A2 { } public class A3 { }

  5. Template Evolution Level 0: no template mechanism A function or group of functions generate code through a set of print statements based on configurative information. Output.print_line(~~~~~~~~~~~~~~~~~~~~); Output.print_line(~~~~~~~~~~~~~~~~~~~~); Output.print_line(~~~~~~~~~~~~~~~~~~~~); If (~~~~) then { Output.print_line(~~~~~~~~~~~~~~~~~~~~); Output.print_line(~~~~~~~~~~~~~~~~~~~~); } • - Hard to change both text structure and meta-data

  6. Template Evolution Level 1: accidental templates A function or group of functions generate code by applying substitution to string template fragmented throughout the program String s = “~~~~~~~~%name%~~~~~~~~~” Output.print_line(s1.Replace(“%name%”,name); • Still hard to change the model or the template. • - Inferring the target code’s structure requires understanding of the program’s logic.

  7. Template Evolution Level 2: Place Holder Templates The textual annotative code is organized as templates in files external to the generation engine that substitute variables for content in a generator specific way • + Template can be changed without changing the generator • Proprietary template syntax • Proprietarysubstitution mechanism • Model extensions may require generator changes. <html> !!Header_Content!! !!Body!! </html>

  8. Template Evolution Level 3: Scripted Templates code generators support templates that include scripting for accessing and substituting template variables. class <%=xo.GetName()%> { <% foreach x in xo.getList()%> <%=x.GetDataType()%> v<%=x.GetName()%>; <%=x.GetDataType()%> get<%=x.GetName()%>{ return v<%=x.GetName()%>; } void set<%=x.GetName(<%=x.GetDataType()%> p<%=x.GetName()%>) { v<%=x.GetName()%>=p<%=x.GetName()%>; } <%}%>

  9. Scripted Templates Benefits: • Both model and template can be changed without affecting the generator. • Standardized substitution mechanism.

  10. Scripted Templates However, the template and the model access code are still intermixed: • Miscoding pitfalls due to the superposition of the codes . • Incomprehensible and incoherent code. • Cumbersome development, test and debug process. • Restricted flexibility of the generated text’s structure. • Limited textual expressive power. • Unnecessary dependency on model access code changes. • Replicated code that burdens the development process.

  11. Scripted Templates Miscoding pitfalls due to the superposition of the code. using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); … SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } } } }

  12. Scripted Templates Miscoding pitfalls due to the superposition of the code. using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); … SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } } does not belong to the code but rather to the model access code. } }

  13. Scripted Templates Miscoding pitfalls due to the superposition of the code. using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); … SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } <# } #> } }

  14. Scripted Templates Incomprehensible and incoherent code. <#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } <# } #> } <# } #> } C# code that belongs to the mode access code Sql code in the data model code Textual code Formatting code

  15. Scripted Templates Cumbersome development and debug process. <#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } <# } #> } <# } #> } C# debugging goes here Sql query debugging here Text issues addressed here Wrong format in here

  16. Scripted Templates Restricted flexibility of the generated text’s structure. Function <%=X%> ( <%foreach …prm….%> <%=prm.datatype%> <%=prm.name%> <% if ….. %> , <%endif%> <%endif%> ) { … } Function Fnc1 (string prm1 , string prm2 , integer prm3 ) { .. } Function Fnc1 ( string prm1 , string prm2 , int prm3 ) { .. }

  17. Scripted Templates Limited textual expressive power. Create procedure getT1RowValues( @Key1 int in, @Key2 varhcar in, @val1 int out, @val2 varchar(20) out = ‘world’, @val3 varchar(20) out ) as Select@val1=val1, @val2=val2, @val3=val3 From T1 Wherekey1=@key1 and key2=@key2

  18. Scripted Templates Unnecessary dependency on model access code changes Function <%=X%> ( <%foreach …prm…in(select …from A).%> <%=prm.datatype%> <%=prm.name%> <% if ….. %> , <%endif%> <%endif%> ) { … } Function <%=X%> ( <%foreach …prm…in(select … from b).%> <%=prm.datatype%> <%=prm.name%> <% if ….. %> , <%endif%> <%endif%> ) { … }

  19. Scripted Templates Replicated code that burdens the development process. private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(),dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } - Replicated code in the same template as well as code replication that is caused by copying data access code into several templates. - Designing, testing, debugging and correcting anything but very trivial model access code becomes a prohibitively costly effort.

  20. Separation of Concerns Annotative information and model access code are separated aspects of code generation. Mixing them makes it difficult to maintain both.

  21. Separation of Concerns • Makes it possible to view a description as a set of coherent and focused concerns. • Different concerns may require different approaches. • Different concerns may require different skill sets.

  22. Separation of Concerns • Makes it possible to view a description as a set of coherent and focused concerns. • Different concerns may require different approaches. • Different concerns may require different skill sets.

  23. Template Separation of Concerns <#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } <# } #> } <# } #> }

  24. Template Separation of Concerns <#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #>_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set {_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>= value; } } <# } #> } <# } #> }

  25. Template Separation of Concerns <#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #>_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set {_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>= value; } } <# } #> } <# } #> } <= Model access code block <= Model access code block <= Model access code block

  26. Template Separation of Concerns • <#@ template language="C#" debug="True" hostspecific="True" #> • <#@ output extension=".cs" #> • <#@ assembly name="System.Data" #> • <#@ assembly name="System.xml" #> • <#@ import namespace="System.Collections.Generic" #> • <#@ import namespace="System.Data.SqlClient" #> • <#@ import namespace="System.Data" #> • using System; • namespace MyProject.Entities • { • <# • string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; • SqlConnection conn = new SqlConnection(connectionString); • conn.Open(); • System.Data.DataTable schema = conn.GetSchema("TABLES"); • string selectQuery = "select * from @tableName"; • SqlCommand command = new SqlCommand(selectQuery,conn); • SqlDataAdapter ad = new SqlDataAdapter(command); • System.Data.DataSet ds = new DataSet(); • foreach(System.Data.DataRow row in schema.Rows) • { • #> • public class <#= row["TABLE_NAME"].ToString().Trim('s') #> • { • <# • command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); • ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); • foreach (DataColumn dc in ds.Tables[0].Columns) • { • #> • private <#= dc.DataType.Name #>_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; • public <#= dc.DataType.Name #> <#= dc.ColumnName #> • { • get { return xxx ;} _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } • set ={ value = xxx ; }_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>= value; } • } • <# } #> • } • <# • } #> • }

  27. Encapsulation using System; namespace MyProject.Entities { public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { private <#= dc.DataType.Name #>_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set {_<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>= value; } } } } <#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> The expression is replaced with $ColName$.

  28. Encapsulation using System; namespace MyProject.Entities { public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { private <#= dc.DataType.Name #>_$ColName$; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return_$ColName$; } set {_$ColName$= value; } } } } <#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> $ColName$ encapsulates the substitution expression that belongs to the transformation layer rather than the template.

  29. Encapsulation using System; namespace MyProject.Entities { public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { private <#= dc.DataType.Name #>_$ColName$; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _$ColName$; } set {_$ColName$= value; } } } } Replace $TableName$ for <#= row["TABLE_NAME"].ToString().Trim('s') #> $DataType$ for <#= dc.DataType.Name #> $CSharpAttributeName$ for <#= dc.ColumnName #>

  30. Abstract Template using System; namespace MyProject.Entities { public class $TableName$ { [ private $DataType$_$ColName$; ^\n] [public $DataType$$CSharpAttributeName$ { get { return_$ColName$; } set {_$ColName$= value; } } ^\n] } }

  31. Abstract Template • Structural Clarity • Abstraction of Text • Readability • Model Access Code Reuse • Transformational Error Reduction • Textual Expressive Power • Traceability • Analyzability

  32. Abstract Template <#@ template language="C#" debug="True" hostspecific="True" #> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.xml" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="System.Data" #> using System; namespace MyProject.Entities { <# string connectionString = "Server=localhost;Database=GridViewGuy;Trusted_Connection=true"; SqlConnection conn = new SqlConnection(connectionString); conn.Open(); System.Data.DataTable schema = conn.GetSchema("TABLES"); string selectQuery = "select * from @tableName"; SqlCommand command = new SqlCommand(selectQuery,conn); SqlDataAdapter ad = new SqlDataAdapter(command); System.Data.DataSet ds = new DataSet(); foreach(System.Data.DataRow row in schema.Rows) { #> public class <#= row["TABLE_NAME"].ToString().Trim('s') #> { <# command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString()); foreach (DataColumn dc in ds.Tables[0].Columns) { #> private <#= dc.DataType.Name #> _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; public <#= dc.DataType.Name #> <#= dc.ColumnName #> { get { return _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #>; } set { _<#= dc.ColumnName.Replace(dc.ColumnName[0].ToString(), dc.ColumnName[0].ToString().ToLower()) #> = value; } } <# } #> } <# } #> } using System; namespace MyProject.Entities { public class $TableName$ { private $DataType$_$ColName$ public $DataType$$CSharpAttributeName$ { get { return _$ColName$; } set {_$ColName$= value; } } } } model content provided as a relational set.

  33. Abstract Template Level 4: Abstract Templates abstract, coherent, template centric representation of text. • Annotated Models: models with annotative information. • Text centric: do not include model access code. • Abstract: represents a meta-description of the text.

  34. Template Structure using System; namespace MyProject.Entities { public class $TableName$ { private $DataType$_$ColName$ public $DataType$$CSharpAttributeName$ { get { return_$ColName$; } set {_$ColName$= value; } } } } Hidden Assumptions: • DataType, ColName and CSharpAttributeName are in the context of TableName. • The annotative text is at a line boundary • There are no separators such as “and” or “,”.

  35. Template Structure using System; namespace MyProject.Entities { [public class $TableName$ { [private $DataType$_$ColName$ public $DataType$$CSharpAttributeName$ { get { return_$ColName$; } set {_$ColName$= value; } } ] } ] } The partition of the text to blocks clarifies the containment relationship between the attribute sets

  36. Attributes and Blocks using System; namespace MyProject.Entities { [public class $TableName$ { [private $DataType$_$ColName$ public $DataType$$CSharpAttributeName$ ] } ] } • A block is instantiated for every unique set of its attributes values. • An attribute is required by default. • A block is a multi-segment, multi-instance attribute of its container block. • A block is optional by default.

  37. Template Structure [ create table $TableName$ ( [ $ColName$$DataType$^,\n] ) ] Instance separator

  38. Template Structure [ create table $TableName$ ( [ $ColName$$DataType$ [ = $Default$ ] $*Comment$^,\n] ) ] Instance separator Optional block Optional variable

  39. Template Structure [ select [$AttName$^,] from $TableName$ [ where ![ $KeyAttName$= @$KeyAttName$ ^ and ] ] ] Instance separator Required block The block containing “where” requires at least one instance in its internal block in order to be generated.

  40. Template as Textual Projector A template is a projector of a hierarchical model portion or modelon [ create table $TableName$ ( [ $ColName$ $DataType$ [ = $Default$]$*Comment$^,\n] ) ]

  41. {TableName} {ColName,DataType,*Comment} … T(TableName,+C(ColName,DataType,*Comment,*D(Default)) 1 2 3 *{Default} Template as Textual Projector A template is a projector of a hierarchical model portion or modelon [ create table $TableName$ ( [ $ColName$ $DataType$ [ = $Default$]$*Comment$^,\n] ) ]

  42. T1 T2 {TableName} root {ColName,DataType,*Comment} 1 2 3 C1 C2 C3 C4 C5 *{Default} {C1,varchar(8)} {C2,int} {C3,int} {C4,varchar(8)} {C5,int} 0 Template as Textual Projector TableName(+C(ColName,DataType,*Comment,*D(Default))) Meta Model Abstract Model Hierarchical Relational create tableT1 ( C1 varchar(8), C2 int= 0, C3 int ) create tableT2 ( C4 varchar(8), C5 int ) Annotated Model Code [ create table $TableName$ ( [ $ColName$ $DataType$ [ = $Default$]$*Comment$^,\n] ) ] Annotated Meta Model = Template

  43. Template Structural Aspect An entity has zero or more attributes. [ xxx $att1$ yyy $att2$ zzz ] Attributes can be required or optional. $reqAtt$ $*OptAtt$ An entity is a composite attribute. Hence, an it can be required or optional An entity is optional by default. ![ xxx $att1$ yyy $att2$ zzz ] – required A (simple) attribute is required by default. $*OptAtt$ - optional

  44. Template Structural Aspect An instance of an entity is a unique set of attributes such that all required values are provided, recursively. The order of the instances is according to the value of the attributes based on the attributes sort level or order of appearance. Attributes are visible by default $~NonVisible$

  45. Conditional Attribute A conditional generation implies generating text conditionally or generating text for a subset of instances that meet the condition. The classify statement derives a subset of attributes from base attributes: Classify BaseTable isa Table where TableType=‘Base’;

  46. Conditional Attribute A conditional generation implies generating text conditionally or generating text for a subset of instances that meet the condition. The classify statement derives a subset of attributes from base attributes: Classify BaseTable isa Table where TableType=‘Base’; [ create procedure Insert_$BaseTable$ …… ] [ create procedure Insert_$Table$ [ @$Column$ $DataType$ ^,\n] [ insert $Table$ ( [ $Column$ ^,] ) values ( [ @$Column$ ^,] ) ] [ insert LOG ( TableName, Content) values ( “@$BaseTable$” , [ “$Column$=”+@$Column$ ^+] ) ] Generated only for base tables

  47. Distinct Partitioning Choice Attributes Di | i=1..n are classification of base attribute B such that an instance that have attribute Dx does not have attribute Dy unless x=y. Classify LongEntityName isa EntityName where LengthFlag=‘Y’; Classify ShortEntityName isa EntityName where LengthFlag=‘N’;

  48. Distinct Partitioning Choice Attributes Di | i=1..n are classification of base attribute B such that an instance that have attribute Dx does not have attribute Dy unless x=y. Classify LongEntityName isa EntityName where LengthFlag=‘Y’; Classify ShortEntityName isa EntityName where LengthFlag=‘N’; [$~EntityName$ ….. [ Entity $LongEntityName$ is a long entity and hence has this code ] [ Entity $ShortEntityName$ is a short entity only ] ] Only one block is generated. Each instance is separated by the separator of the enclosing block.

  49. Overlapping Partitioning Choice Attributes Di | i=1..n are classification of base attribute B such that an instance that have attribute Dx may have attribute Dy where x<>y. Classify L1EntityName isa EntityName where L<1; Classify L2EntityName isa EntityName where L<2;

  50. Overlapping Partitioning Choice Attributes Di | i=1..n are classification of base attribute B such that an instance that have attribute Dx may have attribute Dy where x<>y. Classify L1EntityName isa EntityName where L<1; Classify L2EntityName isa EntityName where L<2; [$~EntityName$ ….. [ Entity $L1EntityName$ has level 1 and up associated information ] [ Entity $L2EntityName$ has level 2 and up content ] ] Only one block is generated. Each instance is separated by the separator of the enclosing block.

More Related