private static Conversion getConversion()

in src/main/java/com/univocity/parsers/annotations/helpers/AnnotationHelper.java [107:260]


	private static Conversion getConversion(Class fieldType, AnnotatedElement target, Annotation annotation) {
		try {
			Parsed parsed = target == null ? null : findAnnotation(target, Parsed.class);
			Class annType = annotation.annotationType();

			String nullRead = getNullReadValue(target, parsed);
			String nullWrite = getNullWriteValue(target, parsed);

			if (annType == NullString.class) {
				NullString nullString = (NullString) annotation;
				String[] nulls = AnnotationRegistry.getValue(target, nullString, "nulls", nullString.nulls());
				return Conversions.toNull(nulls);
			} else if (annType == Validate.class) {
				Validate validate = (Validate) annotation;

				boolean nullable = AnnotationRegistry.getValue(target, validate, "nullable", validate.nullable());
				boolean allowBlanks = AnnotationRegistry.getValue(target, validate, "allowBlanks", validate.allowBlanks());
				String[] oneOf = AnnotationRegistry.getValue(target, validate, "oneOf", validate.oneOf());
				String[] noneOf = AnnotationRegistry.getValue(target, validate, "noneOf", validate.noneOf());
				String matches = AnnotationRegistry.getValue(target, validate, "matches", validate.matches());

				Class[] validators = AnnotationRegistry.getValue(target, validate, "validators", validate.validators());
				return new ValidatedConversion(nullable, allowBlanks, oneOf, noneOf, matches, validators);
			} else if (annType == EnumOptions.class) {
				if (!fieldType.isEnum()) {
					if (target == null) {
						throw new IllegalStateException("Invalid " + EnumOptions.class.getName() + " instance for converting class " + fieldType.getName() + ". Not an enum type.");
					} else {
						throw new IllegalStateException("Invalid " + EnumOptions.class.getName() + " annotation on " + describeElement(target) + ". Attribute must be an enum type.");
					}
				}
				EnumOptions enumOptions = ((EnumOptions) annotation);
				String customElement = AnnotationRegistry.getValue(target, enumOptions, "customElement", enumOptions.customElement());
				String element = customElement.trim();
				if (element.isEmpty()) {
					element = null;
				}

				Enum nullReadValue = nullRead == null ? null : Enum.valueOf(fieldType, nullRead);
				EnumSelector[] selectors = AnnotationRegistry.getValue(target, enumOptions, "selectors", enumOptions.selectors());
				return new EnumConversion(fieldType, nullReadValue, nullWrite, element, selectors);
			} else if (annType == Trim.class) {
				Trim trim = ((Trim) annotation);
				int length = AnnotationRegistry.getValue(target, trim, "length", trim.length());
				if (length == -1) {
					return Conversions.trim();
				} else {
					return Conversions.trim(length);
				}
			} else if (annType == LowerCase.class) {
				return Conversions.toLowerCase();
			} else if (annType == UpperCase.class) {
				return Conversions.toUpperCase();
			} else if (annType == Replace.class) {
				Replace replace = ((Replace) annotation);
				String expression = AnnotationRegistry.getValue(target, replace, "expression", replace.expression());
				String replacement = AnnotationRegistry.getValue(target, replace, "replacement", replace.replacement());
				return Conversions.replace(expression, replacement);
			} else if (annType == BooleanString.class) {
				if (fieldType != boolean.class && fieldType != Boolean.class) {
					if (target == null) {
						throw new DataProcessingException("Invalid  usage of " + BooleanString.class.getName() + ". Got type " + fieldType.getName() + " instead of boolean.");
					} else {
						throw new DataProcessingException("Invalid annotation: " + describeElement(target) + " has type " + fieldType.getName() + " instead of boolean.");
					}
				}
				BooleanString boolString = ((BooleanString) annotation);
				String[] falseStrings = AnnotationRegistry.getValue(target, boolString, "falseStrings", boolString.falseStrings());
				String[] trueStrings = AnnotationRegistry.getValue(target, boolString, "trueStrings", boolString.trueStrings());
				Boolean valueForNull = nullRead == null ? null : BooleanConversion.getBoolean(nullRead, trueStrings, falseStrings);

				if (valueForNull == null && fieldType == boolean.class) {
					valueForNull = Boolean.FALSE;
				}

				return Conversions.toBoolean(valueForNull, nullWrite, trueStrings, falseStrings);
			} else if (annType == Format.class) {
				Format format = ((Format) annotation);
				String[] formats = AnnotationRegistry.getValue(target, format, "formats", format.formats());
				String[] options = AnnotationRegistry.getValue(target, format, "options", format.options());

				Locale locale = extractLocale(options);

				Conversion conversion = null;

				if (fieldType == BigDecimal.class) {
					BigDecimal defaultForNull = nullRead == null ? null : new BigDecimal(nullRead);
					conversion = Conversions.formatToBigDecimal(defaultForNull, nullWrite, formats);
				} else if (Number.class.isAssignableFrom(fieldType) || (fieldType.isPrimitive()) && fieldType != boolean.class && fieldType != char.class) {
					conversion = Conversions.formatToNumber(formats);
					((NumericConversion) conversion).setNumberType(fieldType);
				} else {
					Date dateIfNull = null;
					if (nullRead != null) {
						if ("now".equalsIgnoreCase(nullRead)) {
							dateIfNull = new Date();
						} else {
							if (formats.length == 0) {
								throw new DataProcessingException("No format defined");
							}
							SimpleDateFormat sdf = new SimpleDateFormat(formats[0], locale);
							dateIfNull = sdf.parse(nullRead);
						}
					}

					if (Date.class == fieldType) {
						conversion = Conversions.toDate(locale, dateIfNull, nullWrite, formats);
					} else if (Calendar.class == fieldType) {
						Calendar calendarIfNull = null;
						if (dateIfNull != null) {
							calendarIfNull = Calendar.getInstance();
							calendarIfNull.setTime(dateIfNull);
						}
						conversion = Conversions.toCalendar(locale, calendarIfNull, nullWrite, formats);
					}
				}

				if (conversion != null) {
					if (options.length > 0) {
						//noinspection ConstantConditions
						if (conversion instanceof FormattedConversion) {
							Object[] formatters = ((FormattedConversion) conversion).getFormatterObjects();
							for (Object formatter : formatters) {
								applyFormatSettings(formatter, options);
							}
						} else {
							throw new DataProcessingException("Options '" + Arrays.toString(options) + "' not supported by conversion of type '" + conversion.getClass() + "'. It must implement " + FormattedConversion.class);
						}
					}
					return conversion;
				}

			} else if (annType == Convert.class) {
				Convert convert = ((Convert) annotation);
				String[] args = AnnotationRegistry.getValue(target, convert, "args", convert.args());
				Class conversionClass = AnnotationRegistry.getValue(target, convert, "conversionClass", convert.conversionClass());
				return (Conversion) newInstance(Conversion.class, conversionClass, args);
			}

			if (fieldType == String.class && (nullRead != null || nullWrite != null)) {
				return new ToStringConversion(nullRead, nullWrite);
			}

			return null;
		} catch (DataProcessingException ex) {
			throw ex;
		} catch (Throwable ex) {
			if (target == null) {
				throw new DataProcessingException("Unexpected error identifying conversions to apply over type " + fieldType, ex);
			} else {
				throw new DataProcessingException("Unexpected error identifying conversions to apply over " + describeElement(target), ex);
			}
		}
	}