Angel \”Java\” Lopez on Blog

July 19, 2010

NoSQL Resources

Filed under: Alt.NET, Distributed Computing, NoSQL — ajlopez @ 9:56 am

Thanks to ALT.NET Hispano community, I attended to a VAN (Virtual des-conference), past May 22th. The topic I presented was NoSQL. The Van was in Saturday, and at the next Monday, its video was published at::

VAN NoSQL (Spanish)

Now, this post is a list of resources I used to preparte my talk. First, the Spanish presentation can be downloaded from my Skydrive NoSqlVan2010.pptx

Resources about NoSQL:

A landscape in Wikipedia article.
A brief history of NoSQL interesanting the mention of Pick systems, I mentioned them in my presentation.
Java development 2.0: NoSQL an IBM introduction
NoSQL Architecture
MyNoSQL Active blog about NoSQL
NoSQL Databases – Part 1 – Landscape
NoSQL: scaling to size and scaling to complexity
http://nosql-database.org/
What is NoSQL?
The NoSQL alternative
NoSQL Summer, list of papers
BASE: an Acid alternative
Errors in database systems, eventual consistency and the CAP theorem
Scalable Datastores: comparison nosql, and some scalable RDBMS
NoSQL el movimiento en contra de las bases de datos (Spanish)
Diff SQL NoSQL
Choosing a NoSQL data store according to your data set
John P. Wood NoSQL posts
Databases: relational vs object vs graph vs document
NoSQL: no necesitas ACID
NoSQL and SQL anti-patterns
Learning NoSQL from Twitters experience

About Eventual Consistency:

http://www.allthingsdistributed.com/2008/12/eventually_consistent.html
http://queue.acm.org/detail.cfm?id=1466448
http://devblog.streamy.com/tag/eventual-consistency

CAP Theorem

http://www.julianbrowne.com/article/viewer/brewers-cap-theorem
http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf
There is no free lunch with distributed data

About Google BigTable:

http://labs.google.com/papers/bigtable.html

About Hypertable:

http://hypertable.org/
Hypertable NoSQL (pdf)

About Amazon Dynamo:

Amazon Dynamo (original paper)

About Cassandra:

http://cassandra.apache.org/
http://wiki.apache.org/cassandra/ArticlesAndPresentations
Cassandra by example (Twitter alike one)
http://github.com/ericflo/twissandra
WTF is a supercolumn Cassandra model
Cassandra NoSQL Database
Apache Cassandra
NoSQL Live Dynamo derivatives: Cassandra
http://github.com/suguru/cassandra-webconsole
Tutorial: Getting started with Cassandra
NoSQL in Twitter
Twitter, Facebook and Cassandra, and Open Source
Cassandra and Twitter: interview with Ryan King
(Twitter is reviewing if they use or not NoSQL)

About Voldemort:

http://project-voldemort.com/
Voldemort design
The NoSQL that must not be named
Product project Voldemort Distributed Database

About CouchDB:

http://couchdb.apache.org
CouchDB Introduction
CouchDB Overview

About SimpleDB

http://awsdocs.s3.amazonaws.com/SDB/latest/sdb-gsg.pdf
http://awsdocs.s3.amazonaws.com/SDB/latest/sdb-dg.pdf

About Redis

http://code.google.com/p/redis/
Twitter alike example
Add NoSQL Data Storage to your PHP development with Redis

Memcached:

http://memcached.org/

Graph NoSQL

InfoQ: Graph NoSQL Neo4j
Graph databases: A special case of document databases

Related topics:

Scalability of the Hadoop distributed file system
MapReduce Hadoop algorithms in academic papers

About MongoDB:

NoSQL with MongoDB, NoRM, and ASP.NET, part 1
NoSQL with MongoDB, NoRM, and ASP.NET, part 2
Master Slave in MongoDB
Choosing a non relational database: Why we migrated from MySQL to MongoDb
MongoHQ – The cloud-based hosted database solution for MongoDB.
http://github.com/azamsharp/SKOOL MongoDB, VS2010, ASP.NET MVC, TDD, BDD example
On distributed consistency

The example I used in my talk, with MongoDB was inspired in the first article by Ted Neward:

Going NoSQL with MongoDB
Going NoSQL with MongoDB (Part 2)
Going NoSQL with MongoDB (Part 3)

Example code, very simple page with ASP.NET MVC, MongoDb (add the driver in libraries to the project)

MongoDbMvcApplication1.zip

For this example, I downloaded:

http://github.com/samus/mongodb-csharp
http://www.mongodb.org/display/DOCS/Downloads

My links about these topics:

http://delicious.com/ajlopez/mysql
http://delicious.com/ajlopez/mongodb
http://delicious.com/ajlopez/cassandra
http://delicious.com/ajlopez/couchdb

If you want presentations, tutorials, examples, reviews, try links like:

http://delicious.com/ajlopez/mysql+tutorial
http://delicious.com/ajlopez/mysql+presentation
http://delicious.com/ajlopez/mysql+example
http://delicious.com/ajlopez/mysql+review

Keep tuned!

Angel "Java" Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

July 14, 2010

Building an Application Using AjGenesis (Part 4)

Filed under: AjGenesis, Code Generation, Open Source Projects — ajlopez @ 7:28 pm

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.cmd

GenerateVbNet.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 for

There 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 for

To 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 for

and the GenerateJava.ajg:

for each Entity in Project.Model.Entities
	TransformerManager.Transform("Templates/Java/EntityClass.tpl", "${Project.BuildDirectory}/${Entity.Name}.java", Environment)
end for

There 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 Namespace

The 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

http://twitter.com/ajlopez

July 11, 2010

Building an Application Using AjGenesis (Part 3)

Filed under: AjGenesis, Code Generation, Open Source Projects — ajlopez @ 9:08 pm

This is the third part in this tutorial post series, about building an application using AjGenesis, my open source code generation project. Previous posts:

Building An Application Using AjGenesis (Part 1)
Building An Application Using AjGenesis (Part 2)

The code of this post can be downloaded from AppExampleStep03.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.

This time, I improve the code generation process. The model is the same, but now, the GenerateClasses.cmd:

AjGenesis.Console Project.xml CompleteModelCSharp.ajg GenerateClasses.ajg

has a new parameter: an intermediate task to execute, CompleteModelCSharp.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 for

New things: the definition of functions, the use of .NET method as .ToUpper(), and the completion of the model, like in:

if not Project.CSharp.Namespace then
  Project.CSharp.Namespace = CSharpName(Project.Name)
end if

I added some properties in the model-in-memory. If you don't define a namespace to use, one is created. Note the if Project.CSharp.Namespace is not defined and Project.CSharp is nothing, no exception is raised: undefined O.A.B is evaluated as nothing, and nothing is false in AjBasic (strategy borrowed from PHP).

Then, the above code enriches the model to use, taking decisions related to C#. In next posts, I will write similar code for other technologies. But it's worth to mention that this approach able to write a model, and then, when the technology is chosen, enrich them with tech info.

There is a fragment that add C# type to properties:

  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

The second task is the same of the previous post, GenerateClasses.ajg:

for each Entity in Project.Model.Entities
  TransformerManager.Transform("EntityClass.tpl", "${Entity.Name}.cs", Environment)
end for

The template EntityClass.tpl:

// 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
#>
  }
}

now uses the new properties in model.

This is the Customer.cs generate file:

// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com)
namespace AjApp {
public class Customer
  {
    public string Name { get; set; }
    public string Address { get; set; }
  }
}

Next steps: write more tasks and templates to generate Java, VB.NET files.

As usual, I should mention this is a tutorial series. In the real life, I prefer to adopt another approach, described in my previous post AjGenetizing An Application.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

July 9, 2010

Building an Application using AjGenesis (Part 2)

Filed under: AjGenesis, Code Generation, Open Source Projects — ajlopez @ 10:06 pm

