OPENJPA-2662 intern Strings.toClass

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1758851 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Struberg 2016-09-01 20:20:11 +00:00
parent 305758fc96
commit e647db2ee0
12 changed files with 195 additions and 26 deletions

View File

@ -24,10 +24,9 @@ import java.security.AccessController;
import org.apache.openjpa.jdbc.meta.MappingRepository;
import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.PluginValue;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import serp.util.Strings;
/**
* Handles the complex logic of creating a {@link MappingRepository} for
* a given configuration.
@ -46,7 +45,7 @@ public class MappingRepositoryValue
// since the MappingRepository takes a JDBConfiguration constructor,
// we need to manually perform the instantiation
try {
Class cls = Strings.toClass(clsName,
Class cls = ClassUtil.toClass(clsName,
AccessController.doPrivileged(
J2DoPrivHelper.getClassLoaderAction(type)));
return cls.getConstructor(new Class[]{ JDBCConfiguration.class }).

View File

@ -37,7 +37,6 @@ import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

View File

@ -18,8 +18,6 @@
*/
package org.apache.openjpa.jdbc.kernel.exps;
import java.util.List;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.sql.SQLBuffer;

View File

@ -26,8 +26,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ForeignKey;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.Localizer;
import serp.util.Strings;
/**
* Simple {@link ReverseCustomizer} that uses a properties file to
@ -162,7 +162,7 @@ public class PropertiesReverseCustomizer
public void customize(FieldMapping field) {
String type = getProperty(field.getFullName(false) + ".type");
if (type != null)
field.setDeclaredType(Strings.toClass(type, null));
field.setDeclaredType(ClassUtil.toClass(type, null));
}
public String getFieldName(ClassMapping dec, Column[] cols, ForeignKey fk,

View File

@ -79,6 +79,7 @@ import org.apache.openjpa.jdbc.schema.XMLSchemaParser;
import org.apache.openjpa.jdbc.sql.SQLExceptions;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.CodeFormat;
import org.apache.openjpa.lib.util.Files;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
@ -1675,7 +1676,7 @@ public class ReverseMappingTool
propNames[propNames.length - 1]));
if (typeSpec != null)
type = Strings.toClass(typeSpec, _conf.
type = ClassUtil.toClass(typeSpec, _conf.
getClassResolverInstance().getClassLoader
(ReverseMappingTool.class, null));
}

View File

@ -30,10 +30,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Holds metadata about a Database Stored Procedure.

View File

@ -52,6 +52,7 @@ import org.apache.openjpa.lib.rop.MergedResultObjectProvider;
import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
import org.apache.openjpa.lib.rop.ResultList;
import org.apache.openjpa.lib.rop.ResultObjectProvider;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.OrderedMap;
@ -994,7 +995,7 @@ public class QueryImpl
/**
* Execute the query using the given compilation, executor, and parameter
* values. All other execute methods delegate to this one or to
* {@link #execute(StoreQuery.Executor,Map)} after validation and locking.
* {@link #execute(int, Map)} after validation and locking.
*/
private Object execute(StoreQuery q, StoreQuery.Executor ex,
Object[] params)
@ -1022,7 +1023,7 @@ public class QueryImpl
/**
* Delete the query using the given executor, and parameter
* values. All other execute methods delegate to this one or to
* {@link #delete(StoreQuery.Executor,Map)} after validation and locking.
* {@link #delete(StoreQuery, StoreQuery.Executor, Object[])} after validation and locking.
* The return value will be a Number indicating the number of
* instances deleted.
*/
@ -1053,7 +1054,7 @@ public class QueryImpl
/**
* Update the query using the given compilation, executor, and parameter
* values. All other execute methods delegate to this one or to
* {@link #update(StoreQuery.Executor,Map)} after validation and locking.
* {@link #update(StoreQuery, StoreQuery.Executor, Object[])} after validation and locking.
* The return value will be a Number indicating the number of
* instances updated.
*/
@ -1698,7 +1699,7 @@ public class QueryImpl
_loader = _broker.getConfiguration().getClassResolverInstance().
getClassLoader(_class, _broker.getClassLoader());
try {
return Strings.toClass(name, _loader);
return ClassUtil.toClass(name, _loader);
} catch (RuntimeException re) {
} catch (NoClassDefFoundError ncdfe) {
}

View File

@ -37,6 +37,7 @@ import javax.naming.NamingException;
import org.apache.commons.lang3.StringUtils;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Options;
@ -203,10 +204,10 @@ public class Configurations {
}
if (cls == null) {
try {
cls = Strings.toClass(clsName, loader);
cls = ClassUtil.toClass(clsName, loader);
loaderCache.put(clsName, cls);
} catch (RuntimeException re) {
// TODO, empty block is never good
}
}
return cls;

View File

