package com.mysema.query.sql; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.ArrayUtils; import com.mysema.query.sql.RelationalPath; import com.mysema.query.types.Expression; import com.mysema.query.types.ExpressionBase; import com.mysema.query.types.FactoryExpression; import com.mysema.query.types.QBean; import com.mysema.query.types.Visitor; /** * Expression used to project a list of beans * * @author luis */ public class QBeans extends ExpressionBase implements FactoryExpression { private static final long serialVersionUID = -4411839816134215923L; private final Map, QBean> qBeans = new LinkedHashMap, QBean>(); private final List> expressions = new ArrayList>(); @SuppressWarnings("unchecked") public QBeans(RelationalPath... beanPaths) { super(Beans.class); try { for (RelationalPath path : beanPaths) { Map> bindings = new LinkedHashMap>(); for (Field field : path.getClass().getFields()) { if (Expression.class.isAssignableFrom(field.getType()) && !Modifier.isStatic(field.getModifiers())) { field.setAccessible(true); Expression column = (Expression) field.get(path); bindings.put(field.getName(), column); expressions.add(column); } } qBeans.put(path, new QBean(path.getType(), bindings)); } } catch (Exception e) { throw new IllegalStateException(e); } } @Override public R accept(Visitor v, C context) { return v.visit(this, context); } @Override public List> getArgs() { return expressions; } @Override public Beans newInstance(Object... args) { int offset = 0; Map, Object> beans = new HashMap, Object>(); for (Map.Entry, QBean> entry : qBeans.entrySet()) { RelationalPath path = entry.getKey(); QBean qBean = entry.getValue(); int argsSize = qBean.getArgs().size(); Object[] subArgs = ArrayUtils.subarray(args, offset, offset + argsSize); beans.put(path, qBean.newInstance(subArgs)); offset += argsSize; } return new Beans(beans); } }