Skip to content

Instantly share code, notes, and snippets.

@asouza
Created October 17, 2009 22:54
Show Gist options
  • Save asouza/212480 to your computer and use it in GitHub Desktop.
Save asouza/212480 to your computer and use it in GitHub Desktop.
package br.com.atalho;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import org.mockito.Mockito;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InvocationHandler;
import net.vidageek.mirror.dsl.Mirror;
@SuppressWarnings("unchecked")
public class AtalhoAtributo implements InvocationHandler {
private List<Method> filaDeChamada;
@Override
public Object invoke(Object target, Method metodo, Object[] params)
throws Throwable {
if(metodo.getName().startsWith("get")){
filaDeChamada.add(metodo);
}
if (podeProxyficar(metodo.getReturnType())) {
return cria(metodo.getReturnType());
} else {
if(metodo.getReturnType().isEnum()){
return ((Object[]) new Mirror().on(metodo.getReturnType()).invoke()
.method("values").withoutArgs())[0];
}
else{
if(metodo.getReturnType().isPrimitive()){
return sendoORetornoPrimitivoSoFazChamarOMetodo(target, metodo,
params);
}
else{
return sendoFinalSoRetornaANovaInstancia(metodo);
}
}
}
}
public <T> T para(Class<T> clazz){
filaDeChamada = new ArrayList<Method>();
return cria(clazz);
}
public String stringfy(Object retornoDaChamadaDoMetodo) {
StringBuffer sequenciaDeChamadas = new StringBuffer();
for (Method method : filaDeChamada) {
sequenciaDeChamadas.append(
method.getName().substring(3, 4).toLowerCase()
+ method.getName().substring(4)).append(".");
}
return sequenciaDeChamadas.toString().replaceAll("\\.$", "");
}
private Object sendoORetornoPrimitivoSoFazChamarOMetodo(Object target,
Method metodo, Object[] params) throws IllegalAccessException,
InvocationTargetException {
//pega a Superclass para nao instanciar um proxyficado...
return metodo.invoke(new Mirror().on(target.getClass().getSuperclass()).invoke().constructor().withoutArgs(),params);
}
private Object sendoFinalSoRetornaANovaInstancia(Method metodo) {
return new Mirror().on(metodo.getReturnType()).invoke().constructor().withoutArgs();
}
private boolean podeProxyficar(Class type) {
return !type.isPrimitive() && !Modifier.isFinal(type.getModifiers()) && !type.isAnonymousClass();
}
private <T> T cria(Class<T> clazz) {
return (T) Enhancer.create(clazz, this);
}
}
package br.com.atalho;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
public class AtributoTest {
private AtalhoAtributo atalho;
@Before
public void setUp() {
atalho = new AtalhoAtributo();
}
@Test
public void deveriaRetornarOCaminhoDaChamada() {
Assert.assertEquals(
"situacao.evadido.avaliacao.motivoDaEvasao",
atalho.stringfy(atalho.para(Jovem.class).getSituacao()
.getEvadido().getAvaliacao().getMotivoDaEvasao()));
}
@Test
public void deveriaRetornarOCaminhoDaChamadaCasoOUltimoSejaUmaEnum() {
Assert.assertEquals(
"situacao.evadido.avaliacao.motivoDaEvasao.razaoDaEvasao",
atalho.stringfy(atalho.para(Jovem.class).getSituacao()
.getEvadido().getAvaliacao().getMotivoDaEvasao()
.getRazaoDaEvasao()));
}
@Test
public void deveriaRetornarOCaminhoCasoOUltimoSejaUmPrimtivo() {
Assert.assertEquals("quantos", atalho.stringfy(atalho.para(
Quantidade.class).getQuantos()));
}
@Test
public void deveriaRetornarOCaminhoCasoOUltimoSejaUmaClasseFinal() {
Assert.assertEquals("nome.nome", atalho.stringfy(atalho.para(
Jovem.class).getNome().getNome()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment