登记自定义转换器

@param type 转换的目标类型
@param converterClass 转换器类，必须有默认构造方法
@return {@link ConverterRegistry}
182009
public ConverterRegistry putCustom(Type type, Class<? extends Converter<?>> converterClass) {
		return putCustom(type, ReflectUtil.newInstance(converterClass));
	}
508273
public <FT> void registerConverter(Class<FT> clazz, Converter<FT, ?> converter) {
		converterMap.put(clazz, converter);
	}
701891
public final <S, T> void registerConverter(ConverterKey<S,T> key, Converter<S, T> converter) {	

        if (key.getInputClass() == null) {
            throw new IllegalArgumentException("Input Class must not be null");
        }
        if (key.getOutputClass() == null) {
            throw new IllegalArgumentException("Output Class must not be null");
        }
        if (converter == null) {
            throw new IllegalArgumentException("Converter must not be null");
        }

        if (key.getQualifierAnnotation() == null) {
            throw new IllegalArgumentException("Qualifier must not be null");
        }

        Converter<?,?> old = registeredConverters.putIfAbsent(key, converter);
        if (old != null && (!isSameConverter(old, converter))) {
        	throw new IllegalStateException("Converter already registered for key: " + key);
        }
    }
692249
public <S, T> Converter<S, T> findConverter(ConverterKey<S,T> key) {
		
		 // We check once before attempting introspection so we avoid that if possible
		@SuppressWarnings("unchecked")
		Converter<S,T> converter = (Converter<S, T>) registeredConverters.get(key);
		if (converter != null) {
			return converter;
		}
		
		// Now try introspecting the relevant class
		registerAnnotatedClasses(key.getInputClass(), key.getOutputClass());

		@SuppressWarnings("unchecked")
		Converter<S,T> myConverter = (Converter<S, T>) registeredConverters.get(key);
		return myConverter;
	}
645622
public static Converter<String, Object> createPathParamConverter(final Type resultType) {
    if (!(resultType instanceof Class)) {
      throw new IllegalArgumentException("Unsupported @PathParam type " + resultType);
    }
    return new Converter<String, Object>() {
      @Override
      public Object convert(String value) {
        return ConvertUtils.convert(value, (Class<?>) resultType);
      }
    };
  }
493278
Converter select(Class<?> type) throws IllegalStateException {
        // Check the hashtable first.
        Entry[] entries = iSelectEntries;
        int length = entries.length;
        int index = type == null ? 0 : type.hashCode() & (length - 1);

        Entry e;
        // This loop depends on there being at least one null slot.
        while ((e = entries[index]) != null) {
            if (e.iType == type) {
                return e.iConverter;
            }
            if (++index >= length) {
                index = 0;
            }
        }

        // Not found in the hashtable, so do actual work.

        Converter converter = selectSlow(this, type);
        e = new Entry(type, converter);

        // Save the entry for future selects. This class must be threadsafe,
        // but there is no synchronization. Since the hashtable is being used
        // as a cache, it is okay to destroy existing entries. This isn't
        // likely to occur unless there is a high amount of concurrency. As
        // time goes on, cache updates will occur less often, and the cache
        // will fill with all the necessary entries.

        // Do all updates on a copy: slots in iSelectEntries must not be
        // updated by multiple threads as this can allow all null slots to be
        // consumed.
        entries = (Entry[])entries.clone();

        // Add new entry.
        entries[index] = e;

        // Verify that at least one null slot exists!
        for (int i=0; i<length; i++) {
            if (entries[i] == null) {
                // Found a null slot, swap in new hashtable.
                iSelectEntries = entries;
                return converter;
            }
        }

        // Double capacity and re-hash.

        int newLength = length << 1;
        Entry[] newEntries = new Entry[newLength];
        for (int i=0; i<length; i++) {
            e = entries[i];
            type = e.iType;
            index = type == null ? 0 : type.hashCode() & (newLength - 1);
            while (newEntries[index] != null) {
                if (++index >= newLength) {
                    index = 0;
                }
            }
            newEntries[index] = e;
        }

        // Swap in new hashtable.
        iSelectEntries = newEntries;
        return converter;
    }
