groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Keegan Witt <keeganw...@gmail.com>
Subject Re: Groovy doesn't follow java beans specification on certain edge cases?
Date Tue, 02 Jun 2015 14:49:37 GMT
Actually, I'd like to amend my previous comments.  The method I mentioned
is *not* what Groovy uses to generate getter/setter names as my answer
might have seemed to imply.  However, it is related.

The code that Groovy uses to generate the getter/setter name is "get" /
"is" / "set" +
org.codehaus.groovy.runtime.MetaClassHelper.capitalize(fieldName)
<https://github.com/apache/incubator-groovy/blob/master/src/main/org/codehaus/groovy/runtime/MetaClassHelper.java>.
The code mentions that GROOVY-3211
<https://issues.apache.org/jira/browse/GROOVY-3211> discusses this, and
part of the reason is because they use the *decapitalize* method I
previously mentioned to extract the original field name.  If cName had been
translated to [s/g]etCName, then *decapitalize* would have resolved to
CName, which was not the original property name.

I still hold that Groovy is doing the correct thing here.  Eclipse
<https://bugs.eclipse.org/bugs/show_bug.cgi?id=154823>, Netbeans
<https://netbeans.org/bugzilla/show_bug.cgi?id=165241>, IntelliJ
<https://youtrack.jetbrains.com/issue/IDEA-65251>, and many others have
reached the same conclusion.  Although interestingly, Lombok decided
<https://code.google.com/p/projectlombok/issues/detail?id=722>, after some
discussion
<https://groups.google.com/forum/#!topic/project-lombok/c9WKYhlfe8k>, that
there was no consensus on this question.  One of their principle arguments
was that Java itself was inconsistent (and it kind of is), with
*PropertyDescriptor*'s use of *java.beans.NameGenerator.capitalize* vs the
behavior of *java.beans.Introspector.**decapitalize*.

As a workaround, I suggest you do

*class Foo {*
*    String cName*
*}*
*new java.beans.PropertyDescriptor('cName', Foo,
groovy.lang.MetaProperty.getGetterName('cName', String),
groovy.lang.MetaProperty.getSetterName('cName'))*

Kinda a pain, but there's nothing Groovy can do at this point.  Blame Sun.

-Keegan

On Tue, Jun 2, 2015 at 9:07 AM, Miro Bezjak <bezjak.miro@gmail.com> wrote:

> For future viewers: while PropertyDescriptor doesn't seem to work in this
> case, Introspector.getBeanInfo works properly.
>
> -----------------------------------
> class Foo {
>     String cName
> }
>
> def info = java.beans.Introspector.getBeanInfo(Foo)
> println info.propertyDescriptors*.name // [cName, class, metaClass]
> -----------------------------------
>
> Regards,
> Miro
>
> On Mon, Jun 1, 2015 at 5:31 PM, Owen Rubel <orubel@gmail.com> wrote:
>
>> You da man Keegan!
>>
>> Owen Rubel
>> 415-971-0976
>> orubel@gmail.com
>>
>> On Mon, Jun 1, 2015 at 8:18 AM, Keegan Witt <keeganwitt@gmail.com> wrote:
>>
>>> Section 8.8 of the spec
>>> <http://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/>
is
>>> unclear on the proper capitalization in cases like you've described.
>>> However, if you examine the java.beans.Introspector.decapitalize(String
>>> name) source
>>> <http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/beans/Introspector.java>,
>>> you'll find that Groovy follows the convention as implemented in the
>>> JDK (my guess is Groovy probably calls that exact method somewhere).  As
>>> such, I believe Groovy's behavior is correct as-implemented.
>>>
>>> -Keegan
>>>
>>> On Fri, May 29, 2015 at 10:17 AM, Miro Bezjak <bezjak.miro@gmail.com>
>>> wrote:
>>>
>>>> If by property name you mean: field name (not relevant in this case) +
>>>> getter name + setter name, then yes.
>>>>
>>>> That is, for `cName`, groovy generates: `getcName` and `setcName`. But
>>>> it should (probably?) generate: `getCName` and `setCName`.
>>>>
>>>> Regards,
>>>> Miro
>>>>
>>>> On Fri, May 29, 2015 at 3:39 PM, Jochen Theodorou <blackdrag@gmx.org>
>>>> wrote:
>>>>
>>>>> Am 29.05.2015 15:32, schrieb Miro Bezjak:
>>>>> [...]
>>>>>
>>>>>> As far as I can see, this only affects java.beans. The following
>>>>>> example
>>>>>> works without any problem:
>>>>>> --------------------------------------
>>>>>> class Foo {
>>>>>>      String cName
>>>>>> }
>>>>>>
>>>>>> def f = new Foo()
>>>>>> f.cName = 'abc'
>>>>>> println f.cName // abc
>>>>>> --------------------------------------
>>>>>>
>>>>>>
>>>>>> One workaround is to define proper getter and setter:
>>>>>> --------------------------------------
>>>>>> class Foo {
>>>>>>      String cName
>>>>>>
>>>>>>      String getCName() { cName }
>>>>>>      void setCName(String cName) { this.cName = cName }
>>>>>> }
>>>>>>
>>>>>> new java.beans.PropertyDescriptor('cName', Foo) // ok now
>>>>>> --------------------------------------
>>>>>>
>>>>>
>>>>> that would mean the isCName method missing is a false flag and really
>>>>> this is about capitalization of property names
>>>>>
>>>>> bye blackdrag
>>>>>
>>>>> --
>>>>> Jochen "blackdrag" Theodorou
>>>>> blog: http://blackdragsview.blogspot.com/
>>>>>
>>>>>
>>>>
>>>
>>
>

Mime
View raw message