Thursday, August 19, 2010

Introducing "VeroMark", Object-RDF Mapping (ORM)

"VeroMark" semantic client user interface builder adds to WPF's already rich, XAML-based presentation system powerful UI control extensions as well as the ability to manage data retrieval, data bind UI elements to it, and navigate between pages entirely through configuration, thus enabling the construction of complete WPF user interfaces without touching compiled code. Instead of producing mock-ups and explaining what they imagine the business needs, picture your data and business analysts marking up their ideas directly as functioning UI screens, allowing your software developers to focus on more technical aspects.

As a part of eliminating the need for compiled code, VeroMark supports data binding to an RDF triples-based client model through an object-RDF mapping (ORM) mechanism, which decouples presentation from an underlying "VeroServe Data" data model such that the application's usability isn't limited by it. This article introduces "VeroMark" object-RDF mapping and illustrates key concepts using a simple example.

Building Blocks
WPF's built-in data binding technology is at the heart of how VeroMark connects the user interface elements to the client data and keep them in sync with one another. The client data model available in a page is "described" in XAML markup (this is the ORM) and made available for data binding via one or more EntityProviders. A user interface element is then data-bound to one of these EntityProviders (via an XAML Binding expression "Source"), which at run-time provides in-memory EntityValue object instance(s) that provide access to the actual data to be interacted with on the screen.


Figure 1 Logical relationships between data binding components

Conceptually, think of a description as a Type definition that includes information about how to access property values from within the client data, and an EntityValue as an instance of that Type that provides access to the described properties from a specific, run-time data context (e.g. some specific Id chosen on a search results page).

There is also an EntityValue derivative called Entity, which adds the ability to contain other EntityValue instances (think Composite pattern) and makes them accessible via its property indexer and their description Name. The containment hierarchy of Entity/EntityValue(s) returned by an EntityProvider is determined by the containment hierarchy of its associated description.

Binding Example
Here we show a small example based on the example Ontology. First, we create the description that defines our "BlogEntity". Each property description below defines the property name, the value type (Literal or Identifier), and a Sparql graph pattern for obtaining the unit of client data using a specific data context:

<Controller:EntityDescription x:Key="BlogEntityDescription">
<Controller:EntityDescription.PropertyDescriptions>
<Controller:EntityValueDescription Name="Type" ValueType="Utilities:Identifier">
<Controller:EntityValueDescription.DataAccessor>
<Controller:Template DefaultPattern="?BlogEntity rdf:type ?Type"/>
</Controller:EntityValueDescription.DataAccessor>
</Controller:EntityValueDescription>
<Controller:EntityValueDescription Name="ReferenceName" ValueType="Utilities:Literal">
<Controller:EntityValueDescription.DataAccessor>
<Controller:Template DefaultPattern="?BlogEntity upo:hasReferenceName ?ReferenceName"/>
</Controller:EntityValueDescription.DataAccessor>
</Controller:EntityValueDescription>
<Controller:EntityValueDescription Name="Location" ValueType="Utilities:Identifier">
<Controller:EntityValueDescription.DataAccessor>
<Controller:Template DefaultPattern="?BlogEntity upo:hasLocation ?Location"/>
</Controller:EntityValueDescription.DataAccessor>
</Controller:EntityValueDescription>
</Controller:EntityDescription.PropertyDescriptions>
</Controller:EntityDescription>

Next, we create an EntityProvider instance that references the description (via the "DescriptionSource" property):

<Dsp:EntityProvider x:Key="BlogEntityProvider" PageModelManager="{StaticResource ModelManager}" RootVariable="BlogEntity">
<Controller:DescriptionGenerator DescriptionSource="{StaticResource BlogEntityDescription}" IsSharedDescription="True">
<Controller:Setter PropertyName="Name" Value="BlogEntity"/>
</Controller:DescriptionGenerator>
</Dsp:EntityProvider>

And finally, we data-bind the Text property of a UI TextBox to the "ReferenceName" property we defined as part of the BlogEntity description:

Text="{Binding Source={StaticResource BlogEntityProvider}, Path=[ReferenceName].StringValue, Mode=OneWay}"

A WPF Binding Path starts from a particular object instance (that provided by the Binding Source) and follows the path of property relationships to the resulting property value. Properties preceded by the "." syntax refer to compile time properties, while those encased in square brackets ("[]") refer to property indexer with a signature Type-compatible with the value between the brackets.

We will cover EntityValue properties in more detail in a future article, but for now note that "StringValue" is a compile time property that gives us to access to the string form of the "ReferenceName" Literal in the client data.


Figure 2 Working Example showing "BlogEntity" properties bound to UI elements

In future articles we will elaborate on various aspects of VeroMark data binding including:
  • View Model properties available for binding (via the XAML Binding expression "Path")
  • Data context containment-inheritance
  • Templates
  • Binding converters
  • Other data source "providers" (e.g. FindProvider)


No comments:

Post a Comment