891546
@Override
    public <T> ConfigBuilder withConverter(Class<T> type, int priority, Converter<T> converter) {
        synchronized (this) {
            UserConverter<?> userConverter = UserConverter.newInstance(type, priority, converter);
            addUserConverter(userConverter);
        }
        return this;
    }
107646
protected <T> TypeConverter findTypeConverter(Class<?> sourceType, Class<T> targetType, Class<? extends Annotation> formattingAnnotation) {
        TypeConverter typeConverter = null;
        List<Class> sourceHierarchy = ClassUtils.resolveHierarchy(sourceType);
        List<Class> targetHierarchy = ClassUtils.resolveHierarchy(targetType);
        boolean hasFormatting = formattingAnnotation != null;
        for (Class sourceSuperType : sourceHierarchy) {
            for (Class targetSuperType : targetHierarchy) {
                ConvertiblePair pair = new ConvertiblePair(sourceSuperType, targetSuperType, formattingAnnotation);
                typeConverter = typeConverters.get(pair);
                if (typeConverter != null) {
                    converterCache.put(pair, typeConverter);
                    return typeConverter;
                }
            }
        }
        if (hasFormatting) {
            for (Class sourceSuperType : sourceHierarchy) {
                for (Class targetSuperType : targetHierarchy) {
                    ConvertiblePair pair = new ConvertiblePair(sourceSuperType, targetSuperType);
                    typeConverter = typeConverters.get(pair);
                    if (typeConverter != null) {
                        converterCache.put(pair, typeConverter);
                        return typeConverter;
                    }
                }
            }
        }
        return typeConverter;
    }
1367616
public <T> Converter<T> getConverter(Type type, boolean isCustomFirst) {
		Converter<T> converter = null;
		if (isCustomFirst) {
			converter = this.getCustomConverter(type);
			if (null == converter) {
				converter = this.getDefaultConverter(type);
			}
		} else {
			converter = this.getDefaultConverter(type);
			if (null == converter) {
				converter = this.getCustomConverter(type);
			}
		}
		return converter;
	}
775316
@NullSafe
  @Override
  @SuppressWarnings("unchecked")
  public <R extends Registry<Converter<?, ?>>> R unregister(Converter<?, ?> converter) {

    for (Iterator<Converter<?, ?>> iterator = iterator(); iterator.hasNext(); ) {
      if (iterator.next().equals(converter)) {
        iterator.remove();
        converter.setConversionService(null);
      }
    }

    return (R) this;
  }
460854
private static Converter<List<String>, Object> createListConverter(Type resultType) {
    // Use boxed type if raw type is primitive type. Otherwise the type won't change.
    Class<?> resultClass = getRawClass(resultType);

    // For string, just return the first value
    if (resultClass == String.class) {
      return new BasicConverter(defaultValue(resultClass)) {
        @Override
        protected Object convert(String value) throws Exception {
          return value;
        }
      };
    }

    // Creates converter based on the type

    // Primitive
    Converter<List<String>, Object> converter = createPrimitiveTypeConverter(resultClass);
    if (converter != null) {
      return converter;
    }

    // String constructor
    converter = createStringConstructorConverter(resultClass);
    if (converter != null) {
      return converter;
    }

    // Static string argument methods
    converter = createStringMethodConverter(resultClass);
    if (converter != null) {
      return converter;
    }

    // Collection
    converter = createCollectionConverter(resultType);
    if (converter != null) {
      return converter;
    }

    throw new IllegalArgumentException("Unsupported type " + resultType + " of type class " + resultType.getClass());
  }
1186207
public <T> JsonBuilder registerTypeAdapter(Class<T> clazz, TypeAdapter<T> typeAdapter) {
        typeAdapters.registerTypeAdapter(clazz, typeAdapter);
        return this;
    }
