private Converter cacheConverter()

in xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java [416:484]


    private Converter cacheConverter(final XStreamConverter annotation, final Class<?> targetType) {
        Converter result = null;
        final Object[] args;
        final List<Object> parameter = new ArrayList<>();
        if (targetType != null && annotation.useImplicitType()) {
            parameter.add(targetType);
        }
        final List<Object> arrays = new ArrayList<>();
        arrays.add(annotation.booleans());
        arrays.add(annotation.bytes());
        arrays.add(annotation.chars());
        arrays.add(annotation.doubles());
        arrays.add(annotation.floats());
        arrays.add(annotation.ints());
        arrays.add(annotation.longs());
        arrays.add(annotation.shorts());
        arrays.add(annotation.strings());
        arrays.add(annotation.types());
        for (final Object array : arrays) {
            if (array != null) {
                final int length = Array.getLength(array);
                for (int i = 0; i < length; i++) {
                    parameter.add(Array.get(array, i));
                }
            }
        }
        for (final Class<?> type : annotation.nulls()) {
            final TypedNull<?> nullType = new TypedNull<>(type);
            parameter.add(nullType);
        }
        final Class<? extends ConverterMatcher> converterType = annotation.value();
        Map<List<Object>, Converter> converterMapping = converterCache.get(converterType);
        if (converterMapping != null) {
            result = converterMapping.get(parameter);
        }
        if (result == null) {
            final int size = parameter.size();
            if (size > 0) {
                args = new Object[arguments.length + size];
                System.arraycopy(arguments, 0, args, size, arguments.length);
                System.arraycopy(parameter.toArray(new Object[size]), 0, args, 0, size);
            } else {
                args = arguments;
            }

            final Converter converter;
            try {
                if (SingleValueConverter.class.isAssignableFrom(converterType)
                    && !Converter.class.isAssignableFrom(converterType)) {
                    final SingleValueConverter svc = (SingleValueConverter)DependencyInjectionFactory.newInstance(
                        converterType, args);
                    converter = new SingleValueConverterWrapper(svc);
                } else {
                    converter = (Converter)DependencyInjectionFactory.newInstance(converterType, args);
                }
            } catch (final Exception e) {
                throw new InitializationException("Cannot instantiate converter "
                    + converterType.getName()
                    + (targetType != null ? " for type " + targetType.getName() : ""), e);
            }
            if (converterMapping == null) {
                converterMapping = new HashMap<>();
                converterCache.put(converterType, converterMapping);
            }
            converterMapping.put(parameter, converter);
            result = converter;
        }
        return result;
    }