Skip to content

Instantly share code, notes, and snippets.

@danielpassos
Last active August 31, 2018 14:12
Show Gist options
  • Save danielpassos/538448 to your computer and use it in GitHub Desktop.
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
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