package fr.mch.mdo.restaurant.dao.hibernate; import java.beans.PropertyDescriptor; import java.util.List; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.beanutils.expression.Resolver; import org.hibernate.HibernateException; import org.hibernate.transform.ResultTransformer; import fr.mch.mdo.restaurant.beans.IMdoBean; import fr.mch.mdo.restaurant.dao.beans.OrderLine; /** * Result transformer that allows to transform a result to * a user specified class which will be populated via setter * methods or fields matching the alias name. * The resultBeanTemplate bean is used for being sure that nested property bean is not null. * So when alias has nested property, do not forget to instantiate the nested beans. * * @author mathieu * */ public class MdoAliasToBean implements ResultTransformer { /** * */ private static final long serialVersionUID = 1L; private Class<? extends IMdoBean> resultTemplateClass; private String[] suppliedAliases; public MdoAliasToBean(Class<? extends IMdoBean> resultTemplateClass) { if (resultTemplateClass == null) { throw new IllegalArgumentException("resultTemplateClass cannot be null"); } this.resultTemplateClass = resultTemplateClass; } public MdoAliasToBean(Class<? extends IMdoBean> resultTemplateClass, String[] suppliedAliases) { if (resultTemplateClass == null) { throw new IllegalArgumentException("resultTemplateClass cannot be null"); } this.resultTemplateClass = resultTemplateClass; this.suppliedAliases = suppliedAliases; } public Object transformTuple(Object[] tuple, String[] aliases) { Object result; String[] selectedAliases = this.suppliedAliases; if (selectedAliases == null) { selectedAliases = aliases; } try { result = resultTemplateClass.newInstance(); for (int i = 0; i < selectedAliases.length; i++) { String alias = selectedAliases[i]; Object value = tuple[i]; if (value != null) { // When alias has nested property, do not forget to instantiate the nested beans. newInstanceForNullNestedProperty(result, alias); PropertyUtils.setNestedProperty(result, alias, value); } } } catch (Exception e) { throw new HibernateException("Could not instantiate resultclass: " + resultTemplateClass.getName()); } return result; } private void newInstanceForNullNestedProperty(Object bean, String property) throws Exception { Resolver resolver = BeanUtilsBean.getInstance().getPropertyUtils().getResolver(); while (resolver.hasNested(property)) { String nestedProperty = resolver.next(property); // Get the nested bean Object nestedBean = PropertyUtils.getNestedProperty(bean, nestedProperty); if (nestedBean == null) { PropertyDescriptor nestedPropertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, nestedProperty); // Instance nested bean because it is null nestedBean = nestedPropertyDescriptor.getPropertyType().newInstance(); // Set the new instance to the current bean PropertyUtils.setNestedProperty(bean, nestedProperty, nestedBean); } // Switch the current bean bean = nestedBean; // Remove the current property property = resolver.remove(property); } } public static void main(String[] args) throws Exception { Object bean = new OrderLine(); String property = "productSpecialCode.code.name"; MdoAliasToBean alias = new MdoAliasToBean(OrderLine.class); alias.newInstanceForNullNestedProperty(bean, property); Resolver resolver = BeanUtilsBean.getInstance().getPropertyUtils().getResolver(); System.out.println(resolver.hasNested("property")); // Object aliasValue = PropertyUtils.getNestedProperty(result, alias); // BeanUtilsBean.getInstance().getPropertyUtils().getResolver().hasNested(alias); // if (aliasValue != null) { // PropertyUtils.setNestedProperty( // } } @SuppressWarnings("rawtypes") @Override public List transformList(List collection) { return collection; } }