JDF Blog

Tools, techniques and advice for real-world JDF integrations

Fluent JDF Version Released

with one comment

Fluent JDF Version has been released. You can get the latest package on Nuget or download the binaries from the Codeplex page. Release notes are on our documentation site. This release has a couple of bug fixes including a work-around for what looks like a .NET Framework bug that causes problems with schema validation under some circumstances. The release notes include a link out to a good blog article that explains the problem. The major feature in this release is the ability to pass up to five string parameters to custom template replacement formulas. Let’s take a quick look at how that works.

I’m going to use a simple formula we added to our JDF Workflow Foundation (JWF) product as an example. JWF is our server framework for building JDF devices and controllers. It uses Fluent JDF’s template support to produce responses to standard JMF command and queries. Because it supports hosting multiple devices or controllers in a single process and JDF requires unique device ids, device descriptions, JMF URLs and other similar things per device or controller, we needed a way to pass those elements to template replacements. Here’s a fragment of XML we need to generate in a response that includes information about the current device.

<Device DescriptiveName="my device name" DeviceID="my device id" .../>

If you wanted to turn that into a template, you’d change it to look like this:

<Device DescriptiveName="[:deviceName:]" DeviceID="[:deviceId:]" .../>

And perform the replacement something like this:

var ticket = Ticket.CreateFromTemplate(templateFileName).With()
    .NameValue("deviceName", JwfLibrary.Settings.ServerSettings.DeviceSettings["my device id"].Name)
    .NameValue("deviceId", "my device id")

Pretty simple right? Now imagine that you are writing dozens of message handlers that need the current device name or other data that is looked up based on the device id. Seems kind of tedious to look it up every time and pass it as a name-value. Well, parameterized custom functions solve the problem rather nicely. First, you setup the formula as shown in the next code fragment:

//Could use an anonymous function (Func<string, string>).  This example
//will use a static function declared somewhere in the code
public static string ConfiguredDeviceName(string deviceId) {
    if (deviceId == null) {
        return JwfLibrary.Settings.ServerSettings.DefaultDeviceSettings != null ? JwfLibrary.Settings.ServerSettings.DefaultDeviceSettings.Name : null;
    if (JwfLibrary.Settings.ServerSettings.DeviceSettings.ContainsKey(deviceId)) {
        return JwfLibrary.Settings.ServerSettings.DeviceSettings[deviceId].Name;
    return null;

//Here's the code to configure the function above as a 
//global custom template replacement formula
    .CustomFormula("configuredDeviceName", deviceId => CustomFormulas.ConfiguredDeviceName(deviceId));

Once you have the configuration in place, you need to change the template to use your custom formula and pass it the parameter:

<Device DescriptiveName="[:deviceName=configuredDeviceName(deviceId):]" DeviceID="[:deviceId:]" .../>

Now the code only needs to pass the device ID as shown below:

var ticket = Ticket.CreateFromTemplate(templateFileName).With()
    .NameValue("deviceId", "my device id")

Admittedly, we’re not saving a huge amount of code here but we are gaining considerable re-use. The nice thing is the template now takes care of the device name lookup for the device. The code only has to pass what the template can’t know until replacement time. I would not suggest using parameterized custom formulas when only one template will use the replacement. However, when you have something that needs parameters and will be used over and over again, a parameterized custom formula can make your life simpler.


Written by Tom Cabanski

August 23, 2011 at 2:54 pm

Posted in FluentJDF

One Response

Subscribe to comments with RSS.

  1. Are you still working on this project, or has it gone to the wayside?


    June 12, 2013 at 7:13 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: