Localization of calculated data

CER supports the commonplace Java class String.

Strings may be useful in the initial phases of developing your rule set; however, if your rules contain output which needs to be displayed to users in different locales, then you may need to take advantage of CER's support for localization.

The String value "Hello World" is the below example all very well for end users who read English; but what if they do not?

Figure 1. Outputting a String
<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="HelloWorldRuleSet"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">
  <Class name="HelloWorld">

    <Attribute name="greeting">
      <type>
        <javaclass name="String"/>
      </type>
      <derivation>
        <String value="Hello, world!"/>
      </derivation>
    </Attribute>

  </Class>

</RuleSet>

CER includes a curam.creole.value.Message interface which enables the conversion of a value to locale-specific String at runtime.

For a list CER expressions which can create an instance of curam.creole.value.Message, see Localizable Messages.

Now we will rewrite the HelloWorld example to be localizable:

Figure 2. Outputting a localizable Message
<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="LocalizableHelloWorldRuleSet"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">
  <Class name="HelloWorld">

    <Attribute name="greeting">
      <type>
        <!-- Use Message, not String -->
        <javaclass name="curam.creole.value.Message"/>
      </type>
      <derivation>
        <!-- Look up the value from a localizable
             property, instead of hard-coding a
             single-language String -->
        <ResourceMessage key="greeting"
          resourceBundle="curam.creole.example.HelloWorld"/>
      </derivation>
    </Attribute>

  </Class>

</RuleSet>
Figure 3. Localization of "Hello, world!" - English
# file curam/creole/example/HelloWorld_en.properties

greeting=Hello, world!
Figure 4. Localization of "Hello, world!" - French
# file curam/creole/example/HelloWorld_fr.properties

greeting=Bonjour, monde!

How will this message behave at runtime? Any code which interacts with your rule set must invoke the toLocale method on any messages, to convert them to the required Locale.

Figure 5. Interacting with the localized rule set
package curam.creole.example;

import java.util.Locale;

import junit.framework.TestCase;
import curam.creole.execution.session.RecalculationsProhibited;
import curam.creole.execution.session.Session;
import curam.creole.execution.session.Session_Factory;
import
 curam.creole.execution.session.StronglyTypedRuleObjectFactory;
import
 curam.creole.ruleclass.LocalizableHelloWorldRuleSet.impl.HelloWorld;
import
 curam.creole.ruleclass.LocalizableHelloWorldRuleSet.impl.HelloWorld_Factory;
import curam.creole.storage.inmemory.InMemoryDataStorage;
import curam.creole.value.Message;

public class TestLocalizableHelloWorld extends TestCase {

  /**
   * Runs the class as a stand-alone Java application.
   */
  public static void main(final String[] args) {

    final TestLocalizableHelloWorld testLocalizableHelloWorld =
        new TestLocalizableHelloWorld();
    testLocalizableHelloWorld.testLocalizedRuleOutput();

  }

  /**
   * A simple test case, displaying output localized into different
   * locales.
   */
  public void testLocalizedRuleOutput() {

    final Session session =
        Session_Factory.getFactory().newInstance(
            new RecalculationsProhibited(),
            new InMemoryDataStorage(
                new StronglyTypedRuleObjectFactory()));

    final HelloWorld helloWorld =
        HelloWorld_Factory.getFactory().newInstance(session);

    // returns a Message, not a String
    final Message greeting = helloWorld.greeting().getValue();

    // to decode the message, we need to use the user's locale
    final String greetingEnglish =
        greeting.toLocale(Locale.ENGLISH);
    final String greetingFrench = greeting.toLocale(Locale.FRENCH);

    System.out.println(greetingEnglish);
    System.out.println(greetingFrench);

    assertEquals("Hello, world!", greetingEnglish);
    assertEquals("Bonjour, monde!", greetingFrench);
  }

}

If used within a localizable message, the following data types are formatted at runtime in a locale-aware way:

All other objects are displayed using their toString method.