[prev in list] [next in list] [prev in thread] [next in thread]
List: groovy-dev
Subject: Re: [groovy-dev] dealing with missing groovy properties from java
From: Jeff Brown <brown_j () ociweb ! com>
Date: 2006-11-19 22:31:37
Message-ID: 4560DB49.6020201 () ociweb ! com
[Download RAW message or body]
I surrender. I will continue using the calls to DGM.getProperties that
we are using now.
Thanks again.
jb
Jochen Theodorou wrote:
> Jeff Brown schrieb:
>> See comments below...
>>
>> Jochen Theodorou wrote:
>>> Jeff Brown schrieb:
>>>>
>>>> I worked up a change to MetaClass and MetaClassImpl to add a
>>>> containsProperty method. The containsProperty method in
>>>> MetaClassImpl would be a simple one-liner like...
>>>>
>>>> public boolean containsProperty(String name) {
>>>> return propertyMap.containsKey(name);
>>>> }
>>>>
>>>> This way we can figure out if the property exists before trying to
>>>> access it.
>>>
>>> If the property is defined in getProperty, then this will fail. This
>>> way you get only the properties that are static available and the
>>> properties added through DGM.
> >
>> I am not sure I understand this. Can you explain an example of what
>> type of property would be available via DGM.getProperties() but would
>> not be found by calling the containsProperty method above?
>
> None
>
>> As far as I can tell, DGM.getProperties() returns a subset of what is
>> in the propertyMap (I thought DGM.getProperties was returning
>> everything in the propertyMap except for MetaFieldProperty
>> instances). I think I am misunderstanding something here.
>
> as said in other posts any Groovy class can overwrite getProperty and
> then react to any property request as it wants. For example I could
> return the number of characters of the property name, giving the class
> an infinite number of properties. None of these would be in the map. I
> normally call them dynamic poroperties, but since the MetaClass is
> alreday capable of adding per class properties at runtime and that
> mechanism is unrelated to the getProperty process... the name seems
> not to fit any more. I could call them programatic per instance
> properties... no nice name ;)
>
>>>> This is good because it lets us avoid relying on
>>>> MissingPropertyException for flow control. I also looked a little
>>>> at adding the containsProperty method to GroovyObject and I ended
>>>> up in org.codehaus.groovy.classgen.AsmClassGenerator and had a
>>>> little trouble figuring out exactly how to do what I wanted there.
>>>> I could probably sort it out if I spent some more time there.
>>>
>>> AsmClassGenerator is for bytecode generation only. You wanted to
>>> change the bytecode?
> >
>> I thought that is what would have to happen if this were to be added
>> to GroovyObject.
>
> The code for that is not in ACG, it is in Verifier#visitClass.
>
>>>> Moving forward, what about adding something like containsProperty
>>>> to MetaClass and/or GroovyObject?
>>>
>>> adding it to GroovyObject only means it is not available on Java
>>> classes. As these properties are mostly static I would add them to
>>> MetaClass. If you add them to GroovyObject, then you would have to
>>> ask the GroovyObject each time too and you would have to double the
>>> logic for the properties.
> >
>> I didn't picture having to duplicate any logic. I imagined that the
>> GroovyObject containsProperty method would be calling the
>> containsProperty method on the MetaClass.
>
> if it does, then there is no reason to add that to GroovyObject. But
> this way you don't get per instance properties.
>
>> What I worked up in MetaClass is all working and doing what I want.
>> Implementing the delegation in GroovyObject is the part I didn't
>> figure out how to make work. Adding the method to GroovyObject seems
>> like it might be a good idea, but even if the capability were just in
>> the MetaClass, that alone would be a big help.
>
> changing GroovyObject is critical and shouldn't be done if there is
> another solution.
>
>
>>> A neater way to add properties would be to add them to the
>>> MetaClass. like: metaClass.addProperty(name, getterClosure,
>>> setterClosure). That would also help to speed up the Property
>>> resolving process. Btw, same goes for methods
>>>
>> I am confused about how this relates to the problem of figuring out
>> if a GroovyObject contains a certain property, specifically the
>> ability to do this from Java.
>
> this way you can register properties, that will then show up in the
> map. This way you can avoid overwriting getProperty, and this way
> avoid also to add the same logic for getProperty, setProperty,
> containsProperty. Anyway, it seems you want only the statically
> defined properties in the class. Right?
>
>> I appreciate your thoughts on all of this. Clearly you have a better
>> understanding of the Groovy internals and I appreciate your help.
>> From my perspective it really seems like it would be nice to do
>> something like this...
>>
>> // myGroovyObject is a GroovyObject
>> boolean containsProperty =
>> myGroovyObject.containsProperty(somePropertyName);
>>
>> ...or...
>>
>> boolean containsProperty =
>> myGroovyObject.getMetaClass().containsProperty(somePropertyName);
>>
>> I think I can get what I need now by doing something like this...
>>
>> boolean containsProperty =
>> DefaultGroovyMethods.getProperties(myGroovyObject).containsKey(somePropertyName);
>>
>> I think that is workable but involves some indirection that seems
>> like it might not be necessary.
>
> Well, write a helper method then ;)
>
>> Going straight to the MetaClass and checking the propertyMap for a
>> certain key seems so much more efficient. Calling
>> DefaultGroovyMethods.getProperties() causes the collection of
>> properties to be iterated over at least 3 times, once in
>> DGM.getProperties(), once in DGM.getMetaPropertyValues() and once in
>> MetaClassImpl.getProperties().
>
> there is always the way:
>
>> class PropertyHelper {
>>
>> public static conatinsProperty(Object o, String property) {
>> MetaClass metaClass = InvokerHelper.getMetaClass(o);
>> List mps = metaClass.getProperties();
>> for (Iterator itr = mps.iterator(); itr.hasNext();) {
>> MetaProperty mp = (MetaProperty) itr.next();
>> if (mp.getName().equals(property)) return true; }
>> return false;
>> }
>> }
>
> the first line can be changed if you want to operate on GroovyObject
> only.. anyway, only 2 iterations. The iteration in MetaClassImpl is
> needed, or else fields would be shown as properties. For the
> MetaClassImpl, fields are properties without special getter/setter
> methods. But they are not properties in the way the eban specification
> defines them. So they have to be filtered out.
>
> Originally this method wasn't thought to be used from outside.
>
> bye blackdrag
>
--
Jeff Brown
brown_j@ociweb.com
Principal Software Engineer
Object Computing Inc.
http://www.ociweb.com/
Autism Strikes 1 in 250
Find The Cause ~ Find The Cure
http://www.autismspeaks.org/
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic