Package com.bergerkiller.bukkit.common.conversion

Source Code of com.bergerkiller.bukkit.common.conversion.Conversion

package com.bergerkiller.bukkit.common.conversion;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;

import com.bergerkiller.bukkit.common.conversion.type.ConversionTypes;
import com.bergerkiller.bukkit.common.conversion.type.EmptyConverter;
import com.bergerkiller.bukkit.common.conversion.type.EnumConverter;
import com.bergerkiller.bukkit.common.conversion.type.ObjectArrayConverter;
import com.bergerkiller.bukkit.common.internal.CommonPlugin;
import com.bergerkiller.bukkit.common.utils.CommonUtil;
import com.bergerkiller.bukkit.common.utils.LogicUtil;

/**
* Stores all available converters to convert Object values to a requested type
*/
public class Conversion extends ConversionTypes {
  private static final Map<Class<?>, Converter<Object>> converters = new ConcurrentHashMap<Class<?>, Converter<Object>>();
  static {
    try {
      registerAll(ConversionTypes.class);
      ConversionPairs.class.getModifiers(); // Load this class
    } catch (Throwable t) {
      CommonPlugin.LOGGER_CONVERSION.log(Level.SEVERE, "Failed to initialize default converters", t);
    }
  }

  /**
   * Registers all available static convertor constants found in the Class or enum
   *
   * @param convertorConstants class container to register
   */
  public static void registerAll(Class<?> convertorConstants) {
    for (Object convertor : CommonUtil.getClassConstants(convertorConstants, Converter.class)) {
      if (convertor instanceof Converter) {
        register((Converter<?>) convertor);
      }
    }
  }

  /**
   * Registers a converter so it can be used to convert to the output type it represents.
   * If the converter does not support registration, it is ignored
   *
   * @param converter to register
   */
  @SuppressWarnings("unchecked")
  public static void register(Converter<?> converter) {
    if (!converter.isRegisterSupported()) {
      return;
    }
    converters.put(converter.getOutputType(), (Converter<Object>) converter);
  }

  /**
   * Obtains the converter used to convert to the type specified<br>
   * If none is available yet for the type, a new one is created
   *
   * @param type to convert to
   * @return converter
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public static <T> Converter<T> getConverter(Class<T> type) {
    if (type.isPrimitive()) {
      type = (Class<T>) LogicUtil.getBoxedType(type);
    }
    Converter<T> converter = (Converter<T>) converters.get(type);
    if (converter == null) {
      if (type.isArray()) {
        // Maybe converting to an Object array of a certain component type?
        // Note: Primitives are already dealt with and registered in the map
        final Class<?> componentType = type.getComponentType();
        if (!componentType.isPrimitive()) {
          // Use the ObjectArrayConvertor to deal with this
          converter = new ObjectArrayConverter(componentType);
        }
      } else if (type.isEnum()) {
        // Converting to an enum type - construct a new EnumConverter
        converter = new EnumConverter<T>(type);
      } else {
        // Maybe the requested type is an extension?
        // If so, put a new casting converter in place to deal with it
        for (Converter<Object> conv : converters.values()) {
          if (conv.isCastingSupported() && conv.getOutputType().isAssignableFrom(type)) {
            converter = new CastingConverter(type, conv);
            break;
          }
        }
      }
      // Resolve to the default casting-based converter if not found
      if (converter == null) {
        converter = new EmptyConverter(type);
      }
      // Found. Put into map for faster look-up
      converters.put(type, (Converter<Object>) converter);
    }
    return (Converter<T>) converter;
  }

  /**
   * Converts an object to the given type using previously registered converters
   *
   * @param value to convert
   * @param def value to return on failure (can not be null)
   * @return the converted value
   */
  @SuppressWarnings("unchecked")
  public static <T> T convert(Object value, T def) {
    return convert(value, (Class<T>) def.getClass(), def);
  }

  /**
   * Converts an object to the given type using previously registered converters
   *
   * @param value to convert
   * @param type to convert to
   * @return the converted value, or null on failure
   */
  public static <T> T convert(Object value, Class<T> type) {
    return convert(value, type, null);
  }

  /**
   * Converts an object to the given type using previously registered converters
   *
   * @param value to convert
   * @param type to convert to
   * @param def value to return on failure
   * @return the converted value
   */
  public static <T> T convert(Object value, Class<T> type, T def) {
    if (value == null) {
      return def;
    }
    final Class<?> valueType = value.getClass();
    if (type.isAssignableFrom(valueType)) {
      return type.cast(value);
    }
    return getConverter(type).convert(value, def);
  }
}
TOP

Related Classes of com.bergerkiller.bukkit.common.conversion.Conversion

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.