We don’t need no MxModelReflection

By 4 June 2014 Mendix 5 Comments

The Mx Model Reflection module is a technical component from the Mendix App Store that is used in almost every Mendix project. The main reason for this is that other well-known modules from the app store make use of MxModelReflection, such as the ExcelImporter, ExcelExporter, FixedLengthExporter, and DBReplication modules.

It is a very useful component, but what does the MxModelReflection module actually do?

  • It allows certain users of the Mendix application to see the module names used in the model.
  • Users can select for which modules they want to load the entity information and microflows.
  • It adds tables to your database that will save this information.
  • By using the objects that represent other entities, there is a meta-model at run-time.
  • The meta-model can be used to configure exports and imports of data at run-time, like with the ExcelImporter.

This is very handy! But there are some potential weaknesses:

  • When adding this module, you also will add a number of tables to your application database, which is not very elegant. Also, companies may have architectural policy to mimimize the amount of changes to the database for applications that are already in production. So adding new tables that don’t contain business data is sometimes undesired.
  • It poses a security risk by allowing some users to see (parts of the) source model of the application. This information could give attackers insight in weaknesses that your application might contain.
  • You need to sync the model reflection when you changed something in your model. In every environment (DTAP)… If you forget this on any environment, it can break important functionality, e.g. the ExcelImporter will throw ugly error messages at the user if the model reflection is not synced properly.

In this post I will show a way to get meta-information of your application without using the MxModelReflection module. This will give developers more flexibility and more control over the information shown in the user interface. Also it doesn’t add any tables to the database!

I will create the following Java actions to get the information we need.

java actions

I use the following domain model. Note that the entities are non-persistent, so no database tables will be created:

 

The first Java Action GetAllEntityNames takes no parameters, and returns a list of Entity objects.

Note the use of Core.getMetaObjects(). This part of the Mendix Java API will result in a list of all the entities in the application model. Each entity is represented by an object of the IMetaObject interface. See the Mendix Apidocs for more info.

Use this Java action in a datasource microflow for selecting a single entity, like this:

Microflow DS_AllEntityNames

Microflow DS_AllEntityNames

Of course, you can customize this all you want: maybe you only want to have the entity names of a certain module: then you could just filter the list in the microflow (or change the Java code).

Now, if the user has selected an entity, you might want go one level deeper: the members. Members of an entity consist of primitive members (attributes) and assocations (references and reference sets). To get the associations that a certain entity has, I created this Java action GetAssociationsOfEntity, which takes 1 string parameter (entityName), and returns a list of Assocation objects:

Note the call to Core.getMetaObject(entityName) to get the IMetaObject for the given entity. By calling getMetaAssociationsParent() on the IMetaObject, we get a list of assocations owned by that entity.

Get the members is very similar to the associations. Calling getMetaPrimitives() on the IMetaObject will get a list of its attributes. This Java action GetAttributesOfEntity will take 1 string parameter (entityName), and will return a list of Attribute objects:

By using these Java actions, you can build your own re-usable modules without having to depend on MxModelReflection!

If you have any questions, remarks or suggestions, feel free to contact me or leave a reply below.

5 Comments

  • Rolf says:

    Bart,

    Is er ook een manier om middels een java action de actuele modulenaam en microflownaam uit de context te halen?

    Met vriendelijke groet,

    Rolf

  • Bert Koot says:

    Hi Bart,

    I missed the update. I found the function getActionName() but the Stack seems to be empty. What is wrong with my Java code:

    public class GetMicroflowName extends CustomJavaAction
    {
    public GetMicroflowName(IContext context)
    {
    super(context);
    }

    @Override
    public String executeAction() throws Exception
    {
    // BEGIN USER CODE
    Stack<CoreAction> actionStack = this.getContext().getActionStack();
    String naamMF ;

    if (actionStack.isEmpty()) {
    CoreAction laatsteAction = actionStack.peek();

    naamMF = laatsteAction.getActionName();
    } else {
    naamMF = “Unknown.”;
    }

    return naamMF ;

    // END USER CODE
    }

    /**
    * Returns a string representation of this action
    */
    @Override
    public String toString()
    {
    return “GetMicroflowName”;
    }

    }

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.