Use the Java API

Last update: Edit

1 Introduction

This tutorial contains some examples of how to use the Java API provided by the Mendix Runtime. The tutorial assumes you have basic Java knowledge as well as basic Mendix modeling knowledge.

To avoid cluttering the tutorial, only the relevant code will be shown, not the entire code generated by Studio Pro itself. Recreating the cases yourself and then trying to execute the actions is recommended.

When you look at these examples, often an IContext will be used. This is the context in which something can be done. For example, it holds access rights to objects. If you do something with an object that requires access rights, the context in which you’re working will determine if you have these rights and can perform that action.

This how-to will teach you how to do the following:

  • Execute microflows and commit objects
  • Copy FileDocuments

2 Executing Microflows and Committing Objects

There are cases in which you’d like to execute a microflow in a Java Action. This case will explain how to do this, including how to pass parameters and obtain the return value. Additionally, the result will be saved in an object and the object will be committed.

In this example, we want to execute a microflow that is called FormatString and is part of the MyFirstModule module. It has an input parameter called inputString, which is a string. Its return value is also a string, which contains the formatted string.

You can invoke the microflow directly using its proxy:

myfirstmodule.proxies.microflows.Microflows.formatString(getContext(), "this is an unformatted string");

But you can make your code more readable by first importing the proxy before the class declaration, and then referring to the microflow directly.

import static myfirstmodule.proxies.microflows.Microflows.formatString;
public class …
String formattedString = formatString(getContext(), "this is an unformatted string");

Once we have the value of the formatted string, we can store this in an object and then commit the object.

The code below formats the string "this is an unformatted string" using the microflow MyFirstModule.FormatString, stores it in the TestString attribute of an object of entity testObject, and then commits the object. The code is placed between BEGIN USER CODE and END USER CODE of the Java action.

import static myfirstmodule.proxies.microflows.Microflows.formatString;
public class …
String formattedString = formatString(getContext(), "this is an unformatted string");
testObject.setTestString(context, formattedString);
Core.commit(context, testObject.getMendixObject());

3 Copying FileDocuments

A FileDocument is a system module entity that holds the content of a file (for example, a text file or Excel sheet). For this case, we assume we have an entity called GenericObject that has a relation with an Attachment entity. The Attachment entity inherits from FileDocument. One GenericObject can have multiple Attachments. We’d like to copy the Attachments from one GenericObject to another so that they can be independently modified later.

In the Java Action, we pass two GenericObjects as parameters, a sourceObject, and a destinationObject. We are going to copy all the Attachments from the sourceObject to the destinationObject.

To be able to copy Attachments, we will first need to retrieve them. For this purpose we introduce the extra method called getAttachments, which returns a list of IMendixObjects. This code is put between BEGIN EXTRA CODE and END EXTRA CODE in the Java action.

public static List<IMendixObject> getAttachments(GenericObject object, IContext context) throws CoreException
	String attachmentEntityName = Attachment.entityName;
	String relationName = Attachment.MemberNames.Attachment_GenericObject.toString();
	String currentObjectID = object.getGUID();
	String query = String.format("//%s[%s=$currentid]", attachmentEntityName, relationName);
	return Core.createXPathQuery(query)
		.setVariable("currentid", currentObjectID)
Line Description
1 The help method is defined here. Its parameters are the GenericObject proxy object and the context in which we are performing the query.
3 The name of the Attachment entity is defined in a String by copying the entityName from the Attachment proxy class.
4 The name of the relation between the Attachment entity and GenericObject entity is defined in a String by getting it from the MemberNames enumeration of the Attachment proxy class and calling toString() on it.
5 The ID of the currentObject is retrieved from the GenericObject proxy object method getGUID();.
6 We construct a query on the Attachment entity that is related to the object with currentid. The prefix $ denotes that this is a variable, which can later be safely inserted using the Core.createXPathQuery API.
7 The Core method createXPathQuery is used to create a query. This query fill the variable currentid with the ID of the current object. We pass the context in which we want the query to be executed. After this its result (a list of IMendixObjects) is immediately returned.

Using the createXPathQuery API, you can also enter conditions, such as a sorting mechanism and a maximum number of objects returned. After executing, these are taken into account. View the JavaDoc for more information.

Now that we have a way to get all the Attachments from a certain GenericObject, we can start copying them.

This is the code between BEGIN USER CODE and END USER CODE:

Attachment newAttachment;
InputStream inputStream;
for (IMendixObject iMendixObject: getAttachments(sourceObject, context))
	inputStream = Core.getFileDocumentContent(iMendixObject);
	newAttachment = Attachment.create(context);
	Core.storeFileDocumentContent(context, newAttachment.getMendixObject(), (String) iMendixObject.getValue(system.proxies.Document.MemberNames.Name.toString()),  inputStream);
Line Description
1 Declaring an Attachment variable named newAttachment.
2 Declaring an InputStream variable named inputStream.
3 Starting to loop through a list of IMendixObjects returned by our helper method.
5 Here we use the Core method getFileDocumentContent(), passing our retrieved Attachment object to retrieve the InputStream of the actual file.
6 A new Attachment is instanced.
7 The relation to the destination object is set on our new Attachment.
8 The content of the retrieved InputStream is stored in our new Attachment using the Core method storeFileDocumentContent(). This method takes a number of parameters: the context in which you are performing this store; the IMendixObject of the Attachment proxy, which is retrieved by calling getMendixObject() on the Attachment proxy; the file name of the FileDocument in string format, which is copied from the attachment you’re copying from by using the getValue() method passing the member name you wish to know the value of; and the InputStream containing the actual file.

After this, all Attachments belonging to one GenericObject have been copied to another.

4 Read More