tags:

views:

202

answers:

1

Hi,

I am using EMF through annotated Java code as following

    /**
 * Adds the given type to this filter. Has no effect if the given type
 * already belongs to this filter.
 * 
 * @param type
 *            the type to add
 * @model
 */
public void addEntityType(String type);

/**
 * Returns the list of types belonging to this filter. Types are identified
 * by there name.
 * 
 * @return the list of types for this entity type filter
 * 
 * @model
 */
public List<String> getEntityTypes();

/**
 * Removes the given type from this filter. Has no effect if the given type
 * doesn't belong to this filter.
 * 
 * @param type
 *            the type to remove
 * @model
 */
public void removeEntityType(String type);

After creating ecore and genmodel files from this annotated interface, and after generating code the getEntityTypes method is modified as following:

public EList<String> getEntityTypes();

For encapsulation purpose I want this EList to be unmodifiable, thus the interface client's code can only modify the list through add and remove methods.

Is there any clean way to do that I.e modifying Java annotation or the genmodel file to tell the generator to generate code returning unmodifiable list ? (I was unable to find that after googling ...)

How do you manage such situations ?

Thanks in advance

Manu

+3  A: 

You would need to modify your generated "Impl" class to look like this:

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 */
private EList<String> getEntityTypesGen() {
    if (entityTypes == null) {
        entityTypes = new EDataTypeUniqueEList<String>(String.class, 
            this, NsPackage.THINGY__ENTITY_TYPES);
    }
    return entityTypes;
}

public EList<String> getEntityTypes() {
    return ECollections.unmodifiableEList(getEntityTypesGen());
}

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated NOT
 */
public void addEntityType(String type) {
    getEntityTypesGen().add(type);
}

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated NOT
 */
public void removeEntityType(String type) {
    getEntityTypesGen().remove(type);
}

Note that I've done the following:

  1. Changed the generated getEntityTypes method's name and visibility to getEntityTypesGen and private, respectively. EMF won't mess with the visibility when it regenerates this method. Also, EMF will continue to generate this "Gen" suffixed method even though we now have a non-generated getEntityTypes method.
  2. Added a public, non-generated getEntityTypes method that wraps the default implementation's result in an unmodifiable EList.
  3. Implemented (and changed to non-generated) the add/removeEntityType methods by delegating to the generated getEntityTypesGen method (whose result is still modifiable).

Personally, though, I wouldn't recommend this approach. EMF generally returns modifiable lists for multi-valued references which clients are supposed to modify in order to add or remove items. EMF will lazily create an empty list as needed, so it makes for a cleaner interface (don't need add/remove methods) and a nice API (user has full power of the list API at their fingertips instead of just the add/remove that you provide).

Mark