@ -21,11 +21,11 @@ package org.apache.openjpa.lib.meta;
import java.security.AccessController;
import org.apache.commons.lang3.StringUtils;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import serp.util.Strings;
/**
* Custom SAX parser used by the system to quickly parse metadata files
@ -341,15 +341,15 @@ public class CFMetaDataParser extends XMLMetaDataParser {
boolean noPackage = StringUtils.isEmpty(pkg);
try {
if (fullName || noPackage)
return Strings.toClass(name, resolve, loader);
return Strings.toClass(pkg + "." + name, resolve, loader);
return ClassUtil.toClass(name, resolve, loader);
return ClassUtil.toClass(pkg + "." + name, resolve, loader);
} catch (RuntimeException re) {
}
// if not a full name, now try the name without a package
if (!fullName && !noPackage) {
try {
return Strings.toClass(name, resolve, loader);
return ClassUtil.toClass(name, resolve, loader);
} catch (RuntimeException re) {
}
}
@ -358,7 +358,7 @@ public class CFMetaDataParser extends XMLMetaDataParser {
if (!fullName) {
for (int i = 0; i < PACKAGES.length; i++) {
try {
return Strings.toClass(PACKAGES[i] + name, resolve, loader);
return ClassUtil.toClass(PACKAGES[i] + name, resolve, loader);
} catch (RuntimeException re) {
}
}

View File

@ -37,11 +37,11 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.openjpa.lib.util.ClassUtil;
import org.apache.openjpa.lib.util.Files;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
import serp.bytecode.lowlevel.ConstantPoolTable;
import serp.util.Strings;
/**
* Parser used to resolve arguments into java classes.
@ -159,7 +159,7 @@ public class ClassArgParser {
String[] names = parseTypeNames(arg);
Class<?>[] objs = new Class[names.length];
for (int i = 0; i < names.length; i++)
objs[i] = Strings.toClass(names[i], _loader);
objs[i] = ClassUtil.toClass(names[i], _loader);
return objs;
}
@ -171,7 +171,7 @@ public class ClassArgParser {
String[] names = parseTypeNames(itr);
Class<?>[] objs = new Class[names.length];
for (int i = 0; i < names.length; i++)
objs[i] = Strings.toClass(names[i], _loader);
objs[i] = ClassUtil.toClass(names[i], _loader);
return objs;
}
@ -191,7 +191,7 @@ public class ClassArgParser {
names = entry.getValue();
objs = new Class[names.length];
for (int j = 0; j < names.length; j++) {
objs[j] = Strings.toClass(names[j], _loader);
objs[j] = ClassUtil.toClass(names[j], _loader);
}
rval.put(entry.getKey(), objs);
}

View File

@ -0,0 +1,113 @@
/*
* 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.lib.util;
/**
* Various helper methods to deal with Classes
*/
public final class ClassUtil {
private static final Object[][] _codes = new Object[][]{
{byte.class, "byte", "B"},
{char.class, "char", "C"},
{double.class, "double", "D"},
{float.class, "float", "F"},
{int.class, "int", "I"},
{long.class, "long", "J"},
{short.class, "short", "S"},
{boolean.class, "boolean", "Z"},
{void.class, "void", "V"}
};
private ClassUtil() {
}
/**
* Return the class for the given string, correctly handling
* primitive types. If the given class loader is null, the context
* loader of the current thread will be used.
*
* @throws RuntimeException on load error
* @author Abe White, taken from the Serp project
*/
public static Class toClass(String str, ClassLoader loader) {
return toClass(str, false, loader);
}
/**
* Return the class for the given string, correctly handling
* primitive types. If the given class loader is null, the context
* loader of the current thread will be used.
*
* @throws RuntimeException on load error
* @author Abe White, taken from the Serp project
*/
public static Class toClass(String str, boolean resolve,
ClassLoader loader) {
if (str == null) {
throw new NullPointerException("str == null");
}
// array handling
int dims = 0;
while (str.endsWith("[]")) {
dims++;
str = str.substring(0, str.length() - 2);
}
// check against primitive types
boolean primitive = false;
if (str.indexOf('.') == -1) {
for (int i = 0; !primitive && (i < _codes.length); i++) {
if (_codes[i][1].equals(str)) {
if (dims == 0) {
return (Class) _codes[i][0];
}
str = (String) _codes[i][2];
primitive = true;
}
}
}
if (dims > 0) {
StringBuilder buf = new StringBuilder(str.length() + dims + 2);
for (int i = 0; i < dims; i++) {
buf.append('[');
}
if (!primitive) {
buf.append('L');
}
buf.append(str);
if (!primitive) {
buf.append(';');
}
str = buf.toString();
}
if (loader == null) {
loader = Thread.currentThread().getContextClassLoader();
}
try {
return Class.forName(str, resolve, loader);
} catch (ClassNotFoundException | NoClassDefFoundError e) {
throw new IllegalArgumentException(e.getMessage());
}
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.lib.util;
import org.junit.Assert;
import org.junit.Test;
/**
* TODO remove again. Just to test serp.ClassUtil.toClass
*/
public class ClassUtilTest {
@Test
public void testToClass() {
Assert.assertEquals(this.getClass(), toClass("org.apache.openjpa.lib.util.ClassUtilTest"));
Assert.assertEquals(new ClassUtilTest[0].getClass(), toClass("org.apache.openjpa.lib.util.ClassUtilTest[]"));
Assert.assertEquals(Integer.class, toClass("java.lang.Integer"));
Assert.assertEquals(byte.class, toClass("byte"));
Assert.assertEquals(char.class, toClass("char"));
Assert.assertEquals(double.class, toClass("double"));
Assert.assertEquals(float.class, toClass("float"));
Assert.assertEquals(int.class, toClass("int"));
Assert.assertEquals(long.class, toClass("long"));
Assert.assertEquals(short.class, toClass("short"));
Assert.assertEquals(boolean.class, toClass("boolean"));
Assert.assertEquals(void.class, toClass("void"));
Assert.assertEquals(new float[0].getClass(), toClass("float[]"));
Assert.assertEquals(new float[0][0].getClass(), toClass("float[][]"));
Assert.assertEquals(new long[0][0][0].getClass(), toClass("long[][][]"));
}
@Test(expected = IllegalArgumentException.class)
public void nonExistingClass() {
toClass("does.not.Exist");
}
private Class toClass(String clazz) {
return ClassUtil.toClass(clazz, false, this.getClass().getClassLoader());
}
}