This is the second post in the serie, explaining how to build an application using AjGenesis, my open source code generation project. The previous post in this serie:

Building An Application Using AjGenesis (Part 1)

In this second part, I will generate two simple files, from the model defined in the last post.

The files for this second steps can be downloaded from AppExampleStep02.zip.

You need to download the AjGenesis binaries (trunk version) from AjGenesisTrunkBinaries.zip, expand them, AND add the bin folder to your path.

There is the command PrintEntities.cmd:

AjGenesis.Console Project.xml PrintEntities.ajg

AjGenesis.Console is the console program that launch the AjGenesis process. It receives many arguments. If the argument is an .xml file, its content is loaded in memory as an AjGenesis model (explained below). If the argument is an .ajg, the content of the file is a task, a list of commands to execute in AjGenesis. The commands are written in an interpreted language, named AjBasic.

This is the content of Project.xml (read previous post for more details):

<Project>
  <Name>AjApp</Name>
  <Description>Building an Application using AjGenesis</Description>
  <Model>
    <Entities>
      <Entity Source="Customer.xml"/>
      <Entity Source="Supplier.xml"/>
    </Entities>
  </Model>
</Project>

Once the model is loaded in memory, there is a public variable Project with dynamic properties loaded for each attribute and element. From AjBasic, we can access Project, Project.Model, and Project.Model.Entities.

The content of PrintEntities.ajg:

for each Entity in Project.Model.Entities
  Message "Entity " & Entity.Name
  
  for each Property in Entity.Properties
    Message "   Property ${Property.Name}"
  end for
end for

Note the use of for each, an AjBasic command. Message is a command to print something in the output console. The above code shows one of the features of AjBasic: string expansion. That is, the string:

“ Property ${Property.Name}”

is expanded in runtime to the content of the expression between ${ and }. If you run

PrintEntities.cmd

the output is:

Entity Customer

   Property Name

   Property Address

Entity Supplier

   Property Name

   Property Address

Now, let generate one class file in C# for each entity in model. This is the GenerateClasses.cmd:

AjGenesis.Console Project.xml GenerateClasses.ajg

This command loads Project.xml in memory, and execute the AjGenesis task:

for each Entity in Project.Model.Entities
  TransformerManager.Transform("EntityClass.tpl", "${Entity.Name}.cs", Environment)
end for

There are few public helper objects, predefined in AjGenesis environment. One of them is TransformerManager, that takes three arguments:

- The template file name

- The name of the file to generate

- The current Environment (name/values of global variables and functions, usually pointed by Environment global variable)

This is the first template in this tutorial series, EntityClass.tpl:

// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com)
public class ${Entity.Name}
{
<#
  for each Property in Entity.Properties
#>
  public string ${Property.Name} { get; set; }
<#
  end for
#>
}

A template is a text file with the content to generate, and with fragments between <# and #> that are filled with AjBasic commands. In the above template, the for each command processes each of the properties in the current entity. As in the string expansion, expressions between ${ and } are evaluated and its results are inserted in the output of template process.

This is the output generated for Customer.cs using EntityClass.tpl template:

// Entity Class, generated with AjGenesis (http://ajgenesis.codeplex.com)
public class Customer
{
  public string Name { get; set; }
  public string Address { get; set; }
}

There are still some simplifications: no namespace, all properties are strings, no id for entities, etc… I will address these issues, step by step, in future posts. Next steps: generate, from the same model, C#, VB.NET or Java class files.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

July 7, 2010

Building an Application using AjGenesis (Part 1)

Filed under: AjGenesis, Code Generation, Open Source Projects — ajlopez @ 8:45 pm

This is the first step in a tutorial about how to use AjGenesis to generate an application. The target solution will be .NET, with C#, but I will add some VB.NET, PHP and Java examples, as a “proof of concept” of the power of an abstract model.

This is the first step: write a simple model. You can write the model in XML files, or in plain text files. In this first step, I will write the model in XML format.

