Retrieve translated enumaraion with Java action

2
I want to retrieve the translated value of an enumeration based on the enumeration as a string and the language. This has been asked before in these two posts: https://community.mendix.com/link/questions/2460 https://community.mendix.com/link/questions/8606 Now I got the first one working. If I pass a Mendix object, the enumeration I want to translate and the language I am able to create the translated string and pass it back. But the second one I did not get to work. I do not always have an Enitity to pass so I only want to pass the enumeration as a string. But everytime I try to transform the string to a Mendix enumeration it always fails with a nullpointer. Lets say we have this enumeration: MyFirstModule.testenumeration.optie_1 (so module,name of the enum and the value). How to I transform that to a Mendix Enum? In the community commons you have the EnumartionFromString where you need to pass the class and the string. But creating the class seems to be the problem. Whatever I feed as string to get the class it always returns empty. What am I doing wrong here? And imho Mendix should fix this so that I do not need Java for this. It is in the idear forum already  ( https://community.mendix.com/link/ideas/1715 ) Regards, Ronald
asked
1 answers
5

The following code works in a Java action that takes two strings as parameters (the enumeration and the language code) and returns the translated caption.

// BEGIN USER CODE
try {
	final String[] proxyPath = Enumeration.split("\\.");
	if (proxyPath.length != 3) {
		throw new MendixRuntimeException("Enumeration should be in the "
				+ "format module.enumeration.value`.");
	}
	final String proxyClassName = String.format("%s.proxies.%s",
			proxyPath[0].toLowerCase(), proxyPath[1]);
	final Class<?> proxyClass = Class.forName(proxyClassName);
	if (!proxyClass.isEnum()) {
		throw new MendixRuntimeException("Given enumeration is a "
				+ "class, but not an enumeration.");
	}
	final Field enumField = proxyClass.getField(proxyPath[2]);
	final Method captionMethod = proxyClass.getMethod("getCaption",
			String.class);
	return (String) captionMethod.invoke(enumField.get(null),
			LanguageCode);
} catch (ClassNotFoundException cnfe) {
	throw new MendixRuntimeException("Cannot find given enumeration.",
			cnfe);
} catch (NoSuchFieldException nsfe) {
	throw new MendixRuntimeException("Can find enumeration, but not "
			+ "the requested value.", nsfe);
} catch (NoSuchMethodException nsme) {
	throw new MendixRuntimeException("Can find enumeration, but not "
			+ "the getCaption method.", nsme);
} catch (SecurityException se) {
	throw new MendixRuntimeException("Cannot access enumeration.", se);
} catch (Exception e) {
	throw new MendixRuntimeException("Unexpected error", e);
}
// END USER CODE

This is essentially an adapted version of the second answer you linked to. The following happens:

  1. The enumeration name (something like “MyModule.MyEnumeration.MyValue”) is translated to be “mymodule.proxies.MyEnumeration”, which is the proxy class that Mendix generates for the enumeration.
  2. The given value (“MyValue” in the example) is created and the “getCaption” method is called on it, passing the given language code parameter.

The above uses basic Java reflection, which can trigger a lot of errors, hence the error handling. This should result in somewhat readable errors in the console.

 

For completeness, this is the full Java action code (you can deduce the parameter names and types from this):

// This file was generated by Mendix Studio Pro.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
// Special characters, e.g., é, ö, à, etc. are supported in comments.

package translatedenumerationjava.actions;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.mendix.systemwideinterfaces.MendixRuntimeException;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.webui.CustomJavaAction;

public class JA_GetEnumerationCaption extends CustomJavaAction<java.lang.String>
{
	private java.lang.String Enumeration;
	private java.lang.String LanguageCode;

	public JA_GetEnumerationCaption(IContext context, java.lang.String Enumeration, java.lang.String LanguageCode)
	{
		super(context);
		this.Enumeration = Enumeration;
		this.LanguageCode = LanguageCode;
	}

	@java.lang.Override
	public java.lang.String executeAction() throws Exception
	{
		// BEGIN USER CODE
		try {
			final String[] proxyPath = Enumeration.split("\\.");
			if (proxyPath.length != 3) {
				throw new MendixRuntimeException("Enumeration should be in the "
						+ "format module.enumeration.value`.");
			}
			final String proxyClassName = String.format("%s.proxies.%s",
					proxyPath[0].toLowerCase(), proxyPath[1]);
			final Class<?> proxyClass = Class.forName(proxyClassName);
			if (!proxyClass.isEnum()) {
				throw new MendixRuntimeException("Given enumeration is a "
						+ "class, but not an enumeration.");
			}
			final Field enumField = proxyClass.getField(proxyPath[2]);
			final Method captionMethod = proxyClass.getMethod("getCaption",
					String.class);
			return (String) captionMethod.invoke(enumField.get(null),
					LanguageCode);
		} catch (ClassNotFoundException cnfe) {
			throw new MendixRuntimeException("Cannot find given enumeration.",
					cnfe);
		} catch (NoSuchFieldException nsfe) {
			throw new MendixRuntimeException("Can find enumeration, but not "
					+ "the requested value.", nsfe);
		} catch (NoSuchMethodException nsme) {
			throw new MendixRuntimeException("Can find enumeration, but not "
					+ "the getCaption method.", nsme);
		} catch (SecurityException se) {
			throw new MendixRuntimeException("Cannot access enumeration.", se);
		} catch (Exception e) {
			throw new MendixRuntimeException("Unexpected error", e);
		}
		// END USER CODE
	}

	/**
	 * Returns a string representation of this action
	 */
	@java.lang.Override
	public java.lang.String toString()
	{
		return "JA_GetEnumerationCaption";
	}

	// BEGIN EXTRA CODE
	// END EXTRA CODE
}

And a screenshot of calling the action:

answered