All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.avcompris.commons.query.impl.FieldUtils Maven / Gradle / Ivy

There is a newer version: 0.6.3
Show newest version
package net.avcompris.commons.query.impl;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Maps.newHashMap;
import static java.util.Locale.ENGLISH;
import static org.apache.commons.lang3.StringUtils.isBlank;

import java.lang.reflect.Field;
import java.util.Map;

import org.apache.commons.lang3.NotImplementedException;
import org.joda.time.DateTime;

import net.avcompris.commons.query.Filtering;
import net.avcompris.commons.query.Filtering.Field.Spec;

public abstract class FieldUtils {

	private static final Map ENUM_NAMES = newHashMap();
	private static final Map PROPERTY_NAMES = newHashMap();
	private static final Map SQL_NAMES = newHashMap();

	static String extractSqlName(final Field field) {

		checkNotNull(field, "field");

		final String cached = SQL_NAMES.get(field);

		if (cached != null) {
			return cached;
		}

		final String sqlName;

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null || isBlank(fieldSpecAnnotation.sqlName())) {

			sqlName = field.getName().toLowerCase(ENGLISH);

		} else {

			sqlName = fieldSpecAnnotation.sqlName();
		}

		SQL_NAMES.put(field, sqlName);

		return sqlName;
	}

	public static  String extractPropertyName(final U field) {

		checkNotNull(field, "field");

		final String cached = PROPERTY_NAMES.get(field);

		if (cached != null) {
			return cached;
		}

		final Spec fieldSpecAnnotation = getEnumField(field).getAnnotation(Spec.class);

		if (fieldSpecAnnotation != null) {

			final String propertyName = fieldSpecAnnotation.propertyName();

			if (!isBlank(propertyName)) {

				PROPERTY_NAMES.put(field, propertyName);

				return propertyName;
			}
		}

		final String enumName = extractEnumName(field);

		if (!enumName.toUpperCase(ENGLISH).contentEquals(enumName)) {
			throw new NotImplementedException("enumName should be uppercase: " + enumName);
		}

		final StringBuilder sb = new StringBuilder();

		for (int i = 0; i < enumName.length(); ++i) {

			final char c = enumName.charAt(i);

			if (c == '_') {

				++i;

				final char c2 = enumName.charAt(i);

				sb.append(c2);

			} else {

				sb.append(Character.toLowerCase(c));
			}
		}

		final String propertyName = sb.toString();

		PROPERTY_NAMES.put(field, propertyName);

		return propertyName;
	}

	static  String extractEnumName(final U field) {

		checkNotNull(field, "field");

		final String cached = ENUM_NAMES.get(field);

		if (cached != null) {
			return cached;
		}

		final Class fieldClass = field.getClass();

		checkArgument(fieldClass.isEnum(), //
				"fieldClass should be enum: %s, for field: %s", fieldClass.getName(), field);

		for (final Filtering.Field enumValue : fieldClass.getEnumConstants()) {

			if (enumValue == field) {

				final String enumName = ((Enum) enumValue).name();

				ENUM_NAMES.put(field, enumName);

				return enumName;
			}
		}

		throw new IllegalArgumentException("Cannot extract enumName from field: " + field);
	}

	static  Field getEnumField(final U enumValue) {

		checkNotNull(enumValue, "enumValue");

		final Class enumClass = enumValue.getClass();

		checkState(enumClass.isEnum(), //
				"enumClass should be enum: %s, for enumValue: %s", enumClass.getName(), enumValue);

		final Enum enumConstant = (Enum) enumValue;

		final String fieldName = enumConstant.name();

		for (final Field field : enumClass.getFields()) {

			if (!field.isEnumConstant()) {
				continue;
			}

			if (fieldName.contentEquals(field.getName())) {

				return field;
			}
		}

		throw new IllegalStateException("enumValue: " + enumValue + ", enumClass: " + enumClass);
	}

	static , U extends Filtering.Field> Class extractFieldClass(
			final Class filteringClass) {

		checkNotNull(filteringClass, "filteringClass");

		for (final Class clazz : filteringClass.getClasses()) {

			if (!clazz.isEnum() && !Filtering.Field.class.isAssignableFrom(clazz)) {
				continue;
			}

			@SuppressWarnings("unchecked")
			final Class fieldClass = (Class) clazz;

			return fieldClass;
		}

		throw new RuntimeException("Cannot find \"Field\" enum subclass in: " + filteringClass.getName());
	}

	static boolean isStringField(final Filtering.Field enumValue) {

		final Field field = FieldUtils.getEnumField(enumValue);

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null) {

			return false;

		} else {

			return String.class.equals(fieldSpecAnnotation.type());
		}
	}

	static boolean isIntField(final Filtering.Field enumValue) {

		final Field field = FieldUtils.getEnumField(enumValue);

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null) {

			return false;

		} else {

			return int.class.equals(fieldSpecAnnotation.type());
		}
	}

	public static boolean isBooleanField(final Filtering.Field enumValue) {

		final Field field = FieldUtils.getEnumField(enumValue);

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null) {

			return false;

		} else {

			return boolean.class.equals(fieldSpecAnnotation.type());
		}
	}

	static boolean isDateTimeField(final Filtering.Field enumValue) {

		final Field field = FieldUtils.getEnumField(enumValue);

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null) {

			return false;

		} else {

			return DateTime.class.equals(fieldSpecAnnotation.type());
		}
	}

	static boolean isEnumField(final Filtering.Field enumValue) {

		final Field field = FieldUtils.getEnumField(enumValue);

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null) {

			return false;

		} else {

			return fieldSpecAnnotation.type().isEnum();
		}
	}

	static Class> getEnumFieldClass(final Filtering.Field enumValue) {

		final Field field = FieldUtils.getEnumField(enumValue);

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		checkArgument(fieldSpecAnnotation != null, //
				"Field should be @Spec-annotated: %s", enumValue);

		final Class type = fieldSpecAnnotation.type();

		checkArgument(type.isEnum(), //
				"Field @Spec-type should be enum: %s (%s)", type.getName(), enumValue);

		@SuppressWarnings("unchecked")
		final Class> enumType = (Class>) type;

		return enumType;
	}

	static String[] extractAliases(final Field field) {

		checkNotNull(field, "field");

		final Spec fieldSpecAnnotation = field.getAnnotation(Spec.class);

		if (fieldSpecAnnotation == null) {

			return new String[0];

		} else {

			return fieldSpecAnnotation.alias();
		}
	}
}