Avatar billede kernelx Juniormester
22. april 2013 - 11:32 Der er 3 kommentarer og
1 løsning

Javassist og methodwrapper

Jeg har en class FooEntity og Bar:
-------------------------
public class FooEntity {

    private String foo;
    private String bar;

    public String getFoo() {return foo;}
    public void setFoo(String foo) {this.foo = foo;}

    public String getBar() {return bar;}
    public void setBar(String bar) {this.bar = bar;}
}

public class Bar {

    public boolean isBar(String propertyName) {
      return "bar".equals(propertyName);
    }

}
-------------------------

Nu vil jeg adde en field som har type Bar. Desuden vil jeg wrappe mine getter og setter.
Resultatet skal ligne noget i denne stil:


-------------------------
public class FooEntity {

    private String foo;
    private String bar;
    private Bar b; // ny field

    public String getFoo() {
        if (b.isBar("foo")) {
            return null;
        }
        return foo;
    }

    public void setFoo(String foo) {
        if (b.isBar("foo")) {
            return;
        }
        this.foo = foo;
    }

    public String getBar() {
        if (b.isBar("bar")) {
            return null;
        }
        return bar;
    }

    public void setBar(String bar) {
        if (b.isBar("bar")) {
            return;
        }
        this.bar = bar;
    }
}
-------------------------

...

public static void main(String[] args) throws Exception {
    // change FooEntity with javassist
    Bar b = new Bar();
    FooEntity fooEntity = new FooEntity();
    Field bField = fooEntity.getDeclaredField("b");
    bField.set(fooEntity, b);
    fooEntity.setFoo("abc");
    fooEntity.setBar("abc");
    System.out.println(fooEntity.getFoo()); // null
    System.out.println(fooEntity.getBar()); // "bar"
}

...

Mine spoergsmaal er:

1. Hvordan kan jeg adde et field som har en Type som ikke er primitiv?

2. Hvordan kan jeg wrappe en eksisterende method?

Mange tak og venlig hilsen
KernelX
Avatar billede arne_v Ekspert
23. april 2013 - 01:12 #1
Eksempel taet paa dit:


package hack;

public class FooEntity {
    private Long id;
    private String fooBar;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFooBar() {
        return fooBar;
    }
    public void setFooBar(String fooBar) {
        this.fooBar = fooBar;
    }
}




package hack;

public class Bar {
    public boolean isWhatever() {
        return true;
    }
}




package hack;

public interface HasBar {
    public Bar getBar();
    public void setBar(Bar b);
}




package hack;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtNewMethod;
import javassist.NotFoundException;

public class ClassHack3 {
    public static void main(String[] args) throws NotFoundException, CannotCompileException {
        ClassPool pool = ClassPool.getDefault();
        CtClass cc = pool.get("hack.FooEntity");
        cc.addField(new CtField(pool.get("hack.Bar"), "b", cc));
        cc.addInterface(pool.get("hack.HasBar"));
        cc.addMethod(CtNewMethod.make("public hack.Bar getBar() { return b; }", cc));
        cc.addMethod(CtNewMethod.make("public void setBar(hack.Bar b) { this.b = b; }", cc));
        cc.getDeclaredMethod("getFooBar").setBody("if(b.isWhatever()) return \"fake\"; else return fooBar;");
        cc.toClass();
        FooEntity o = new FooEntity();
        o.setId(1L);
        o.setFooBar("ABC");
        ((HasBar)o).setBar(new Bar());
        System.out.println(o.getId() + " " + o.getFooBar() + " " + ((HasBar)o).getBar());
    }
}
Avatar billede kernelx Juniormester
11. maj 2013 - 20:46 #2
Mange tak! Husk at skrive et eller andet som svar
Avatar billede arne_v Ekspert
11. maj 2013 - 23:00 #3
svar
Avatar billede arne_v Ekspert
12. maj 2013 - 15:39 #4
Der er andre frameworks end JavaAssist, men fordi JA bruger Java source code, saa synes jeg at det er ret nemt at bruge.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester