[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