OPENJPA-2467: Fix detection of property access method names. Patch contributed by Dalia Abo Sheasha.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1564931 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Richard G. Curtis 2014-02-05 21:18:31 +00:00
parent bcf46e516c
commit 0527c4570d
8 changed files with 588 additions and 8 deletions

View File

@ -398,14 +398,24 @@ public class CodeGenerator {
code.append("is");
else
code.append("get");
if (fieldName.length() > 1 && Character.isLowerCase(fieldName.charAt(0))
&& Character.isUpperCase(fieldName.charAt(1))) {
code.append(fieldName).parens();
} else {
code.append(capFieldName).parens();
}
code.openBrace(2).endl();
code.tab(2).append("return ").append(fieldName).
append(";").endl();
code.closeBrace(2).afterSection();
// setter
if (fieldName.length() > 1 && Character.isLowerCase(fieldName.charAt(0))
&& Character.isUpperCase(fieldName.charAt(1))) {
code.tab().append("public void set").append(fieldName);
} else {
code.tab().append("public void set").append(capFieldName);
}
code.openParen(true).append(fieldType).append(paramType).
append(" ").append(propertyName).closeParen();
code.openBrace(2).endl();

View File

@ -806,7 +806,7 @@ public class PCEnhancer {
* Return the name of the setter method for the given field.
*/
private static String getSetterName(FieldMetaData fmd) {
return "set" + StringUtils.capitalize(fmd.getName());
return fmd.getSetterName();
}
/**

View File

@ -123,6 +123,19 @@ public class Reflection {
|| m.getReturnType() == Boolean.class)) {
setGetterMethod(cls, prop, m);
return m;
} else {
m = getDeclaredMethod(c, "get" + prop, null);
if (m != null) {
setGetterMethod(cls, prop, m);
return m;
} else {
m = getDeclaredMethod(c, "is" + prop, null);
if (m != null
&& (m.getReturnType() == boolean.class || m.getReturnType() == Boolean.class)) {
setGetterMethod(cls, prop, m);
return m;
}
}
}
}
}

View File

@ -2446,4 +2446,26 @@ public class FieldMetaData
public void setUseSchemaElement(boolean _useSchemaElement) {
this._useSchemaElement = _useSchemaElement;
}
public String getSetterName() {
String setterName = "set" + StringUtils.capitalize(_name);
if (_name.length() > 1 && Character.isLowerCase(_name.charAt(0)) && Character.isUpperCase(_name.charAt(1))) {
// We have the special case where the first char is lower, and the
// following char is capital. We need to support using the
// setaStart() (correct) and setAStart() (incorrect -- old way)
Class<?> type = getDeclaringMetaData().getDescribedType();
setterName = "set" + _name;
try {
type.getDeclaredMethod(setterName, getType());
return setterName;
} catch (Exception e) {
}
setterName = "set" + StringUtils.capitalize(_name);
try {
type.getDeclaredMethod(setterName, getType());
} catch (Exception e) {
}
}
return setterName;
}
}

View File

@ -0,0 +1,217 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.access;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "CAPITALIZATION_TABLE")
public class PropertyAccessCapitalization {
private long id;
private int word;
private int aWord;
private int aaWord;
private int aaaWord;
private int CAPITAL;
private int aCAPITAL;
private int Another;
private int a1;
private int B1;
private int a;
private int B;
private boolean aBoolean;
private boolean BBoolean;
private boolean BOOLEAN;
private boolean Bool;
public int getaCAPITAL() {
return aCAPITAL;
}
public void setaCAPITAL(int aCAPITAL) {
this.aCAPITAL = aCAPITAL;
}
public int getA1() {
return a1;
}
public void setA1(int a1) {
this.a1 = a1;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
@Id
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getWord() {
return word;
}
public void setWord(int word) {
this.word = word;
}
public int getaWord() {
return aWord;
}
public void setaWord(int aWord) {
this.aWord = aWord;
}
public int getAaWord() {
return aaWord;
}
public void setAaWord(int aaWord) {
this.aaWord = aaWord;
}
public int getAaaWord() {
return aaaWord;
}
public void setAaaWord(int aaaWord) {
this.aaaWord = aaaWord;
}
public int getCAPITAL() {
return CAPITAL;
}
public void setCAPITAL(int cAPITAL) {
CAPITAL = cAPITAL;
}
public int getB1() {
return B1;
}
public void setB1(int b1) {
B1 = b1;
}
public int getB() {
return B;
}
public void setB(int b) {
B = b;
}
public int getAnother() {
return Another;
}
public void setAnother(int another) {
Another = another;
}
public boolean isaBoolean() {
return aBoolean;
}
public void setaBoolean(boolean aBoolean) {
this.aBoolean = aBoolean;
}
public boolean isBBoolean() {
return BBoolean;
}
public void setBBoolean(boolean bBoolean) {
BBoolean = bBoolean;
}
public boolean isBOOLEAN() {
return BOOLEAN;
}
public void setBOOLEAN(boolean bOOLEAN) {
BOOLEAN = bOOLEAN;
}
public boolean isBool() {
return Bool;
}
public void setBool(boolean bool) {
Bool = bool;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PropertyAccessCapitalization other = (PropertyAccessCapitalization) obj;
if (getAnother() != other.getAnother())
return false;
if (getB() != other.getB())
return false;
if (getB1() != other.getB1())
return false;
if (isBBoolean() != other.isBBoolean())
return false;
if (isBOOLEAN() != other.isBOOLEAN())
return false;
if (isBool() != other.isBool())
return false;
if (getCAPITAL() != other.getCAPITAL())
return false;
if (getA() != other.getA())
return false;
if (getA1() != other.getA1())
return false;
if (isaBoolean() != other.isaBoolean())
return false;
if (getaCAPITAL() != other.getaCAPITAL())
return false;
if (getaWord() != other.getaWord())
return false;
if (getAaWord() != other.getAaWord())
return false;
if (getAaaWord() != other.getAaaWord())
return false;
if (getId() != other.getId())
return false;
if (getWord() != other.getWord())
return false;
return true;
}
}

View File

@ -0,0 +1,220 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.access;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "CAPITALIZATION_OLD_BEHAVIOR_TABLE")
@Access(AccessType.PROPERTY)
public class PropertyAccessCapitalizationOldBehavior {
private long id;
private int word;
private int aWord;
private int aaWord;
private int aaaWord;
private int CAPITAL;
private int aCAPITAL;
private int Another;
private int a1;
private int B1;
private int a;
private int B;
private boolean aBoolean;
private boolean BBoolean;
private boolean BOOLEAN;
private boolean Bool;
public int getAWord() {
return aWord;
}
public void setAWord(int aWord) {
this.aWord = aWord;
}
@Id
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getWord() {
return word;
}
public void setWord(int word) {
this.word = word;
}
public int getAaWord() {
return aaWord;
}
public void setAaWord(int aaWord) {
this.aaWord = aaWord;
}
public int getAaaWord() {
return aaaWord;
}
public void setAaaWord(int aaaWord) {
this.aaaWord = aaaWord;
}
public int getCAPITAL() {
return CAPITAL;
}
public void setCAPITAL(int cAPITAL) {
CAPITAL = cAPITAL;
}
public int getACAPITAL() {
return aCAPITAL;
}
public void setACAPITAL(int aCAPITAL) {
this.aCAPITAL = aCAPITAL;
}
public int getA1() {
return a1;
}
public void setA1(int a1) {
this.a1 = a1;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB1() {
return B1;
}
public void setB1(int b1) {
B1 = b1;
}
public int getB() {
return B;
}
public void setB(int b) {
B = b;
}
public int getAnother() {
return Another;
}
public void setAnother(int another) {
Another = another;
}
public boolean isABoolean() {
return aBoolean;
}
public void setABoolean(boolean aBoolean) {
this.aBoolean = aBoolean;
}
public boolean isBBoolean() {
return BBoolean;
}
public void setBBoolean(boolean bBoolean) {
BBoolean = bBoolean;
}
public boolean isBOOLEAN() {
return BOOLEAN;
}
public void setBOOLEAN(boolean bOOLEAN) {
BOOLEAN = bOOLEAN;
}
public boolean isBool() {
return Bool;
}
public void setBool(boolean bool) {
Bool = bool;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PropertyAccessCapitalizationOldBehavior other = (PropertyAccessCapitalizationOldBehavior) obj;
if (getAnother() != other.getAnother())
return false;
if (getB() != other.getB())
return false;
if (getB1() != other.getB1())
return false;
if (isBBoolean() != other.isBBoolean())
return false;
if (isBOOLEAN() != other.isBOOLEAN())
return false;
if (isBool() != other.isBool())
return false;
if (getCAPITAL() != other.getCAPITAL())
return false;
if (getA() != other.getA())
return false;
if (getA1() != other.getA1())
return false;
if (isABoolean() != other.isABoolean())
return false;
if (getACAPITAL() != other.getACAPITAL())
return false;
if (getAWord() != other.getAWord())
return false;
if (getAaWord() != other.getAaWord())
return false;
if (getAaaWord() != other.getAaaWord())
return false;
if (getId() != other.getId())
return false;
if (getWord() != other.getWord())
return false;
return true;
}
}

View File

@ -0,0 +1,94 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.access;
import java.util.Random;
import javax.persistence.EntityManager;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
public class TestPropertyAccessCapitalization extends SingleEMFTestCase {
public void setUp() {
setUp(DROP_TABLES, PropertyAccessCapitalization.class, PropertyAccessCapitalizationOldBehavior.class);
}
public void testCorrectCapitalization() {
EntityManager em = emf.createEntityManager();
PropertyAccessCapitalization entity = new PropertyAccessCapitalization();
Random r = new Random();
entity.setId(r.nextInt());
entity.setWord(r.nextInt());
entity.setaWord(r.nextInt());
entity.setAaWord(r.nextInt());
entity.setAaaWord(r.nextInt());
entity.setCAPITAL(r.nextInt());
entity.setaCAPITAL(r.nextInt());
entity.setAnother(r.nextInt());
entity.setA1(r.nextInt());
entity.setB1(r.nextInt());
entity.setA(r.nextInt());
entity.setB(r.nextInt());
entity.setaBoolean(true);
entity.setBBoolean(true);
entity.setBOOLEAN(true);
entity.setBool(true);
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
em.clear();
PropertyAccessCapitalization persistentEntity = em.find(PropertyAccessCapitalization.class, entity.getId());
assertEquals(entity, persistentEntity);
}
public void testOldCapitalization() {
EntityManager em = emf.createEntityManager();
PropertyAccessCapitalizationOldBehavior entity = new PropertyAccessCapitalizationOldBehavior();
Random r = new Random();
entity.setId(r.nextInt());
entity.setWord(r.nextInt());
entity.setAWord(r.nextInt());
entity.setAaWord(r.nextInt());
entity.setAaaWord(r.nextInt());
entity.setCAPITAL(r.nextInt());
entity.setACAPITAL(r.nextInt());
entity.setAnother(r.nextInt());
entity.setA1(r.nextInt());
entity.setB1(r.nextInt());
entity.setA(r.nextInt());
entity.setB(r.nextInt());
entity.setABoolean(true);
entity.setBBoolean(true);
entity.setBOOLEAN(true);
entity.setBool(true);
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
em.clear();
PropertyAccessCapitalizationOldBehavior persistentEntity =
em.find(PropertyAccessCapitalizationOldBehavior.class, entity.getId());
assertEquals(entity, persistentEntity);
}
}

View File

@ -609,12 +609,16 @@ public class PersistenceMetaDataDefaults
return false;
}
try {
String setterName;
if (member.getName().startsWith("is")) {
setterName = "set" + member.getName().substring(2);
} else {
setterName = "set" + member.getName().substring(3);
}
// check for setters for methods
Method setter = (Method) AccessController.doPrivileged(
J2DoPrivHelper.getDeclaredMethodAction(
meta.getDescribedType(), "set" +
StringUtils.capitalize(name), new Class[] {
((Method) member).getReturnType() }));
Method setter =
(Method) AccessController.doPrivileged(J2DoPrivHelper.getDeclaredMethodAction(
meta.getDescribedType(), setterName, new Class[] { ((Method) member).getReturnType() }));
if (setter == null && !isAnnotatedTransient(member)) {
logNoSetter(meta, name, null);
return false;