private MapperConverter findConverter()

in johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java [678:735]


    private MapperConverter findConverter(final boolean copyDate, final AccessMode.DecoratedType decoratedType) {
        MapperConverter converter = decoratedType.findConverter();
        if (converter != null) {
            return converter;
        }

        final JohnzonConverter annotation = decoratedType.getAnnotation(JohnzonConverter.class);

        Type typeToTest = decoratedType.getType();
        if (annotation != null) {
            try {
                converter = annotation.value().newInstance();
            } catch (final Exception e) {
                throw new IllegalArgumentException(e);
            }
        } else if (ParameterizedType.class.isInstance(decoratedType.getType())) {
            final ParameterizedType type = ParameterizedType.class.cast(decoratedType.getType());
            final Type rawType = type.getRawType();
            if (Class.class.isInstance(rawType)
                    && Collection.class.isAssignableFrom(Class.class.cast(rawType))
                    && type.getActualTypeArguments().length >= 1) {
                typeToTest = type.getActualTypeArguments()[0];
            } // TODO: map
        }
        if (converter == null && Class.class.isInstance(typeToTest)) {
            final Class type = Class.class.cast(typeToTest);
            ConcurrentMap<AdapterKey, Adapter<?, ?>> adapters = config.getAdapters();

            if (Date.class.isAssignableFrom(type) && copyDate) {
                converter = new DateWithCopyConverter(Adapter.class.cast(adapters.get(new AdapterKey(Date.class, String.class))));
            } else {
                for (final Map.Entry<AdapterKey, Adapter<?, ?>> adapterEntry : adapters.entrySet()) {
                    if (adapterEntry.getKey().getFrom() == adapterEntry.getKey().getTo()) { // String -> String
                        continue;
                    }
                    if (adapterEntry.getKey().getFrom() == type && !(
                            // ignore internal converters to let primitives be correctly handled
                            ConverterAdapter.class.isInstance(adapterEntry.getValue()) &&
                                    isBuiltInJohnzonConverter(ConverterAdapter.class.cast(adapterEntry.getValue()).getConverter()))) {

                        if (converter != null) {
                            throw new IllegalArgumentException("Ambiguous adapter for " + decoratedType);
                        }
                        converter = adapterEntry.getValue();
                    }
                }
            }
            if (converter == null && Enum.class.isAssignableFrom(type)) {
                final AdapterKey key = new AdapterKey(String.class, type);
                converter = adapters.get(key); // first ensure user didnt override it
                if (converter == null) {
                    converter = new ConverterAdapter(config.getEnumConverterFactory().apply(type), type);
                    adapters.put(key, (Adapter<?, ?>) converter);
                }
            }
        }
        return converter;
    }