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