64063
protected ConversionStatus convertCompatible(String rawString, Class<?> type) {
        ConversionStatus status = new ConversionStatus();
        for (PriorityConverter con : converters.getAll()) {
            Type key = con.getType();
            if (key instanceof Class) {
                Class<?> clazz = (Class<?>) key;
                if (type.isAssignableFrom(clazz)) {
                    Object converted = convert(rawString, key);
                    status.setConverted(converted);
                    break;
                }
            } else if (key instanceof TypeVariable) {
                TypeVariable<?> typeVariable = (TypeVariable<?>) key;
                status = convertGenericClazz(rawString, type, typeVariable);
                if (status.isConverterFound()) {
                    break;
                }
            }
        }
        return status;

    }
1049598
public static final <TO, FROM> void register(Class<TO> to, Class<FROM> from, DataConverter<TO, FROM> converter) {
		converters.put(new DataConverterKey<TO, FROM>(to, from), converter);
	}
1368565
public Tree setType(Class<?> type) {
		if (value == null || value.getClass() == type) {
			return this;
		}
		value = DataConverterRegistry.convert(type, value);
		if (parent != null && key != null) {
			if (key instanceof String) {
				parent.putObjectInternal((String) key, value, false);
			} else {
				parent.remove((int) key);
				parent.insertObjectInternal((int) key, value);
			}
		}
		return this;
	}
809889
public static void addInternalConverters(Map<Class<?>, Converter<?, ?>> converterMap) {
		converterMap.put(BigDecimal.class, BigDecimalConverter.getSingleton());
		converterMap.put(BigInteger.class, BigIntegerConverter.getSingleton());
		converterMap.put(Boolean.class, BooleanConverter.getSingleton());
		converterMap.put(boolean.class, BooleanConverter.getSingleton());
		converterMap.put(Byte.class, ByteConverter.getSingleton());
		converterMap.put(byte.class, ByteConverter.getSingleton());
		converterMap.put(Character.class, CharacterConverter.getSingleton());
		converterMap.put(char.class, CharacterConverter.getSingleton());
		converterMap.put(Date.class, DateConverter.getSingleton());
		converterMap.put(Double.class, DoubleConverter.getSingleton());
		converterMap.put(double.class, DoubleConverter.getSingleton());
		converterMap.put(Enum.class, EnumConverter.getSingleton());
		converterMap.put(Float.class, FloatConverter.getSingleton());
		converterMap.put(float.class, FloatConverter.getSingleton());
		converterMap.put(Integer.class, IntegerConverter.getSingleton());
		converterMap.put(int.class, IntegerConverter.getSingleton());
		converterMap.put(Long.class, LongConverter.getSingleton());
		converterMap.put(long.class, LongConverter.getSingleton());
		converterMap.put(Short.class, ShortConverter.getSingleton());
		converterMap.put(short.class, ShortConverter.getSingleton());
		converterMap.put(String.class, StringConverter.getSingleton());
		converterMap.put(UUID.class, UuidConverter.getSingleton());
	}
538869
private static <T> ConvertibleType<T> of(final DynamoDBTypeConverter<?,T> converter) {
        final Class<?> clazz = converter.getClass();
        if (!clazz.isInterface()) {
            for (Class<?> c = clazz; Object.class != c; c = c.getSuperclass()) {
                for (final Type genericType : c.getGenericInterfaces()) {
                    final ConvertibleType<T> type = ConvertibleType.<T>of(genericType);
                    if (type.is(DynamoDBTypeConverter.class)) {
                        if (type.params.length == 2 && type.param(0).targetType() != Object.class) {
                            return type.param(0);
                        }
                    }
                }
            }
            final ConvertibleType<T> type = ConvertibleType.<T>of(clazz.getGenericSuperclass());
            if (type.is(DynamoDBTypeConverter.class)) {
                if (type.params.length > 0 && type.param(0).targetType() != Object.class) {
                    return type.param(0);
                }
            }
        }
        throw new DynamoDBMappingException("could not resolve type of " + clazz);
    }