2016-04-04 4 views
14

Um ein bestimmtes Objekt mit mapstruct Karte Ich brauche eine individuelle Nachbearbeitung, die einen zusätzlichen Parameter benötigt, es zu tun ist Arbeit:Karte eine Sammlung mit dem Parameter mit 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()); 
      } 
     } 

    } 
} 

Das funktioniert ganz gut. Das Problem beginnt, wenn ich folgende Methode zu diesem Mapper hinzufügen:

public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, Locale userLanguage); 

Ich brauche diesen Parameter (userLanguage) als auch passieren, aber mapstruct scheint zu ‚brechen‘ in diesem Fall: Ich erzeugen für diese folgenden Code (was natürlich einen Übersetzungsfehler gibt):

@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; 
} 

ich bin sicher, dass es auf den Parameter verwendet ist, da, wenn ich es entfernen (aus allen Mapping-Methoden), dann die mAPLIST Methode korrekt erzeugt wird.

Was muss getan werden, um benutzerdefinierte Parameter in diesem Fall zuzulassen?

Antwort

7

Was Sie beschreiben, ist (noch) nicht möglich. Können Sie eine Feature-Anfrage in unserem issue tracker öffnen? Wir sollten Mittel bereitstellen, um Parameter als eine Art "Kontext" zu bezeichnen, der über den Call-Stack weitergegeben wird.

Als vorübergehende Lösung können Sie einen Blick auf ThreadLocal werfen, den Sie vor dem Aufrufen der Zuordnungsroutine festgelegt haben und auf den Sie in der Anpassung nach der Zuordnung zugreifen. Es ist nicht elegant - und Sie müssen sicherstellen, dass der lokale Thread bereinigt wird, um Speicherlecks zu vermeiden - aber es sollte ausreichen.

+0

Danke, erstellt https://github.com/mapstruct/mapstruct/issues/809 –

+0

FYI: Da ich bereits eine Fassade als Wrapper für die tatsächlichen Mapper erstellt hatte (um den Code mehr von der tatsächlichen Mapper-Implementierung zu entkoppeln) Ich durchlaufe einfach die Liste der einzelnen Elemente (AlertConfigAction) und ordne sie einzeln zu. Wenn diese Funktion unterstützt wird, kann ich einfach die Fassade aktualisieren. –

1

Ich glaube nicht, dass es möglich ist. Zumindest nicht so. Problem ist, dass Sie die Schnittstelle/abstrakte Klasse vorbereiten - und der Rest wird von der Engine erledigt. Und diese Engine erwartet Methoden mit einem Parameter ... Es gibt Dekoratoren, aber sie gehen genauso. Ich würde versuchen, Sprache zu injizieren. Erstelle eine Bean, markiere sie als Session-Bereich und finde es heraus. Mit Spring würden Sie ScopedProxyMode dafür verwenden ... Nicht sicher, wie das mit CDI geht.

Andere Option ist mehr Workaround, dann Lösung - vielleicht, dass AlertConfigAction diese Informationen weitergeben kann?

Verwandte Themen