package pl.net.bluesoft.util.lang.cquery;
import pl.net.bluesoft.util.lang.Pair;
import pl.net.bluesoft.util.lang.cquery.func.F;
import pl.net.bluesoft.util.lang.cquery.func.F2;
import java.lang.reflect.Method;
import java.text.MessageFormat;
/**
* User: POlszewski
* Date: 2011-07-29
*/
public final class Selectors<T> {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static F<Object, Object> prop(final String property) {
return new Get(property);
}
public static <T, P> F<T, P> prop(final String property, Class<P> clazz) {
return new Get<T, P>(property);
}
private static class Get<T, P> implements F<T, P> {
private final String property;
private Method getAccessor;
public Get(String property) {
this.property = property;
}
@SuppressWarnings("unchecked")
@Override
public P invoke(T x) {
if (getAccessor == null) {
getAccessor = extractAccessor(x, property);
}
try {
return (P)getAccessor.invoke(x);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static Method extractAccessor(Object x, String property) {
String Property = Character.toUpperCase(property.charAt(0)) + property.substring(1);
try {
return x.getClass().getMethod("get" + Property);
}
catch (Exception e) {
try {
return x.getClass().getMethod("is" + Property);
}
catch (Exception e1) {
throw new RuntimeException(e);
}
}
}
@SuppressWarnings("unchecked")
public static F<Object, Object> identity() {
return (F<Object, Object>)identity;
}
@SuppressWarnings("unchecked")
public static <T> F<T, T> identity(Class<T> clazz) {
return (F<T,T>)identity;
}
public static <T> F<T, String> format(final String format) {
return new F<T, String>() {
@Override
public String invoke(T x) {
return MessageFormat.format(format, x);
}
};
}
public static F2<Object, Object, Object[]> arrayPair() {
return arrayPair;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T1, T2> F2<T1, T2, Pair<T1, T2>> pair(Class<T1> leftClazz, Class<T2> rightClazz) {
return (F2)pair;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static F2<Object, Object, Pair<Object, Object>> pair() {
return (F2)pair;
}
private static final F2<Object, Object, Object[]> arrayPair = new F2<Object, Object, Object[]>() {
@Override
public Object[] invoke(Object x, Object y) {
return new Object[] { x, y };
}
};
@SuppressWarnings({ "unchecked", "rawtypes" })
private static final F2<?, ?, Pair> pair = new F2() {
@Override
public Object invoke(Object x, Object y) {
return new Pair(x, y);
}
};
@SuppressWarnings("rawtypes")
private static final F<?,?> identity = new F() {
@Override
public Object invoke(Object x) {
return x;
}
};
}