package ru.hflabs.rcd.index;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
/**
* Класс <class>IndexedField</class> реализует описание индексированного поля
*
* @see ru.hflabs.rcd.model.annotation.Indexed.Field
*/
public abstract class IndexedField {
/*
* Доступные статусы
*/
public static final int FILTERABLE = 0b001;
public static final int SEARCHABLE = 0b010;
public static final int SORTABLE = 0b101;
/** Статус индексирования поля */
private int state;
public IndexedField(int state) {
this.state = state;
}
/**
* @return Возвращает отслеживаемый сервис доступа к индекстированному полю
*/
public abstract Member getMember();
/**
* @return Возвращает название поля
*/
public abstract String getName();
/**
* @return Возвращает тип поля
*/
public abstract Class<?> getType();
/**
* Проверяет и возвращает <code>TRUE</code>, если флаг поля установлен
*
* @param targetFlag проверяемый статус
* @return Возвращает флаг проверки
*/
public boolean isStateEnabled(int targetFlag) {
return (state & targetFlag) == targetFlag;
}
/**
* Класс <class>ByField</class> реализует описание индексированного поля на основе {@link Field реального поля} класса
*/
public static class ByField extends IndexedField {
/** Отслеживаемое поле */
private final Field field;
public ByField(int state, Field field) {
super(state);
this.field = field;
}
@Override
public Member getMember() {
return field;
}
@Override
public String getName() {
return field.getName();
}
@Override
public Class<?> getType() {
return ClassUtils.resolvePrimitiveIfNecessary(field.getType());
}
}
/**
* Класс <class>ByMethod</class> реализует описание индексированного поля на основе {@link Method метода} класса
*/
public static class ByMethod extends IndexedField {
/** Название переменной */
private final String name;
/** Отслеживаемый метод */
private final Method method;
public ByMethod(int state, String name, Method method) {
super(state);
this.name = name;
this.method = method;
}
@Override
public Member getMember() {
return method;
}
@Override
public String getName() {
return name;
}
@Override
public Class<?> getType() {
return ClassUtils.resolvePrimitiveIfNecessary(method.getReturnType());
}
}
/**
* Класс <class>ByAlias</class> реализует описание индексированного поля, ссылаясь на другое поле, используя псевдоним
*/
public static class ByAlias extends IndexedField {
/** Название поля */
private final String alias;
/** Делегат поля */
private final IndexedField delegate;
public ByAlias(String alias, IndexedField delegate) {
super(delegate.state);
this.alias = alias;
this.delegate = delegate;
}
@Override
public Member getMember() {
return delegate.getMember();
}
@Override
public String getName() {
return alias;
}
@Override
public Class<?> getType() {
return delegate.getType();
}
}
}