--- title: "Using the Mendix Runtime Java API" url: /refguide10/java-api-tutorial/ weight: 40 description: "Describes how to add a Java action, edit it in Eclipse, and call it from a microflow." --- ## Introduction This tutorial contains some examples of how to use the [Mendix Runtime Java API](/apidocs-mxsdk/apidocs/runtime-api-10/). The tutorial assumes that you have some basic Java and Mendix modeling knowledge. To avoid cluttering the tutorial, only the relevant code is 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 is 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 are working will determine whether you have these rights and can perform that action. This tutorial teaches you how to do the following: * Execute microflows and commit objects * Copy FileDocuments ## Executing Microflows and Committing Objects Sometimes you want to execute a microflow in a Java Action. This section explains 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, you will 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: ```java 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. ```java import static myfirstmodule.proxies.microflows.Microflows.formatString; … public class … … String formattedString = formatString(getContext(), "this is an unformatted string"); … ``` Once you have the value of the formatted string, you 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. ```java import static myfirstmodule.proxies.microflows.Microflows.formatString; … public class … … // BEGIN USER CODE String formattedString = formatString(getContext(), "this is an unformatted string"); testObject.setTestString(context, formattedString); Core.commit(context, testObject.getMendixObject()); // END USER CODE … ``` ## Copying FileDocuments A **FileDocument** is a system module entity that holds the content of a file (for example, a text file or an Excel sheet). For this case, you 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`. You copy the `Attachments` from one `GenericObject` to another so that they can be independently modified later. In the Java Action, you pass two `GenericObjects` as parameters, a `sourceObject` and a `destinationObject`. You will also copy all the `Attachments` from the `sourceObject` to the `destinationObject`. To be able to copy `Attachments`, you 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. ```java public static List 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) .execute(context); } ``` | Line | Description | | --- | --- | | 1 | The help method is defined here. Its parameters are the `GenericObject` proxy object and the context in which you 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 | You 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 fills the variable `currentid` with the ID of the current object. You pass the context in which you 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 the query, these are taken into account. View the JavaDoc for more information. Now that you have a way to get all the `Attachments` from a certain `GenericObject`, you can start copying them. This is the code between `BEGIN USER CODE` and `END USER CODE`: ```java Attachment newAttachment; InputStream inputStream; for (IMendixObject iMendixObject: getAttachments(sourceObject, context)) { inputStream = Core.getFileDocumentContent(iMendixObject); newAttachment = Attachment.create(context); newAttachment.setAttachment_GenericObject(destinationObject); 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 the `Core` method `getFileDocumentContent()` is used, passing the 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 are 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` are copied to another. ## Read More * [Extending Your Application with Custom Java](/refguide10/extending-your-application-with-custom-java/)