CodeFluent and XMI: a second step towards supporting UML models

21 01 2010

We recently announced, the CodeFluent Importer could now create a CodeFluent Model from a Enterprise Architect Model (http://codefluent.wordpress.com/2009/11/20/codefluent-and-enterprise-architect-the-first-stone-towards-importing-uml-model/). Well, in the same continuity, we’re announcing the release of a new beta feature of the CodeFluent Importer: XMI 2.1 support. XMI is a standard, XML based, file format supported by several UML designers on the market such as the followings:

  • Enterprise Architect (Sparx Systems),
  • Magic Draw (No Magic Inc.),
  • UModel (Altova),
  • and many more!

For instance, here’s a model edited with Magic Draw UML 16.6:

The Model in MagicDraw

Model in MagicDraw

By saving your model in XMI, and running the CodeFluent Importer, you’ll get a CodeFluent Model. As an example, here’s the imported version of the previous model (viewed in CodeFluent’s upcoming graphic editor):

The imported CodeFluent Model

Now that you have a CodeFluent Model, you’ll now be able to generate 100% functional components by defining your desired producers. If ever you want to know more about this new CodeFluent Importer feature, feel free to contact us!

CodeFluent R&D Team





Concurrency Management with CodeFluent

13 01 2010

Since business applications are commonly used by multitudes of end users, concurrency management is a common issue in business application development.

Basics

Concurrency is a well-known issue and you’ll find nice articles (such as this one) explaining what concurrency is, as well as common patterns to address it.
To sum-up, there are three common ways to address concurrency management when developing your application:

  • No concurrency protection

Probably, the easiest to implement :) .
No concurrency protection implies several users can edit the same data, and the “last one wins” rule is applied.

  • Optimistic

In the optimistic concurrency model, users are always allowed to read the data, and perhaps even to update it. When the user attempts to save the data, however, the system checks to see if the data has been updated by anyone else since the user first retrieved it. If it has been changed, the update fails.

  • Pessimistic

This concurrency model places locks on data. If one user has a record open and any other users attempt to read that data in a context that allows editing, the system denies the request.

CodeFluent

CodeFluent supports the optimistic concurrency protection model, and this concurrency protection is activated for all entities by default. However, having a concurrency protection doesn’t always make sense, may it be for business reasons or technical ones. In such cases, it’s then possible to disable concurrency at the project level:

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1"
            defaultNamespace="Sample" defaultConcurrencyMode="None">
(...)
</cf:project>

Or for a specific entity:

<Customer concurrencyMode="None">
(...)
</Customer>

How it works

Entities with a concurrencyMode set to Optimistic (default) have an extra property named RowVersion that gets generated.
On each write operation, the RowVersion column in the persistence layer gets updated. Thanks to this property, CodeFluent can tell when a user tries to persist an obsolete version of an entity. This is done by comparing the persisted RowVersion to the one sent by the user: if ever they’re different, a CodeFluentConcurrencyException is raised.

Handling the CodeFluentConcurrencyException

When bumping into a CodeFluentConcurrencyException, the first question one should ask himself is: is it relevant to have concurrency protection on this business entity?
Having a concurrency protection doesn’t always make sense, may it be for business or technical reasons. For instance, a scenario where concurrency protection could be useless, would be in a case where children entities are automatically updated when a concurrency protected parent entity is updated: if updating the parent succeeded, updating children will.

Let’s get back to our exception and let’s say we do want concurrency protection on the entity that triggered the exception.
CodeFluent generates automatically a method named Reload which is made to help you handle those concurrency exceptions.
The Reload method takes as a parameter an enumeration named CodeFluentReloadOption which can be a combination of the following values:

  • BinaryLargeObjects
  • Default
  • Everything
  • Nothing
  • Properties
  • RowVersion
  • ShadowProperties

Note: The Default value is actually set to Everything.

Thanks to this method, you’ll be able to handle your concurrency exception by calling the reload method with the right option. For instance, would you want to bypass the concurrency protection, you could reload just the RowVersion so that you can overwrite the current record.
On the other hand you could also reload you’re whole entity by calling this method and ask the user to start-over with his modifications.

The CodeFluent R&D team.





Reusing existing .NET types with CodeFluent

12 01 2010

Hi!

First of all happy new year to our readers :)

Yes, using CodeFluent, you can store existing .NET types  instances to the persistence layer (whatever that is: SQL Server, Oracle database, etc.). There are actually many ways to do it.

Ok, let’s suppose we want to store, say, graphical shapes in the database.  We define this very simple model, defining coordinates, width and height of the shape bounding rectangle:

<Shape>
  <Id />
  <BoundsX typeName="int" />
  <BoundsY typeName="int" />
  <BoundsW typeName="int" />
  <BoundsH typeName="int" />
</Shape>