The initial model is a free one: you can design the model as you want. In this serie of post, I will refine the model, step by step, to show how to design a complete solution, that can be reused and extended with manual code and extensions. I want to model an enterprise application: customers, suppliers, invoices, payments, etc. Let start with Customer and Supplier.

(You can download the code from AppExampleStep01.zip (only three short XML files))

This is the Customer.xml file:

<Entity>
	<Name>Customer</Name>
	
	<Properties>
		<Property>
			<Name>Name</Name>
			<Type>Text</Type>
		</Property>
		<Property>
			<Name>Address</Name>
			<Type>Text</Type>
		</Property>
	</Properties>
</Entity>

There is a similar file for Supplier.xml. Note that there is no schema to follow: you can add any tag in a well formed document. In the next steps, I will load the model in memory, to be process by AjGenesis tasks and template. AjGenesis will recognize automatically that <Properties> is a list of tags <Property>. See that there is simple values, like <Name>, and compound ones, like <Property>.

One of the principles that guided me in my design choices was: the model (XML, text file, etc..) should not hurt my eyes. So, instead of write all the model in only one file, I wrote another XML file that include the entities:

<Project>
	<Name>AjApp</Name>
	<Description>Building an Application using AjGenesis</Description>
	<Model>
		<Entities>
			<Entity Source="Customer.xml"/>
			<Entity Source="Supplier.xml"/>
		</Entities>
	</Model>
</Project>

 

The attribute Source is a distinguished one: AjGenesis process that tag including the content of the referenced file, as it were in the parent file. When AjGenesis load the model, it will be one in memory, altought it is serialized in many  files.

Next steps: how to use this model in AjGenesis, and generate some C# files from it.

Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

July 4, 2010

Generating a solution with AjGenesis using NHibernate Hbm files

Filed under: .NET, AjGenesis, Code Generation, NHibernate, Open Source Projects — ajlopez @ 9:06 pm

Some months ago, I wrote an example of code generation, using .hbm files as the initial model:

Generating Code with AjGenesis Using NHibernate Hbm Files

Since then, I improved the example. You can download from the trunk at Codeplex:

I prepared a ready-to-run package, at my Skydrive:

Examples > AjGenesis > NHibernateMappingExample02.zip

This is its folder structure:

There is two projects: AjFirstExample, and AjTest. The former has only two simple entities. The latter has entities with one-to-many relation. You can generate the code for a complete .NET solution, launching commands:

GenerateAjFirstExample.cmd
GenerateAjTest.cmd

There are “shortcuts” to

GenerateProject AjFirstExample
GenerateProject AjTest

This is the solution generated for AjTest project:

You can run it as a web site:

In this example, the model, the .hbm files, was enriched with the use of meta tags, like in Employee.hbm in AjTest:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
  assembly="AjTest.Entities"
  namespace="AjTest.Entities"
  >
  <class name="Employee" table="employees">
    <meta attribute="SetName">Employees</meta>
    <meta attribute="Descriptor">Employee</meta>
    <meta attribute="SetDescriptor">Employees</meta>
    
    <id name="Id" column="Id" type="Int32">
      <meta attribute="Description">Id</meta>
      <generator class="native"/>
    </id>
    <property name="EmployeeCode" type="String">
      <meta attribute="Description">Employee Code</meta>
    </property>
    <property name="LastName" type="String">
      <meta attribute="Description">Last Name</meta>
    </property>
    <property name="FirstName" type="String">
      <meta attribute="Description">First Name</meta>
    </property>
    <many-to-one name="Department" column="IdDepartment"
                 class="AjTest.Entities.Department, AjTest.Entities" />
    <bag name="Tasks" lazy="true" inverse="true" cascade="all">
      <key column="IdEmployee"/>
      <one-to-many class="AjTest.Entities.Task, AjTest.Entities"/>
    </bag>  
    <bag name="EmployeeSkills" lazy="true" inverse="true" cascade="all">
      <key column="IdEmployee"/>
      <one-to-many class="AjTest.Entities.EmployeeSkill, AjTest.Entities"/>
    </bag>  
  </class>
