package com.github.kahalemakai.opencsv.beans.processing.decoders;

import com.github.kahalemakai.opencsv.beans.processing.DataDecodingException;
import com.github.kahalemakai.opencsv.beans.processing.Decoder;
import lombok.AccessLevel;
import lombok.Setter;

import java.util.*;

@Log4j
public class EnumDecoder<E extends Enum<E>> implements Decoder<E> {
    @Setter(AccessLevel.PROTECTED)
    private Map<String, E> mapping = new HashMap<>();
    private Class<? extends E> type;
    private Map<String, E> enumMapping = new HashMap<>();

    @Override
    public E decode(String value) {
        final E e = getEnumConstant(value);
        if (e == null) {
            if (log.isDebugEnabled()) {
                final String msg = String.format("could not decode value '%s' as enum of type %s", value, getClass().getCanonicalName());
                log.debug(msg);
            }
            return Decoder.decodingFailed();
        }
        return e;
    }

    public final void put(final String key, final String value) {
        if (!enumMapping.containsKey(value)) {
            throw new IllegalArgumentException(String.format("cannot map value '%s' to enum constant of enum class %s", value, getClass().getCanonicalName()));
        }
        mapping.put(key, enumMapping.get(value));
    }

    public final E getEnumConstant(final String key) {
        return mapping.get(key);
    }

    public final void setType(final Class<? extends E> type) {
        if (type == null) {
            throw new UnsupportedOperationException("type has already been set");
        }
        this.type = type;
        for (E e : type.getEnumConstants()) {
            enumMapping.put(e.name(), e);
        }
    }

}

@@ -120,28 +120,14 @@
 ng.D
-ataDecodingException
+ecoder
 ;%0Aim
@@ -135,63 +135,26 @@
 ort 
-com.github.kahalemakai.opencsv.beans.processing.Decoder
+lombok.AccessLevel
 ;%0Aim
@@ -161,35 +161,30 @@
 port lombok.
-AccessLevel
+Setter
 ;%0Aimport lom
@@ -187,22 +187,34 @@
  lombok.
-Setter
+extern.log4j.Log4j
 ;%0A%0Aimpor
@@ -229,9 +229,37 @@
 til.
-*
+HashMap;%0Aimport java.util.Map
 ;%0A%0A@
@@ -1367,32 +1367,82 @@
 et(key);%0A    %7D%0A%0A
+    // FIXME: turn this into a static constructor%0A
     public final
@@ -1480,17 +1480,20 @@
 ends E%3E 
-t
+newT
 ype) %7B%0A 
@@ -1503,18 +1503,57 @@
     
-if (
+synchronized (this) %7B%0A            if (this.
 type 
-=
+!
 = nu
@@ -1562,32 +1562,36 @@
 ) %7B%0A            
+    
 throw new Unsupp
@@ -1644,32 +1644,36 @@
  set%22);%0A        
+    
 %7D%0A        this.t
@@ -1670,25 +1670,9 @@
     
-this.type = type;
+%7D
 %0A   
@@ -1687,17 +1687,20 @@
  (E e : 
-t
+newT
 ype.getE

make EnumDecoder thread-safe