Here, .NET connoisseurs should object that this is heresy! There is an existing .NET type “Rectangle”, in the System.Drawing namespace, from the standard System.Drawing assembly, that already defines something similar. Can we use it? Yes, we can!

Binary Serialization

Out first shoot at this is:

<Shape>
  <Id />
  <Bounds typeName="System.Drawing.Rectangle" />
</Shape>

That works fine because CodeFluent tries to serialize everything it does not “know”. Known types are (using C# aliases when it exists): int, uint, long, ulong, short, ushort, byte, sbyte, byte[], bool, float, double, decimal, string, char, System.Guid, System.DateTime, System.TimeSpan, explicit CodeFluent blob types (declared using “file”, “video”, “image”, “audio”), all enum (System.Enum) types.

For all other “unknown” types, CodeFluent uses serialization. Ok, but what kind of serialization?

First, CodeFluent checks to see if the type implements the little known “IBinarySerialize” (from the Microsoft.SqlServer.Server namespace) interface. This is especially useful for SQL 2008 types (see this article http://forums.softfluent.com/default.aspx?g=posts&t=40 for more details).

Then, CodeFluent uses what has been configured on the property. This is defined by the model attribute ‘persistenceSerializationMode’. The default value  is ‘Binary | ArrayOfBytesType’. It means the .NET instance will be serialized using .NET standard serialization (not XML, not SOAP), and stored as an array of bytes.

Thus, our rectangle will be serialized as an array of bytes. With this model, the corresponding “Bounds” column data type in the database will be TEXT/NTEXT (SQL server) or BLOB (Oracle).

With the following C# using the generated BOM (note we use the standard .NET Rectangle type, as expected):

  Shape shape = new Shape();
  shape.Bounds = new System.Drawing.Rectangle(10, 20, 30, 40);
  shape.Save();

We will have this in SQL Server:

Xml Serialization

Now, we could also declare this

<Shape>
  <Id />
  <Bounds typeName="System.Drawing.Rectangle" persistenceSerializationMode="Xml | StringType" />
</Shape>

Because we used Xml combined with StringType, the corresponding “Bounds” column data type in the database will be XML (supported in SQL Server 2005 or higher and Oracle Database 10 or higher). With the same C# code, we will have this in SQL Server:

If we click on the Xml column, we can see the Rectangle instance was automatically serialized as plain Xml, thanks to CodeFluent:

Lightweight Serialization

Now, let’s suppose we want to load all our shapes ordered – server side – by the rectangle area, or we want to write some back end process that need access to the inner properties of the stored rectangles. What we want to do is have the X, Y, Width and Height properties available in the persistence layer. The solution is to declare the Rectangle .NET type as an existing CodeFluent lightweight entity. This is how we do this:

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultNamespace="Test" assemblyPaths="System.Drawing">
  <Rectangle namespace="System.Drawing, System.Drawing">
    <X />
    <Y />
    <Height />
    <Width />
  </Rectangle>
  <Shape>
    <Id />
    <Bounds typeName="System.Drawing.Rectangle" />
    <cf:method name="LoadOrderedByBoundsSize" body="load() raw">
      SELECT * FROM Shape ORDER BY Bounds_Shape_Rectangle_Width * Bounds_Shape_Rectangle_Height
    </cf:method>
  </Shape>
</cf:project>

In this model, you can see we declare a regular CodeFluent entity named “Rectangle” in the namespace System.Drawing. The ‘namespace’ attribute notation here includes the assembly name as well (without culture and version). Please note the project node also has an ‘assemblyPaths’ that helps CodeFluent to determine if an entity is an existing type or not. The value of ‘assemblyPaths’ is just a comma separated list of physical assembly paths, or GAC names.

When an existing type is declared as a CodeFluent entity, this entity does not have the notion of key properties. You just need to declare what properties you want CodeFluent to use when persisting an instance of it. These properties must exist and the name is case sensitive. In the case of Rectangle, X, Y, Height and Width are real properties of System.Int32 type. Rectangle also has Bottom or Left properties, but since they are redundant, we don’t declare them. The persistence type is automatically determined by CodeFluent using Reflection techniques.

In this example, the method is a RAW method because CodeFluent does not allow the * notation in an order by.

In the database we now have 4 columns representing the Bounds property. If we use the same previous C# code, this is what we have in the database:

Have fun with CodeFluent!

The CodeFluent R&D team.





CodeFluent supports Silverlight 4 (beta)

6 01 2010

A new assembly is now part of the setup: CodeFluent.Runtime.Silverlight4.dll. It can be used right now for your Silverlight 4 projects, just like CodeFluent.Runtime.Silverlight3.dll (for SL3) and CodeFluent.Runtime.Silverlight.dll (for SL2).

It has exactly the same features as the previous ones.

Have fun with Silverlight 4!

The CodeFluent R&D team.





CodeFluent 2009 Achievements

30 12 2009

Hi all,

Now is the time to list what has been added to the product this year!

Producers:

  • Microsoft SharePoint WebParts producer 2.0 (great enhancements at runtime)
  • Oracle Database producer 1.0 (beta)
  • Smart Client producer 1.0 (beta)
  • MSBuild producer 1.0
  • Patch producer 1.0
  • Microsoft Silverlight 2 support for Service Model (SCOM) producer
  • Microsoft Silverlight 3 support for Service Model (SCOM) producer
  • Microsoft Silverlight 4 (beta) support for Service Model (SCOM) producer

 

Importers:

  • Sparx Systems Enterprise Architect importer 1.0 (beta)

 

Others:

  • A lot of effort has been put into documentation
  • SQL 2008 support (geography, hierarchyid, geometry types, importer, …)
  • Access 2007 synchronization support
  • CodeFluent 64 bits native version (WOW support has always been there)
  • Enhancements to the CodeFluent Model (including Lightweight entities)
  • Blob import enhancements for all importers (including Access OLEObjects)
  • Xml documentation is now generated by BOM producer
  • New Starter Wizard tool has been added
  • New UrlValidate & EmailValidate rules
  • New TextSearch pattern

Phew! We really did all that, plus some more, less visible enhancements and bug fixes (it happens!). We also worked a lot on the CodeFluent graphical modeling tool, integrated with Microsoft Visual Studio 2008, and this is not yet visible…

As always, you can track the latest changes, from a technical perspective, here http://www.codefluent.com/builds/history.htm

The CodeFluent R&D team.





CodeFluent Oracle Producer is available (in Beta)!

18 12 2009

Hi everyone,

This long awaited persistence layer producer is now available for our customers. So there are now two persistence producers available from us: Microsoft SQL Server (supporting versions 2000, 2005 and 2008), and Oracle Database (supporting versions 10 and 11).

The Oracle producer is very logically comparable to the SQL Server one, in terms of features. It is capable of generating SQL scripts for:

  • Schema/Users
  • Tables
  • Constraints (primary and foreign keys)
  • Views
  • Procedures (and associated Oracle Packages)
  • Sequences (for auto numbering support)
  • Instances (including CodeFluent blob objects)

The beta version of this producer is missing one cool feature though: the difference engine. Today, it drops and recreates tables at each generation. However, this can be mitigated by the use of CodeFluent instances.

As a funny example, we have converted the Access Northwinds database into an SQL Server and an Oracle Northwinds database without writing a single line of code, using some cool CodeFluent features.

This is an image of the original unmodified Access database:

The first action was to use the CodeFluent Access Importer. This has created a CodeFluent model, shown here using the CodeFluent Portable Editor (not yet released!):

Then, we used simultaneously the SQL Server and the Oracle producer on the CodeFluent model. This is a diagram of the generated schema shown in SQL Server Enterprise Manager:

And this is a screenshot of Oracle’s SQL Developer, displaying the generated database:

Although CodeFluent is *not* an import/export tool, it does help for interoperability scenarios!

Some key points to emphasize:

  • The process used here is not a “simple” database-to-database import. It is a database-to-model-to-database generation. Oracle or SQL Server are not aware about Access here. The model could be modifed to suit any needs.
  • The CodeFluent Access importer is capable of extracting Access OLE Objects and transforming them into CodeFluent blob instances. Because SQL Server and Oracle producers are both capable of saving CodeFluent instances, including blob instances, they are also imported into the generated databases. We can clearly check this in the last screenshot (using SQ Developer builtin blob/image visualization feature) showing an image blob that existed in the original Access database.

The Oracle producer is available in latest CodeFluent builds, starting from today, here “http://www.codefluent.com/builds/Latests/”

The documentation has not yet been updated for the Oracle producer, so if you need it, please contact us at support@softfluent.com.

The CodeFluent R&D team.





SQL Hints

14 12 2009

CodeFluent allows developers to specify SQL specific hints on its methods.

For instance, doing as so:

<cf:project xmlns:cf=“http://www.softfluent.com/codefluent/2005/1″
            xmlns:cfps=“http://www.softfluent.com/codefluent/producers.sqlserver/2005/1″>

 <Customer>
    <Id />
    <Name />
    <cf:method name=“LoadByName”
            body=“load(string name) Where Name=@name” cfps:tableHint=“NOLOCK“ />
 </Customer>
</cf:project>

Will generate a T-SQL stored procedure with the NOLOCK hint applied to the Customer table.

A recurring question that we have is “which SQL Server hints does CodeFluent support?“. Well the answer is very straightforward: all of them! Since, the applied hint isn’t inferred from the specified value, it means that regarding CodeFluent, you could specify anything! All that matters is that the specified hint is actually supported by the targeted platform.

For an exhaustive hint list, please check-out your SQL Server’s corresponding documentation:

CodeFluent R&D Team





CodeFluent and the SqlGeography Type

14 12 2009

Although there is not a geography type in CodeFluent (as this is too specific to SQL Server 2008), you can still use the new SQL 2008 geography type today.

First you need to declare the target type in the CodeFluent SQL Server Producer (with the ‘cfps:dataType’ attribute). Then, optionally, you can declare a computed companion property that will hold the data as the corresponding SQL Server 2008 .NET Type: SqlGeography.

It will work because these types can be transferred back and forth as arrays of bytes. Here is a sample model that does it:

Code:

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1"
                   defaultNamespace="Test"
                   xmlns:cfps="http://www.softfluent.com/codefluent/producers.sqlserver/2005/1">

 <Address>
  <Id />
  <RawSpatialLocation cfps:dataType="geography" typeName="byte[]" maxLength="-1" />
  <SpatialLocation typeName="Microsoft.SqlServer.Types.SqlGeography" persistent="false">
  <cf:rule typeName="OnGet" />
  <cf:rule typeName="OnAfterSet" />
  <cf:snippet name="SpatialLocation">

 private void OnGetSpatialLocation()
 {
  _spatialLocation = new Microsoft.SqlServer.Types.SqlGeography();
  using (System.IO.MemoryStream stream = new System.IO.MemoryStream(RawSpatialLocation))
  {
   using (System.IO.BinaryReader reader = new System.IO.BinaryReader(stream))
   {
    _spatialLocation.Read(reader);
   }
  }
 }

 private void OnAfterSetSpatialLocation(Microsoft.SqlServer.Types.SqlGeography spatialLocation)
 {
  using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
  {
   using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(stream))
   {
    _spatialLocation.Write(writer);
    _rawSpatialLocation = stream.ToArray();
   }
  }
 }
  </SpatialLocation>
 </Address>
</cf:project>

NOTE1: make sure Microsoft.SqlServer.Types.dll is referenced for the project to compile.

NOTE2: all this is valid for the SqlGeography, SqlGeometry and SqlHierarchyId types.

The next version of CodeFluent will allow you to directly declare this:

Introduced with the latest CodeFluent build (B31218), you can now do this:

Code:

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1"
                  defaultNamespace="Test"
                  xmlns:cfps="http://www.softfluent.com/codefluent/producers.sqlserver/2005/1"
                  assemblyPaths="c:\temp\Microsoft.SqlServer.Types.dll"> <!-- adapt this to your machine -->

 <Address>
  <Id />
  <SpatialLocation cfps:dataType="geography" typeName="Microsoft.SqlServer.Types.SqlGeography, Microsoft.SqlServer.Types" />
</Address>
</cf:project>

CodeFluent R&D Team





Business Object Model Now Supports Oracle Databases

8 12 2009

Support of Oracle Databases at Business Object Model (BOM) level was now added using Microsoft’s (System.Data.OracleClient) and Oracle’s (Oracle.DataAccess.Client) providers.
To enable this support, neither extra attributes nor any modifications in the BOM are required: all one needs to do is to update its connection string declaration.

Example:

  1. .NET Oracle Provider:
    <[DefaultNamespace] persistenceTypeName="System.Data.OracleClient.OracleConnection, System.Data.OracleClient"
    connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MYORACLESERVER)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)));user id=HR;password=hr" />
    
  2. ODP.NET Oracle Provider:
    <[DefaultNamespace] persistenceTypeName="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess.Client"
    connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MYORACLESERVER)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)));user id=HR;password=hr" />
    

The CodeFluent runtime will automatically add the cursor parameter which is required to read Oracle Server procedures.

Even though the Oracle Server Producer is still on its way, this provides a way to map a generated BOM onto an Oracle persistence layer.

CodeFluent R&D Team





CodeFluent and Enterprise Architect: the first stone towards importing UML model.

20 11 2009

The R&D team has just delivered an internal release of CodeFluent that demonstrates how to import an UML model designed with Sparx Systems Enterprise Architect software. Starting from an input Abstract Class Model designed through EA, we are able to import the entire entities diagram as a CodeFluent model. The following screenshot depicts a sample EA model with the following business entities: Order, Order Status, Account, Transaction, Line Item and Stock Item:

 
 

Let’s now have a look of the generated CodeFluent model using the forthcoming CodeFluent modeler:

 
 

The Enterprise Architect importer is still at an early stage of the development cycle but we will work hard during the forthcoming months to deliver a complete solution for importing UML models to CodeFluent. You will then be able to generate ready to use components (from database to UI such as SharePoint) on Microsoft technologies.

Ease your life, use CodeFluent .

Stay tuned!

Omid Bayani.