In this post, I will generate, from the same model, text files for C#, Java, and VB.NET. Previous posts:
Building An Application Using AjGenesis (Part 1)
Building An Application Using AjGenesis (Part 2)
Building an Application Using AjGenesis (Part 3)
The code of this post can be downloaded from AppExampleStep04.zip.
You need the latest AjGenesis binaries. You can get them from AjGenesisTrunkBinaries.zip. (the full source code is at AjGenesis Codeplex repository). You should add the bin directory to your path, to run the examples of this post.
The example now has more folder structure:
Projects\AjApp is the folder containing the model of the example, in Project.xml:
<Project> <Name>AjApp</Name> <Description>Building an Application using AjGenesis</Description> <Model> <Entities> <Entity Source="Entities/Customer.xml"/> <Entity Source="Entities/Supplier.xml"/> </Entities> </Model> </Project>I could add more folders, describing other projects, if needed.
At root folder, the example have three commands:
GenerateCSharp.cmd
GenerateJava.cmdGenerateVbNet.cmd
The three commands have a similar content. This is the GenerateCSharp.cmd:
AjGenesis.Console Projects\AjApp\Project.xml Projects\AjApp\Technologies\CSharp.xml Tasks\Complete.ajg Tasks\Generate.ajg
Note there is two model: Project.xml is like the previous posts. The new one describe the technology to use, CSharp.xml:
<Technology> <Name>CSharp</Name> </Technology>Now, it’s only the name of the programming language. I could extend this model to define database, web servers to use, etc…. Then: Project.xml is the abstract model. Technologies\CSharp.xml, Technologies\VbNet.xml, Technologies\Java.xml are the models describing the technology to use. Each of the Generate*.cmd loads the abstract model, AND one of the tech ones.
The Complete.ajg:
' Set Build Directory if not Project.BuildDirectory then Project.BuildDirectory = "Build/${Project.Name}/${Technology.Name}" end if FileManager.CreateDirectory(Project.BuildDirectory) IncludeCode "Tasks/Complete${Technology.Name}.ajg"Note the use of a trick: include the code of another file, to run, using a dynamic string. If Technology.Name == “CSharp”, the above task will execute CompleteCSharp.ajg:
' Some functions ' Name to use for variables function CSharpVariableName(name) firstletter = name.Substring(0,1) return firstletter.ToLower() & name.Substring(1) end function ' Name to use for Classes, Properties.. function CSharpName(name) firstletter = name.Substring(0,1) return firstletter.ToUpper() & name.Substring(1) end function function CSharpType(type) type = type.ToLower() if type="text" then return "string" end if if type="integer" then return "int" end if return type end function ' Set namespace to use in CSharp code if not Project.CSharp.Namespace then Project.CSharp.Namespace = CSharpName(Project.Name) end if ' Complete Entities for each Entity in Project.Model.Entities ' Set the variable name to use for an entity if not Entity.CSharp.VariableName then Entity.CSharp.VariableName = CSharpVariableName(Entity.Name) end if for each Property in Entity.Properties ' Set the CSharp to use in each property if not Property.CSharp.Type then Property.CSharp.Type = CSharpType(Property.Type) end if end for end forThere are similar tasks for the others technologies: CompleteVbNet.ajg, CompleteJava.ajg. These tasks complete the model in memory (like assigning namespaces, packages, variable names to properties, build directory…)
The second task is Generate.ajg:
IncludeCode "Tasks/Generate${Technology.Name}.ajg"Again, the old trick of dynamic include. This is the GenerateCSharp.ajg subtask:
for each Entity in Project.Model.Entities TransformerManager.Transform("Templates/CSharp/EntityClass.tpl", "${Project.BuildDirectory}/${Entity.Name}.cs", Environment) end forTo compare, this is the CompleteJava.ajg:
' Some functions ' Name to use for variables function JavaVariableName(name) firstletter = name.Substring(0,1) return firstletter.ToLower() & name.Substring(1) end function ' Name to use for Classes, Properties.. function JavaName(name) firstletter = name.Substring(0,1) return firstletter.ToUpper() & name.Substring(1) end function function JavaType(type) type = type.ToLower() if type="text" then return "String" end if if type="integer" then return "int" end if return type end function ' Set package to use in Java code if not Project.Java.Package then Project.Java.Package = JavaName(Project.Name).ToLower() end if ' Complete Entities for each Entity in Project.Model.Entities ' Set the variable name to use for an entity if not Entity.Java.VariableName then Entity.Java.VariableName = JavaVariableName(Entity.Name) end if for each Property in Entity.Properties if not Property.Java.VariableName then Property.Java.VariableName = JavaVariableName(Property.Name) end if ' Set the Java to use in each property if not Property.Java.Type then Property.Java.Type = JavaType(Property.Type) end if end for end forand the GenerateJava.ajg:
for each Entity in Project.Model.Entities TransformerManager.Transform("Templates/Java/EntityClass.tpl", "${Project.BuildDirectory}/${Entity.Name}.java", Environment) end forThere are templates for each technology. This is EntityClass.tpl for CSharp:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) namespace ${Project.CSharp.Namespace} { public class ${Entity.Name} { <# for each Property in Entity.Properties #> public ${Property.CSharp.Type} ${Property.Name} { get; set; } <# end for #> } }and this is EntityClass.tpl for Java:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) package ${Project.Java.Package}; public class ${Entity.Name} { <# for each Property in Entity.Properties #> private ${Property.Java.Type} ${Property.Java.VariableName}; <# end for for each Property in Entity.Properties #> public ${Property.Java.Type} get${Property.Name}() { return this.${Property.Java.VariableName}; } public void set${Property.Name}(${Property.Java.Type} value) { this.${Property.Java.VariableName} = value; } <# end for #> }Running the three Generate*.cmds, create the Build folder, with Build\AjApp, Build\AjApp\CSharp, Build\AjApp\Java, Build\AjApp\VbNet subfolders.
The generated Customer.cs:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) namespace AjApp { public class Customer { public string Name { get; set; } public string Address { get; set; } } }The generated Customer.vb:
' Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) Namespace AjApp Public Class Customer Private mName as String Private mAddress as String Public Property Name as String Get return Me.mName End Get Set(value as String) Me.mName = value End Value End Property Public Property Address as String Get return Me.mAddress End Get Set(value as String) Me.mAddress = value End Value End Property End Class End NamespaceThe generated Customer.java:
// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com) package ajapp; public class Customer { private String name; private String address; public String getName() { return this.name; } public void setName(String value) { this.name = value; } public String getAddress() { return this.address; } public void setAddress(String value) { this.address = value; } }Next steps: to generate a C# or VB.NET project, to load in Visual Studio, or an Eclipse project for Java.
Keep tuned!
Angel “Java” Lopez
http://www.ajlopez.com
[...] assets from my post Building An Application using AjGenesis (Part 4), I wrote the [...]
Pingback by AjGenesis and Language Workbench Competition 2011 « Angel “Java” Lopez on Blog — March 8, 2011 @ 5:33 pm