Сгенерировать метод, возвращающий EMF Unmodifiable list - PullRequest
2 голосов
/ 12 июня 2009

Я использую EMF через аннотированный Java-код следующим образом

/**
 * 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);

После создания файлов ecore и genmodel из этого аннотированного интерфейса и после генерации кода метод getEntityTypes изменяется следующим образом:

public EList<String> getEntityTypes();

В целях инкапсуляции я хочу, чтобы этот EList не изменялся, поэтому код клиентского интерфейса может изменять список только с помощью методов добавления и удаления.

Есть ли какой-нибудь чистый способ сделать это, например, модифицируя аннотацию Java или файл genmodel, чтобы сообщить генератору генерировать код, возвращающий неизменяемый список? (Я не смог найти это после поиска в Google ...)

Как вы справляетесь с такими ситуациями?

Заранее спасибо

Маню

1 Ответ

4 голосов
/ 13 июня 2009

Вам необходимо изменить сгенерированный класс "Impl", чтобы он выглядел следующим образом:

/**
 * <!-- 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);
}

Обратите внимание, что я сделал следующее:

  1. Изменены имя и видимость сгенерированного метода getEntityTypes для getEntityTypesGen и private соответственно. EMF не будет связываться с видимостью, когда восстанавливает этот метод. Кроме того, EMF будет продолжать генерировать этот суффиксированный метод «Gen», даже если у нас теперь есть несгенерированный метод getEntityTypes.
  2. Добавлен открытый не сгенерированный метод getEntityTypes, который оборачивает результат реализации по умолчанию в неизменяемый EList.
  3. Реализованы (и изменены на не сгенерированные) методы add / removeEntityType путем делегирования сгенерированному методу getEntityTypesGen (результат которого по-прежнему можно изменять).

Лично я бы не рекомендовал такой подход. EMF обычно возвращает изменяемые списки для многозначных ссылок, которые клиенты должны изменить, чтобы добавить или удалить элементы. EMF будет лениво создавать пустой список по мере необходимости, что делает его более понятным интерфейсом (не нужно добавлять / удалять методы) и приятным API (пользователь имеет полную мощь API списка в своих руках, а не просто добавляет / удаляет) что вы предоставляете).

...