On 07.06.2016 14:55, Edd Grant wrote:
Hi folks,

Anyone have any ideas here? Wondering if the lack of response is due to
me phrasing the question badly, let me know if that's the case and I'll
try and re-word?

probably more because the usual suspects to answer this have been at the GR8 conference or simply busy ;)

[...]
    I am trying to control the behaviour exhibited by some of our POGOs
    when they are created using a Map constructor which contains keys
    that do NOT map to their properties e.g.

    class Person {
       String name
    }

    def person = new Person([name: 'Edd', age: 35])

    Normally the above would call propertyMissing() however I have
    discovered that I can define a trait (which the class then
    implements) and provide a default implementation of this method e.g.

    trait LogsUnknownProperties implements GroovyInterceptable {

         private static final Logger LOGGER =
    Logger.getLogger(LogsUnknownProperties)

         def propertyMissing(String name, value){
             LOGGER.warn("Class: ${this.class.name
    <http://this.class.name>} - Could not set property with name
    '${name}' having value '${value}' as property does not exist.")
         }
    }

you could also use propertyMissing and forget about GroovyInterceptable... still can use the trait of course

    This works brilliantly in mutable POGOs, however for POGOs which are
    annotated with @Immutable it doesn't work. From looking at the code
    in ImmutableASTTransformation.java this seems to be because the
    checkPropNames() method throws a MissingPropertyException:

    
https://github.com/groovy/groovy-eclipse/blob/master/base/org.codehaus.groovy20/src/org/codehaus/groovy/transform/ImmutableASTTransformation.java#L556

    Is there any way I can intercept the throwing of this exception so I
    can control the behaviour for @Immutable classes in the same way I
    can for mutable ones? I wondered if it could be achieved with a
    sprinkling of meta-programming but I'm not sure where to start looking?

if runtime meta-programming is good enough for you (not visible to Java), then you could do the following:

def constructor = Person.getConstructor(HashMap)
Person.metaClass.constrcutor = {Map m ->
   /* my logic here */
   orig.newInstance(myModifiedMap)
}

something like that. If you need that from the Java side as well, then I don“t think there is a solution

bye Jochen



Reply via email to