eclipse-emfemfxcore

How to define a map in Xcore


According to the EMF FAQ, it is possible to create a Map in EMF:

An EMap is basically a List of java.util.Map$Entry instances. Therefore to create a Map you need to first model your map entry by following these steps:

  1. Create an EClass with the name [Type1]To[Type2]Map where [Type1] represents the key's type and the [Type2] represents the value's type.
  2. Set the Instance Class Name property of the newly created EClass to java.util.Map$Entry.
  3. Create an EAttribute or EReference named "key" and set the EDataType or EClass for it.
  4. Create an EAttribute or EReference called "value" and set the EDataType or EClass for it.

Now, when you create an EReference somewhere that uses this map entry class as its EClass, the EMF code generator will detect this special case and generate a properly typed EMap getter/setter for you instead of a normal EList getter/setter.

Can I use this with Xcore models? I am not sure whether step #2 is doable in Xcore or whether it supports maps at all.


Solution

  • For me this works.

    DataPoints.xcore:

    ...
    class KeyValuePair wraps java.util.Map$Entry {
        String key
        String value
    }
    
    class KeyValueList {
        contains KeyValuePair[] entries
    }
    

    The above results in a KeyValueListImpl class with a getEntries method that looks like this:

    public EMap<String, String> getEntries() {
        if (entries == null) {
            entries = new EcoreEMap<String,String>(DataPointsPackage.Literals.KEY_VALUE_PAIR, KeyValuePairImpl.class, this, DataPointsPackage.KEY_VALUE_LIST__ENTRIES);
        }
        return entries;
    }