Сопоставьте коллекцию с параметром с mapstruct
Чтобы сопоставить определенный объект с mapstruct, мне нужна специальная пост-обработка, для которой необходим дополнительный параметр:
@Mapper
public abstract class AlertConfigActionMapper {
@Mappings({ @Mapping(target = "label", ignore = true)})
public abstract AlertConfigActionTO map (AlertConfigAction action, Locale userLanguage);
@AfterMapping
public void setLabel (AlertConfigAction action, @MappingTarget AlertConfigActionTO to, Locale userLanguage) {
for (AlertConfigActionLabel label : action.getAlertConfigActionLabels()) {
if (label.getLanguage().equals(userLanguage)) {
to.setLabel(label.getLabel());
break;
} else if (label.getLanguage().equals(Locale.ENGLISH)) {
to.setLabel(label.getLabel());
}
}
}
}
Это работает отлично.
Проблема начинается, когда я добавляю следующий метод к этому картографу:
public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, Locale userLanguage);
Мне нужно передать этот параметр (userLanguage), но mapstruct, похоже, "сломается" в этом случае: я генерирую следующий код для этой части (что естественно дает ошибку компиляции):
@Override
public List<AlertConfigActionTO> mapList(List<AlertConfigAction> actions, Locale userLanguage) {
if ( actions == null && userLanguage == null ) {
return null;
}
List<AlertConfigActionTO> list = new List<AlertConfigActionTO>();
return list;
}
Я уверен, что это связано с параметром, так как если я удалю его (из всех методов сопоставления), тогда метод mapList будет сгенерирован правильно.
Что нужно сделать для разрешения пользовательских параметров в этом случае?
Ответы
Ответ 1
То, что вы описали, пока невозможно. Не могли бы вы открыть запрос функции в нашем отслеживании проблем? Мы должны предоставлять средства обозначения параметров как своего рода "контекста", который передается по стеку вызовов.
В настоящее время вы можете взглянуть на использование ThreadLocal
, которое вы установили перед вызовом процедуры сопоставления и которую вы получаете при настройке после сопоставления. Это не изящно - и вам нужно очистить локальную нить, чтобы избежать утечек памяти, но это должно сделать трюк.
Ответ 2
Я не думаю, что это возможно. По крайней мере, не так. Проблема в том, что вы готовите интерфейс/абстрактный класс, а отдых выполняется движком. И этот движок ожидает методов с одним параметром... Есть декораторы, но они идут одинаково. Я бы попытался ввести язык. Создайте bean, отметьте его как область сеанса и узнайте. С помощью Spring вы должны использовать ScopedProxyMode для этого... Не знаете, как это происходит с CDI.
Другой вариант более обходчив, тогда решение - может быть, AlertConfigAction
может передать эту информацию?
Ответ 3
Я знаю, что этот вопрос довольно старый, но я столкнулся с этой проблемой, и начиная с версии 1.2 mapstruct, вы можете решить ее, используя @Context
Поэтому объявление отображения списка должно быть таким:
public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, @Context Locale userLanguage);
Теперь вам просто необходимо добавить еще одно неабстрактное отображение:
public AlertConfigActionTO mapConcrete (AlertConfigAction action, @Context Locale userLanguage){
return map (action, userLanguage);
}