Wicket
  1. Wicket
  2. WICKET-1327

CompoundModel backed by cglib proxies

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Later
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: wicket
    • Labels:
      None

      Description

      This is a simple model that lets cglib handle building the propertyExpression.

      1. matej_and_johan_great_work_in_thailand.jar
        5 kB
        Johan Compagner
      2. Model.zip
        6 kB
        Scott Swank
      1.
      cache created proxy classes Sub-task Resolved Unassigned
       

        Activity

        Hide
        Martin Grigorov added a comment -

        Closing the ticket as "Later" because there is no much traffic in this ticket lately.

        There are few other similar solutions described at https://cwiki.apache.org/WICKET/working-with-wicket-models.html#WorkingwithWicketmodels-RefactorSafePropertyModels

        Show
        Martin Grigorov added a comment - Closing the ticket as "Later" because there is no much traffic in this ticket lately. There are few other similar solutions described at https://cwiki.apache.org/WICKET/working-with-wicket-models.html#WorkingwithWicketmodels-RefactorSafePropertyModels
        Hide
        James Carman added a comment -

        Would you be willing to implement this using Apache Commons Proxy? It would take all of the proxying logic (CGLIB stuff) out of your code and it would also allow you (or the user) to switch proxying technologies altogether. Let me know if you want an example.

        Show
        James Carman added a comment - Would you be willing to implement this using Apache Commons Proxy? It would take all of the proxying logic (CGLIB stuff) out of your code and it would also allow you (or the user) to switch proxying technologies altogether. Let me know if you want an example.
        Hide
        Scott Swank added a comment -

        Because the ExpressionBuilder has a cglib proxy it is not Serializable. This means that we want to evaluate the expression and serialize the resulting String. Because we don't know when the recording is complete, we need to hook into the jvm's serialization process via writeObject() to ensure that we have a String instead of an ExpressionBuilder.

        String getPropertyExpression()
        {
        // If not yet evaluated, then do so now and then
        // discard the expression builder since it is no longer useful
        // and is not Serializable
        if (propertyExpression == null)

        { propertyExpression = expressionBuilder.eval(); expressionBuilder = null; }

        return propertyExpression;
        }

        private void writeObject(ObjectOutputStream out) throws IOException

        { // PropertyExpressionBuilder is not serializable, but the String it // generates is. Hence we must call getPropertyExpression() before // serialization. getPropertyExpression(); out.defaultWriteObject(); }
        Show
        Scott Swank added a comment - Because the ExpressionBuilder has a cglib proxy it is not Serializable. This means that we want to evaluate the expression and serialize the resulting String. Because we don't know when the recording is complete, we need to hook into the jvm's serialization process via writeObject() to ensure that we have a String instead of an ExpressionBuilder. String getPropertyExpression() { // If not yet evaluated, then do so now and then // discard the expression builder since it is no longer useful // and is not Serializable if (propertyExpression == null) { propertyExpression = expressionBuilder.eval(); expressionBuilder = null; } return propertyExpression; } private void writeObject(ObjectOutputStream out) throws IOException { // PropertyExpressionBuilder is not serializable, but the String it // generates is. Hence we must call getPropertyExpression() before // serialization. getPropertyExpression(); out.defaultWriteObject(); }
        Hide
        Johan Compagner added a comment -

        with this attachement you can do this:

        SafePropertyModel<Person> p = new SafePropertyModel<Person>(new Person());
        TextField field = new TextField("name", p.bind(p.property().getFirstName()));

        Show
        Johan Compagner added a comment - with this attachement you can do this: SafePropertyModel<Person> p = new SafePropertyModel<Person>(new Person()); TextField field = new TextField("name", p.bind(p.property().getFirstName()));
        Hide
        Blake Minghelli added a comment -

        Scott Swank posted this model implementation on my behalf. Please accept this as authorization to treat this as an open contribution to Wicket.

        Show
        Blake Minghelli added a comment - Scott Swank posted this model implementation on my behalf. Please accept this as authorization to treat this as an open contribution to Wicket.
        Hide
        Igor Vaynberg added a comment -

        property1.property2 should be no problem considering there are getProperty1() that returns an object which has getProperty2(), this is handled by a simple builder pattern where getProperty1() returns a builder proxy of object that has getProperty2() and keeps context.

        mylist.0 will be tricky for arrays, not sure if we can intercept myarray[5].getfoo(). we can intercept getfoo() obviously, but myarray[5]?

        property[key] should also be ok, the builderproxy returned for set or map can keep track of get calls.

        Show
        Igor Vaynberg added a comment - property1.property2 should be no problem considering there are getProperty1() that returns an object which has getProperty2(), this is handled by a simple builder pattern where getProperty1() returns a builder proxy of object that has getProperty2() and keeps context. mylist.0 will be tricky for arrays, not sure if we can intercept myarray [5] .getfoo(). we can intercept getfoo() obviously, but myarray [5] ? property [key] should also be ok, the builderproxy returned for set or map can keep track of get calls.
        Hide
        Frank Bille Jensen added a comment -

        Only having looked briefly at it, it looks quite cool. I'm all for putting in extensions to begin with until we know what to do with it. And I wouldn't be against replacing property model and friends with this if it proves to be same performance and that users like it.

        How will it handle expressions like these (this is what property resolver handles atm):

        "property1.property2"
        "mylist.0"
        "property[key]"

        Show
        Frank Bille Jensen added a comment - Only having looked briefly at it, it looks quite cool. I'm all for putting in extensions to begin with until we know what to do with it. And I wouldn't be against replacing property model and friends with this if it proves to be same performance and that users like it. How will it handle expressions like these (this is what property resolver handles atm): "property1.property2" "mylist.0" "property [key] "
        Hide
        Igor Vaynberg added a comment -

        if we start going down this road we can also have an alternative property resolver that generates bytecode to directly access fields instead of reflection. maybe put this into wicket-something.

        Show
        Igor Vaynberg added a comment - if we start going down this road we can also have an alternative property resolver that generates bytecode to directly access fields instead of reflection. maybe put this into wicket-something.
        Hide
        Scott Swank added a comment -

        Proof of concept implementation.

        Show
        Scott Swank added a comment - Proof of concept implementation.

          People

          • Assignee:
            Unassigned
            Reporter:
            Scott Swank
          • Votes:
            4 Vote for this issue
            Watchers:
            9 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development