Please enable JavaScript to view this site.

Altova MapForce 2020 Enterprise Edition

The MapForce Function File (.mff) is a configuration file in XML format that makes it possible to adapt functions from custom Java, C#, or C++ libraries into MapForce, so that they appear in the Libraries window. An .mff file essentially mediates between your custom libraries and MapForce, and it must be configured to specify a) the interfaces to the custom functions and b) where the implementation can be found in generated code. This topic provides instructions on how to do this.

 

Note the following:

 

The *.mff library files must be valid against the following schema: ..\Program Files\MapForceLibraries\mff.xsd. The mff.xsd schema defines the custom library configuration and is for internal use only. Altova GmbH retains the right to change this file format with new releases.

It is possible to define only one C#, C++, or Java class per .mff file.

 

The following code listing illustrates a sample .mff file for C++:

 

<?xml version="1.0" encoding="UTF-8"?>
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
  <implementations>
    <implementation language="cpp">
        <setting name="namespace" value="mylib"/>
        <setting name="class" value="Greetings"/>
        <setting name="path" value="C:\Libraries\cpp"/>
        <setting name="include" value="Greetings.h"/>
        <setting name="source" value="Greetings.cpp"/>
    </implementation>
  </implementations>
  <group name="greetings">
    <component name="sayhello">
        <sources>
          <datapoint name="ismorning" type="xs:boolean"/>
        </sources>
        <targets>
          <datapoint name="result" type="xs:string"/>
        </targets>
        <implementations>
          <implementation language="cpp">
              <function name="SayHello"/>
          </implementation>
        </implementations>
        <description>
          <short>result = sayhello(ismorning)</short>
          <long>Returns "Good morning" or "Good day", depending on the input parameter.</long>
        </description>
    </component>
  </group>
</mapping>

 

The image below shows a custom .mff file may look after import into MapForce. Notice that the custom library "mylib" appears as a library entry (sorted alphabetically), containing the "sayhello" string function.

mf_custom_lib

The steps needed to adapt the mff file to suit your needs are described below.

 

Configuring the library name

The library name is found in the .mff file line shown below. By convention, library names are written in lowercase in MapForce; however, you can also use uppercase letters.

 

<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">

 

In the sample above, the entry that will appear in the Libraries window will be called mylib.

 

Configuring the language implementations

The <implementations> element is a mandatory element which specifies which languages your library should support, and it must be added as child of <mapping>, for example:

 

<!-- ... -->
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
  <implementations>

    <implementation language="cpp">
        <setting name="namespace" value="mylib"/>
        <setting name="class" value="Greetings"/>
        <setting name="path" value="C:\Libraries\cpp"/>
        <setting name="include" value="Greetings.h"/>
        <setting name="source" value="Greetings.cpp"/>
    </implementation>
  </implementations>
<!-- ... -->

 

The settings within each <implementation> allow the generated code to call the specific functions defined in Java, C++ or C#.

 

An .mff file can be written so that it targets more than one programming language. In this case, every additional language must contain an additional <implementation> element. The specific settings for each programming language are discussed below.

Java library reference

<!-- ... -->
<implementation language="java">
  <setting name="package" value="com.hello.functions"/>
  <setting name="class" value="Greetings"/>
</implementation>
<!-- ... -->

 

It is important for the generated code to be able to find your Greetings.class file. Therefore, make sure that a reference to your class has been added to the Java class path.

C# library reference

<!-- ... -->
    <implementation language="cs">
        <setting name="namespace" value="MyLibrary" />
        <setting name="class" value="Greetings" />
        <setting name="reference" value="C:\Libraries\cs\MyLibrary\bin\debug\MyLibrary.dll" />
    </implementation>
<!-- ... -->

 

For C#, it is important that the namespace in the code corresponds to the namespace defined in the .mff file (in the code listing above, the namespace is MyLibrary). The same is true for the class name (in the code listing above, the class name is Greetings). The third setting, reference, provides the path of the dll that is to be linked to the generated code.

C++ library reference

<!-- ... -->
  <implementation language="cpp">
        <setting name="namespace" value="MyLibrary"/>
        <setting name="class" value="Greetings"/>
        <setting name="path" value="C:\Libraries\cpp"/>
        <setting name="include" value="Greetings.h"/>
        <setting name="source" value="Greetings.cpp"/>
  </implementation>
<!-- ... -->

 

For C++, note the following:

 

namespace is the namespace in which your Greetings class will be defined. It must be equal to the library attribute in mapping element.

path is the path in which the include and the source files are to be found.

When code for a mapping is generated, the include and source files will be copied to the directory targetdir/libraryname (defined when selecting the menu command File | Generate code in | C++) and included in the project file.

 

All the include files you supply will be included in the generated algorithm.

 

Adding a component

In the Libraries window of the MapForce graphics user interface, each function appears nested under a function group, for example "string functions". In the .mff file, a function corresponds to a <component> element. Conversely, each <component> must be nested under a <group> element, for example:

 

<!-- ... -->
<group name="string functions">
  <component name="sayhello">
  <!-- ... -->
  </component>
</group>
<!-- ... -->

 

The code shown below defines a sample function (component) called sayhello.

 

<!-- ... -->
<component name="sayhello">
  <sources>
    <datapoint name="ismorning" type="xs:boolean"/>
  </sources>
  <targets>
    <datapoint name="result" type="xs:string"/>
  </targets>
  <implementations>
  <!-- ... -->
  </implementations>
  <description>
    <short>result = sayhello(ismorning)</short>
    <long>Returns "Good morning" or "Good day", depending on the input parameter.</long>
  </description>
</component>
<!-- ... -->

 

Here is how the component above would look in MapForce:

mf_custom_func

In the code listing above, a <datapoint> can be loosely defined as the input or output parameter of a function (also known as input or output connector). The type argument of the <datapoint> specifies the data type of the parameter (or the data type of the return value).

 

Only one target datapoint is allowed for each function. There is no limitation as to how many source datapoints you can define.

 

The data type of each datapoint must be one of the XML Schema types (for example, xs:string, xs:integer, etc.) These data types have to correspond to the data types of the function's parameters you defined in your Java, C++ or C# library. For the mapping of XML Schema datatypes to language types, see Data Type Mapping.

 

Functions are accompanied by short and long descriptions in the Libraries window. The short description is always shown to the right of the function name, while the long description is displayed as a tooltip when you place the mouse cursor over the short description.

mf_custom_func_description

 

Defining language implementations

We can now make a connection between the function in the Libraries window and the function in the custom Java, C# or C++ classes. This is achieved through the <implementation> element.

 

As previously stated, one function may have multiple implementation elements—one for each supported programming language. A function may be called "Hello" in Java, or "SayHello" in C++. This is why you need to specify a separate function name for each programming language. A function for each of the three programming languages might look as follows:

 

<!-- ... -->
<component name="sayhello">
<!-- ... -->
  <implementations>
    <implementation language="cs">
        <function name="HelloFunction"/>
    </implementation>
    <implementation language="java">
        <function name="Hello"/>
    </implementation>
    <implementation language="cpp">
        <function name="SayHello"/>
    </implementation>
  </implementations>
<!-- ... -->
</component>
<!-- ... -->

 

The value you supply as function name must exactly match the name of the method in the Java, C# or C++ class.

© 2020 Altova GmbH