</hibernate-mapping>

Note the use of the meta tag at class level, and at property level. AjGenesis run tasks, one is Tasks\LoadMappings.ajg:

include "Utilities/Utilities.tpl"
include "Utilities/FileUtilities.tpl"
include "Utilities/TypeUtilities.tpl"
Include("Utilities/NHibernateUtilities.tpl")
include "Templates/CSharp/UtilitiesCs.tpl"
include "Templates/CSharp/CSharpFunctions.tpl"
AssemblyManager.LoadFrom("Libraries/NHibernate.dll")
parser = new NHibernate.Cfg.MappingSchema.MappingDocumentParser()
if not Project.BuildDir then
  Project.BuildDir = "Build/${Project.Name}/CSharp"
end if
Project.Entities = CreateList()
for each MappingName in Project.Mappings
  filename = "Projects/${Project.Name}/Mappings/${MappingName}.hbm.xml"
  mapping = parser.Parse(OpenAsStream(filename))
    
  for each hbmclass in mapping.Items where IsType(hbmclass, "HbmClass")
    Entity = CreateObject()
    
    Project.Entities.Add(Entity)
  
    Entity.ClassName = hbmclass.name
    Entity.Name = hbmclass.name
    Entity.Namespace = mapping.namespace
    
    Message "Processing Mapping of Entity " & Entity.Name
        
    Entity.Properties = CreateList()
    
    if hbmclass.Id then
      Property = CreateObject()
      Property.Name = hbmclass.Id.name
      Property.Type = HbmTypeToCSharp(hbmclass.Id.type1, Entity.Namespace)
      Property.IsId = True
      for each meta in hbmclass.Id.meta
        Property.SetValue(meta.attribute, meta.GetText())
      end for
      Entity.Properties.Add(Property)
    end if
    
    for each meta in hbmclass.meta
      Entity.SetValue(meta.attribute, meta.GetText())
    end for
        
    for each item in hbmclass.Items
      Message "Processing Item " & item.GetType().Name
      
      if IsType(item, "HbmProperty") then
        Property = CreateObject()
        Property.Name = item.name
        Property.SetValue("Description", "Description " & item.name)
        Property.Type = HbmTypeToCSharp(item.type1, Entity.Namespace)
        Entity.Properties.Add(Property)
        for each meta in item.meta
          Property.SetValue(meta.attribute, meta.GetText())
        end for
      end if
      
      if IsType(item, "HbmManyToOne") then
        Property = CreateObject()
        Property.Name = item.name
        Property.Type = HbmTypeToCSharp(item.class, Entity.Namespace)
        Property.Reference = HbmTypeToCSharp(item.class, Entity.Namespace)
        Entity.Properties.Add(Property)
      end if
      if IsType(item, "HbmSet") then
        Property = CreateObject()
        Property.Name = item.name
        Property.IsSet = true
        Property.Type = HbmTypeToCSharp(item.Item.class, Entity.Namespace)
        Entity.Properties.Add(Property)
      end if
      if IsType(item, "HbmBag") then
        Property = CreateObject()
        Property.Name = item.name
        Property.IsList = true
        Property.Type = HbmTypeToCSharp(item.Item.class, Entity.Namespace)
        Entity.Properties.Add(Property)
      end if
    end for    
  end for
end for

Note the use of Property.SetValue(…), Entity.SetValue(…) to enrich the in-memory model representation with the new metadata contained in mapping files. As in other AjGenesis examples, the metadata is used to show legends in presentation files, or for whatever you want to put in the tasks and templates.

This is a “proof-of-concept” example. It should be improved to use all the power of NHibernate. But it’s a demostration of the power of an initial model, to create lot of text artifacts, in this case, a ready-to-run application.

More examples are coming, this time using a free model. Keep tuned!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Theme: Shocking Blue Green. Get a free blog at WordPress.com

Follow

Get every new post delivered to your Inbox.

Join 67 other followers