Wow, this works... (A bean property annotation for Java)

Ok, I've added a few more features (the ability to call an external method prior to actually setting the value). I've also found out that there will not be any IDE support available yet. Netbeans will not have JSR269 support until 6.0, and Eclipse will not have the support until 3.3. Bummer.

Right now this works with javac from JDK 6, need to try it in various IDEs to see if it will work as well. (Yes, I understand this is against the specification for JSR269 [no preprocessing annotations]).

[pfnguyen@ares panno]$ ls
A.java  B.java
[pfnguyen@ares panno]$ cat A.java
import com.hanhuy.panno.Property;

import java.sql.SQLException;

public class A {
    private @Property String fool = "I pity the foo!";
    private @Property boolean alwaysRight = false;

    private @Property(useGet = true) boolean booleanWithGet = false;

    // preCallMethod can also point to another object, e.g. "someObject.method"
    @Property(preCallMethod = "genericValidator",
              preCallThrows = "SQLException")
    private int constrainedProperty = 42;

    public A() {
        System.out.println("A<init>: " + getFool());
    }

    private void genericValidator(
            A source, String property, int oldValue, int newValue)
    throws SQLException {

        System.out.println(
                "Attempting to modify '" + property + "' to " + newValue);

        if (newValue != 54)
            throw new SQLException(
                    "This is some arbitrary exception: " + newValue);
    }
}
[pfnguyen@ares panno]$ cat B.java
import java.sql.SQLException;

public class B {
    public static void main(String args[]) {
        A a = new A();
        System.out.println(a.getFool());
        a.setFool("I am not a fool");
        System.out.println(a.getFool());
        System.out.println(a.isAlwaysRight());
        a.setAlwaysRight(true);
        System.out.println(a.isAlwaysRight());
        System.out.println(a.getBooleanWithGet());
        System.out.println(a.getConstrainedProperty());
        try {
            a.setConstrainedProperty(54);
        }
        catch (SQLException e) {
            System.out.println("This should not happen yet!");
        }
        try {
            a.setConstrainedProperty(42);
        }
        catch (SQLException e) {
            System.out.println("Got expected exception: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
[pfnguyen@ares panno]$ javac -cp ~/development/panno/build/hanhuy-panno.jar *.java
[pfnguyen@ares panno]$ java -cp . B
A<init>: I pity the foo!
I pity the foo!
I am not a fool
false
true
false
42
Attempting to modify 'constrainedProperty' to 54
Attempting to modify 'constrainedProperty' to 42
Got expected exception: This is some arbitrary exception: 42
java.sql.SQLException: This is some arbitrary exception: 42
        at A.genericValidator(A.java:28)
        at A.setConstrainedProperty(A.java:13)
        at B.main(B.java:21)
[pfnguyen@ares panno]$ javap A
Compiled from "A.java"
public class A extends java.lang.Object{
    public A();
    public void setFool(java.lang.String);
    public java.lang.String getFool();
    public void setAlwaysRight(boolean);
    public boolean isAlwaysRight();
    public void setBooleanWithGet(boolean);
    public boolean getBooleanWithGet();
    public void setConstrainedProperty(int)       throws java.sql.SQLException;
    public int getConstrainedProperty();
}

Comments: 6

#6 Christian B wrote on Monday, October 3, 2011 at 6:07 PM

Where is the implementation for your @Property

Did I just miss it on page?

#5 Authenticated User Perry Nguyen wrote on Tuesday, August 11, 2009 at 4:05 PM

I haven't looked into making this work any further, my code was basically just a proof-of-concept.

You may want to take a look at Project Lombok - http://projectlombok.org/

#4 Florian Brunner wrote on Tuesday, August 11, 2009 at 9:26 AM

Hi, this sounds very interesting! Can you show the code how you implemented it? Could you make the NetBeans IDE to support it?

#3 Strider80 wrote on Saturday, November 24, 2007 at 7:41 PM

Great idea, and of course you don't need Sun's support to start using your own annotations and annotation processor.

I replied with some more ideas and suggestions on your forum post here http://forum.java.sun.com/thread.jspa?messageID=9986112

(Also I'm very interested in seeing relevant parts of your implementation of the annotation processor because I'm kind of new at that.)

#2 Authenticated User Perry Nguyen wrote on Friday, May 18, 2007 at 3:13 PM

With regard to IDE support, I believe if I can use the same approach for injecting the methods into the AST for the IDE as I do for javac then IDE support will be a non-issue.

The big problem is just figuring out the appropriate APIs to use to make this happen. Since JSR269 explicitly disallows this, I need to find some backdoor mechanisms. This varies by IDE. Hopefully, Netbeans 6.0 will work out of the box, since it practically uses the unmodified compiler (and will include JSR269 support)

I will try hacking at Eclipse 3.3 when I get more time.

#1 Andrew Eisenberg wrote on Wednesday, May 16, 2007 at 10:43 AM

This is a great idea. Please keep at it. It would be great to have something like this (almost) supported in the JDK.

Also regarding IDE support, a problem will be eager parsing of the files. When editing, there will be lots of squiggly lines under all the get and set methods because they don't exist when editing.

Eclipse 3.3M7 has the JSR 269 interfaces mapped out and the proper compiler hooks, but it's not documented yet.

Comment

No HTML is allowed. Numeric entity refs (&#nnnn;) are supported. Use {{{ and }}} to delimited preformatted sections. Items noted by * are mandatory.

Identify yourself

All new comments are moderated for spam protection. Email addresses are visible only to the entry owner and administrators.

  • Use AccessKey-P to Preview and AccessKey-S to Post