If you would like to upgrade to a newer long-term support version of Studio Pro, see Moving from Mendix Studio Pro 8 to 9.
Use the Java API
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 teaches you how to do the following:
- Execute microflows and commit objects
- Copy FileDocuments
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.
First, we will introduce a helper method that we will place in the section BEGIN EXTRA CODE and END EXTRA CODE. The method 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.
private static String formatString(String inputString, IContext context) throws CoreException
{
	Map<String,Object> parameters = new HashMap<String, Object>();
	parameters.put("inputString", inputString);
	String formattedString = (String) Core.execute(context, "MyFirstModule.FormatString", parameters);
	return formattedString;
}| Line | Description | 
|---|---|
| 1 | In this line, the method is defined. We'll need the input string, and we'll also need the context in which this microflow is executed. | 
| 3 | To pass parameters to a microflow, a map is used. A HashMapis being used here. The map consists of a string key, which holds the name of the parameter in the microflow, and an object value, which holds the value of the parameter. | 
| 4 | An entry is put in the HashMapcontaining the name of the parameter (inputString) and the value of the string. | 
| 5 | The core method executed is called. This executes the microflow. It has the following parameters: the context, the module name and microflow name, and the parameter map. The method always returns an object which can be cast to the type that the microflow returns, in this case a string. | 
| 6 | The microflow return value is returned by our helper method. | 
Once we have the value of the formatted string, we are going to store this in an object. This is the code between BEGIN USER CODE and END USER CODE.
String formattedString = formatString("this is an unformatted string", context);
testObject.setTestString(context, formattedString);
Core.commit(context, testObject.getMendixObject());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)
		.execute(context);
}| Line | Description | 
|---|---|
| 1 | The help method is defined here. Its parameters are the GenericObjectproxy object and the context in which we are performing the query. | 
| 3 | The name of the Attachmententity is defined in aStringby copying theentityNamefrom theAttachmentproxy class. | 
| 4 | The name of the relation between the Attachmententity andGenericObjectentity is defined in aStringby getting it from theMemberNamesenumeration of theAttachmentproxy class and callingtoString()on it. | 
| 5 | The ID of the currentObjectis retrieved from theGenericObjectproxy object methodgetGUID();. | 
| 6 | We construct a query on the Attachmententity that is related to the object withcurrentid. The prefix$denotes that this is a variable, which can later be safely inserted using theCore.createXPathQueryAPI. | 
| 7 | The CoremethodcreateXPathQueryis used to create a query. This query fill the variablecurrentidwith 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 ofIMendixObjects) 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);
	newAttachment.setAttachment_GenericObject(destinationObject);
	Core.storeFileDocumentContent(context, newAttachment.getMendixObject(), (String) iMendixObject.getValue(system.proxies.Document.MemberNames.Name.toString()),  inputStream);
}| Line | Description | 
|---|---|
| 1 | Declaring an Attachmentvariable namednewAttachment. | 
| 2 | Declaring an InputStreamvariable namedinputStream. | 
| 3 | Starting to loop through a list of IMendixObjectsreturned by our helper method. | 
| 5 | Here the CoremethodgetFileDocumentContent()is used, passing the retrievedAttachmentobject to retrieve theInputStreamof the actual file. | 
| 6 | A new Attachmentis instanced. | 
| 7 | The relation to the destination object is set on our new Attachment. | 
| 8 | The content of the retrieved InputStreamis stored in our newAttachmentusing theCoremethodstoreFileDocumentContent(). This method takes a number of parameters: the context in which you are performing this store; theIMendixObjectof theAttachmentproxy, which is retrieved by callinggetMendixObject()on theAttachmentproxy; the file name of theFileDocumentin string format, which is copied from the attachment you're copying from by using thegetValue()method passing the member name you wish to know the value of; and theInputStreamcontaining the actual file. | 
After this, all Attachments belonging to one GenericObject have been copied to another.