You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2007/04/25 01:34:46 UTC
svn commit: r532137 - in
/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa:
enhance/PCEnhancer.java enhance/Reflection.java meta/ClassMetaData.java
Author: pcl
Date: Tue Apr 24 16:34:46 2007
New Revision: 532137
URL: http://svn.apache.org/viewvc?view=rev&rev=532137
Log:
OPENJPA-219. Avoid Class.getDeclaredField() / Class.getDeclaredMethod() in Reflection, since they throw exceptions as a side-effect. Also contains assorted clean-up in ClassMetaData.
Modified:
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java?view=diff&rev=532137&r1=532136&r2=532137
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/PCEnhancer.java Tue Apr 24 16:34:46 2007
@@ -687,15 +687,8 @@
Class owner) {
// find the actual ancestor class that declares the field, then
// check if the class is persistent, and if the field is managed
- for (; !owner.getName().equals(Object.class.getName());
- owner = owner.getSuperclass()) {
- try {
- owner.getDeclaredField(fieldName);
- break;
- } catch (Exception e) {
- }
- }
- if (owner.getName().equals(Object.class.getName()))
+ Field f = Reflection.findField(owner, fieldName, false);
+ if (f == null)
return null;
// managed interface
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java?view=diff&rev=532137&r1=532136&r2=532137
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/enhance/Reflection.java Tue Apr 24 16:34:46 2007
@@ -47,20 +47,20 @@
public static Method findGetter(Class cls, String prop, boolean mustExist) {
prop = StringUtils.capitalize(prop);
String name = "get" + prop;
+ Method m;
try {
- for (Class c = cls; c != null && c != Object.class;
+ // this algorithm searches for a get<prop> or is<prop> method in
+ // a breadth-first manner.
+ for (Class c = cls; c != null && c != Object.class;
c = c.getSuperclass()) {
- try {
- return c.getDeclaredMethod(name, (Class[]) null);
- } catch (NoSuchMethodException nsme) {
- try {
- Method m = c.getDeclaredMethod("is" + prop,
- (Class[]) null);
- if (m != null && (m.getReturnType() == boolean.class
- || m.getReturnType() == Boolean.class))
- return m;
- } catch (NoSuchMethodException nsme2) {
- }
+ m = getDeclaredMethod(c, name, null);
+ if (m != null) {
+ return m;
+ } else {
+ m = getDeclaredMethod(c, "is" + prop, null);
+ if (m != null && (m.getReturnType() == boolean.class
+ || m.getReturnType() == Boolean.class))
+ return m;
}
}
} catch (Exception e) {
@@ -89,14 +89,13 @@
public static Method findSetter(Class cls, String prop, Class param,
boolean mustExist) {
String name = "set" + StringUtils.capitalize(prop);
- Class[] params = new Class[] { param };
+ Method m;
try {
- for (Class c = cls; c != null && c != Object.class;
+ for (Class c = cls; c != null && c != Object.class;
c = c.getSuperclass()) {
- try {
- return c.getDeclaredMethod(name, params);
- } catch (NoSuchMethodException nsme) {
- }
+ m = getDeclaredMethod(c, name, param);
+ if (m != null)
+ return m;
}
} catch (Exception e) {
throw new GeneralException(e);
@@ -108,17 +107,41 @@
}
/**
- * Return the field with the given name, optionally throwing an exception
+ * Invokes <code>cls.getDeclaredMethods()</code>, and returns the method
+ * that matches the <code>name</code> and <code>param</code> arguments.
+ * Avoids the exception thrown by <code>Class.getDeclaredMethod()</code>
+ * for performance reasons. <code>param</code> may be null.
+ *
+ * @since 0.9.8
+ */
+ private static Method getDeclaredMethod(Class cls, String name,
+ Class param) {
+ Method[] methods = cls.getDeclaredMethods();
+ for (int i = 0 ; i < methods.length; i++) {
+ if (name.equals(methods[i].getName())) {
+ Class[] methodParams = methods[i].getParameterTypes();
+ if (param == null && methodParams.length == 0)
+ return methods[i];
+ if (param != null && methodParams.length == 1
+ && param.equals(methodParams[0]))
+ return methods[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return the field with the given name, optionally throwing an exception
* if none.
*/
public static Field findField(Class cls, String name, boolean mustExist) {
try {
- for (Class c = cls; c != null && c != Object.class;
+ Field f;
+ for (Class c = cls; c != null && c != Object.class;
c = c.getSuperclass()) {
- try {
- return c.getDeclaredField(name);
- } catch (NoSuchFieldException nsfe) {
- }
+ f = getDeclaredField(c, name);
+ if (f != null)
+ return f;
}
} catch (Exception e) {
throw new GeneralException(e);
@@ -126,6 +149,22 @@
if (mustExist)
throw new UserException(_loc.get("bad-field", cls, name));
+ return null;
+ }
+
+ /**
+ * Invokes <code>cls.getDeclaredFields()</code>, and returns the field
+ * that matches the <code>name</code> argument. Avoids the exception
+ * thrown by <code>Class.getDeclaredField()</code> for performance reasons.
+ *
+ * @since 0.9.8
+ */
+ private static Field getDeclaredField(Class cls, String name) {
+ Field[] fields = cls.getDeclaredFields();
+ for (int i = 0 ; i < fields.length; i++) {
+ if (name.equals(fields[i].getName()))
+ return fields[i];
+ }
return null;
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?view=diff&rev=532137&r1=532136&r2=532137
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java Tue Apr 24 16:34:46 2007
@@ -55,7 +55,6 @@
import org.apache.openjpa.util.LongId;
import org.apache.openjpa.util.MetaDataException;
import org.apache.openjpa.util.ObjectId;
-import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OpenJPAId;
import org.apache.openjpa.util.ShortId;
import org.apache.openjpa.util.StringId;
@@ -117,6 +116,10 @@
private static final Localizer _loc = Localizer.forPackage
(ClassMetaData.class);
+ private static final FetchGroup[] EMPTY_FETCH_GROUP_ARRAY
+ = new FetchGroup[0];
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
private MetaDataRepository _repos;
private transient ClassLoader _loader = null;
@@ -784,8 +787,9 @@
synchronized (_ifaceMap) {
Map fields = (Map) _ifaceMap.get(iface);
if (fields == null)
- return new String[0];
- return (String[]) fields.keySet().toArray(new String[0]);
+ return EMPTY_STRING_ARRAY;
+ return (String[]) fields.keySet().toArray(
+ new String[fields.size()]);
}
}
@@ -1397,15 +1401,12 @@
if (fieldName == null || SYNTHETIC.equals(fieldName))
return null;
- for (Class type = _type; type != null && type != Object.class;
- type = type.getSuperclass()) {
- try {
- return type.getDeclaredField(fieldName);
- } catch (Exception e) {
- }
- }
- throw new MetaDataException(_loc.get("no-detach-state", fieldName,
- _type));
+ Field f = Reflection.findField(_type, fieldName, false);
+ if (f != null)
+ return f;
+ else
+ throw new MetaDataException(
+ _loc.get("no-detach-state", fieldName, _type));
}
/**
@@ -1823,7 +1824,7 @@
ClassMetaData embed = pks[0].getEmbeddedMetaData();
validateAppIdClassMethods(embed.getDescribedType());
validateAppIdClassPKs(embed, embed.getFields(),
- embed.getDescribedType(), runtime);
+ embed.getDescribedType());
}
return;
}
@@ -1850,7 +1851,7 @@
validateAppIdClassMethods(_objectId);
// make sure the app id class has all pk fields
- validateAppIdClassPKs(this, pks, _objectId, runtime);
+ validateAppIdClassPKs(this, pks, _objectId);
}
}
@@ -1904,7 +1905,7 @@
* Validate that the primary key class has all pk fields.
*/
private void validateAppIdClassPKs(ClassMetaData meta,
- FieldMetaData[] fmds, Class oid, boolean runtime) {
+ FieldMetaData[] fmds, Class oid) {
if (fmds.length == 0 && !Modifier.isAbstract(meta.getDescribedType().
getModifiers()))
throw new MetaDataException(_loc.get("no-pk", _type));
@@ -2012,7 +2013,7 @@
*/
public FetchGroup[] getDeclaredFetchGroups() {
if (_fgs == null)
- _fgs = (_fgMap == null) ? new FetchGroup[0] : (FetchGroup[])
+ _fgs = (_fgMap == null) ? EMPTY_FETCH_GROUP_ARRAY : (FetchGroup[])
_fgMap.values().toArray(new FetchGroup[_fgMap.size()]);
return _fgs;
}