Last active
August 31, 2018 14:12
-
-
Save danielpassos/538448 to your computer and use it in GitHub Desktop.
[AliasToBeanResultTransformer] Extende as funcionalidades do AliasToBeanResultTransformer do Hibernate permitindo atribuir valores em diversos niveis. #hibernate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Collection; | |
import java.util.List; | |
import net.vidageek.mirror.dsl.Mirror; | |
import org.hibernate.HibernateException; | |
import org.hibernate.transform.ResultTransformer; | |
/** | |
* | |
* Extende as funcionalidades do <a href="http://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/transform/AliasToBeanResultTransformer.html"> | |
* AliasToBeanResultTransformer</a> do Hibernate permitindo atribuir valores em diversos niveis. | |
* | |
* @author Daniel Passos ( [email protected] ) | |
* | |
*/ | |
public class AliasToBeanResultAdvancedTransformer implements ResultTransformer { | |
private static final long serialVersionUID = 6908300000610725645L; | |
private final Class resultClass; | |
private final boolean useAcessores; | |
public AliasToBeanResultAdvancedTransformer(Class resultClass) { | |
if(resultClass == null) { | |
throw new IllegalArgumentException("resultClass cannot be null"); | |
} | |
this.resultClass = resultClass; | |
this.useAcessores = true; | |
} | |
public AliasToBeanResultAdvancedTransformer(Class resultClass, boolean useAcessores) { | |
if(resultClass == null) { | |
throw new IllegalArgumentException("resultClass cannot be null"); | |
} | |
this.resultClass = resultClass; | |
this.useAcessores = useAcessores; | |
} | |
public Object transformTuple(Object[] tuple, String[] aliases) { | |
Object result; | |
try { | |
result = resultClass.newInstance(); | |
for (int i = 0; i < aliases.length; i++) { | |
this.verifyDispatch(result, aliases[i], tuple[i]); | |
} | |
} catch (IllegalAccessException e) { | |
throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName()); | |
} catch (InstantiationException e) { | |
throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName()); | |
} | |
return result; | |
} | |
public List transformList(List collection) { | |
return collection; | |
} | |
/** | |
* | |
* Verifica pra onde enviar a chamada para setar a propriedade | |
* | |
* @author Daniel Passos ( [email protected] ) | |
* | |
* @param result Objeto onde o valor ser� adicionado | |
* @param alias Nome do atributo a ser populado | |
* @param value Valor a ser inserido no atributo | |
* | |
*/ | |
private void verifyDispatch(Object result, String alias, Object value) { | |
// pra que setar um valor null se este ja e o padrao? | |
if( value == null ) { | |
return; | |
} | |
if( alias.indexOf(".") == -1 ) { | |
this.setValue(result, alias, value); | |
} else { | |
this.setValueOfManyLevel(result, alias.split("[.]"), 0, value); | |
} | |
} | |
/** | |
* | |
* Seta o valor da propriedade ( alias ) dentro da entidade ( result ) | |
* de acordo com o tipo de acesso solicitado | |
* | |
* @author Daniel Passos ( [email protected] ) | |
* | |
* @param target Objeto onde o valor será adicionado | |
* @param fieldName Nome do atributo a ser populado | |
* @param value Valor a ser inserido no atributo | |
* | |
*/ | |
private void setValue(Object target, String fieldName, Object value) { | |
if (useAcessores) { | |
new Mirror().on(target).invoke().setterFor(fieldName).withValue(value); | |
} else { | |
new Mirror().on(target).set().field(fieldName).withValue(value); | |
} | |
} | |
/** | |
* | |
* Instancia as entidades dentro da resulClass ate chegar ao ultimo | |
* nivel e podem setar a propriedade dentro da ultima entidade | |
* | |
* @author Daniel Passos ( [email protected] ) | |
* | |
* @param result Objeto onde o valor ser� adicionado | |
* @param levels Nivel hierarquico dos atributos dentro do resulClass | |
* @param indexOfLevel Indice dentro do level | |
* @param value Valor a ser inserido no atributo | |
* | |
*/ | |
private void setValueOfManyLevel(Object result, String[] levels, int indexOfLevel, Object value) { | |
// Se for o ultimo nivel do alias e hora de popular o atributo | |
if( indexOfLevel == (levels.length - 1) ) { | |
if( result instanceof Collection ) { | |
// TODO | |
} else { | |
setValue(result, levels[indexOfLevel], value); | |
} | |
} else { | |
Object destination = createNewInstanceOfAtributeIfNotExists(result, levels[indexOfLevel]); | |
setValueOfManyLevel(destination, levels, indexOfLevel + 1, value); | |
} | |
} | |
/** | |
* | |
* Cria uma nova instancia de uma determinada entidade | |
* dentro da classe caso esta ainda não exista | |
* | |
* @author Daniel Passos ( [email protected] ) | |
* | |
* @param target Instancia onde o novo atributo vai ser criado | |
* @param fieldName Nome do atributo a ser criado | |
* | |
* @return | |
* | |
*/ | |
@SuppressWarnings("unchecked") | |
private Object createNewInstanceOfAtributeIfNotExists(Object target, String fieldName) { | |
Class typeOfField = new Mirror().on(target.getClass()).reflect().field(fieldName).getType(); | |
Object instanceOfField = null; | |
if( useAcessores ) { | |
instanceOfField = new Mirror().on(target).invoke().getterFor(fieldName); | |
} else { | |
instanceOfField = new Mirror().on(target).get().field(fieldName); | |
} | |
// Caso o campo esteja nulo seta a nova instanca nele, caso contrario mante a antiga | |
if( instanceOfField == null ) { | |
instanceOfField = new Mirror().on(typeOfField).invoke().constructor().withoutArgs(); | |
setValue(target, fieldName, instanceOfField); | |
} | |
return instanceOfField; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment