mirror of https://github.com/apache/openjpa.git
Option to create proxies for standard java.util types at build time. These
proxies can be serialized as proxies for use with detached state managers, whereas runtime-generated proxies have to serialize themselves as a copied instance of their corresponding java.util type in case they are transferred to a different classloading environment. git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@486825 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dfca20d465
commit
d6dbadaa3c
|
@ -78,13 +78,10 @@ public class Proxies {
|
||||||
/**
|
/**
|
||||||
* Used by proxy types to serialize non-proxy versions.
|
* Used by proxy types to serialize non-proxy versions.
|
||||||
*/
|
*/
|
||||||
public static Object writeReplace(Proxy proxy) {
|
public static Object writeReplace(Proxy proxy, boolean detachable) {
|
||||||
// we can't send dynamically-created classes to another JVM
|
if (detachable && (proxy == null || proxy.getOwner() == null
|
||||||
/*
|
|| proxy.getOwner().isDetached()))
|
||||||
if (proxy == null || proxy.getOwner() == null
|
|
||||||
|| proxy.getOwner().isDetached())
|
|
||||||
return proxy;
|
return proxy;
|
||||||
*/
|
|
||||||
return proxy.copy(proxy);
|
return proxy.copy(proxy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -46,6 +47,7 @@ import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
import org.apache.openjpa.lib.util.Files;
|
import org.apache.openjpa.lib.util.Files;
|
||||||
import org.apache.openjpa.lib.util.JavaVersions;
|
import org.apache.openjpa.lib.util.JavaVersions;
|
||||||
import org.apache.openjpa.lib.util.Localizer;
|
import org.apache.openjpa.lib.util.Localizer;
|
||||||
|
import org.apache.openjpa.lib.util.Options;
|
||||||
import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
|
import org.apache.openjpa.lib.util.concurrent.ConcurrentHashMap;
|
||||||
import serp.bytecode.BCClass;
|
import serp.bytecode.BCClass;
|
||||||
import serp.bytecode.BCClassLoader;
|
import serp.bytecode.BCClassLoader;
|
||||||
|
@ -331,9 +333,11 @@ public class ProxyManagerImpl
|
||||||
// we don't lock here; ok if two proxies get generated for same type
|
// we don't lock here; ok if two proxies get generated for same type
|
||||||
ProxyCollection proxy = (ProxyCollection) _proxies.get(type);
|
ProxyCollection proxy = (ProxyCollection) _proxies.get(type);
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
proxy = (ProxyCollection) instantiateProxy
|
ClassLoader l = getMostDerivedLoader(type, ProxyCollection.class);
|
||||||
(generateProxyCollectionBytecode(type), type,
|
Class pcls = loadBuildTimeProxy(type, l);
|
||||||
ProxyCollection.class, null, null);
|
if (pcls == null)
|
||||||
|
pcls = loadProxy(generateProxyCollectionBytecode(type, true),l);
|
||||||
|
proxy = (ProxyCollection) instantiateProxy(pcls, null, null);
|
||||||
_proxies.put(type, proxy);
|
_proxies.put(type, proxy);
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
|
@ -346,8 +350,11 @@ public class ProxyManagerImpl
|
||||||
// we don't lock here; ok if two proxies get generated for same type
|
// we don't lock here; ok if two proxies get generated for same type
|
||||||
ProxyMap proxy = (ProxyMap) _proxies.get(type);
|
ProxyMap proxy = (ProxyMap) _proxies.get(type);
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
proxy = (ProxyMap) instantiateProxy(generateProxyMapBytecode(type),
|
ClassLoader l = getMostDerivedLoader(type, ProxyMap.class);
|
||||||
type, ProxyMap.class, null, null);
|
Class pcls = loadBuildTimeProxy(type, l);
|
||||||
|
if (pcls == null)
|
||||||
|
pcls = loadProxy(generateProxyMapBytecode(type, true), l);
|
||||||
|
proxy = (ProxyMap) instantiateProxy(pcls, null, null);
|
||||||
_proxies.put(type, proxy);
|
_proxies.put(type, proxy);
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
|
@ -360,9 +367,11 @@ public class ProxyManagerImpl
|
||||||
// we don't lock here; ok if two proxies get generated for same type
|
// we don't lock here; ok if two proxies get generated for same type
|
||||||
ProxyDate proxy = (ProxyDate) _proxies.get(type);
|
ProxyDate proxy = (ProxyDate) _proxies.get(type);
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
proxy = (ProxyDate) instantiateProxy
|
ClassLoader l = getMostDerivedLoader(type, ProxyDate.class);
|
||||||
(generateProxyDateBytecode(type), type, ProxyDate.class, null,
|
Class pcls = loadBuildTimeProxy(type, l);
|
||||||
null);
|
if (pcls == null)
|
||||||
|
pcls = loadProxy(generateProxyDateBytecode(type, true), l);
|
||||||
|
proxy = (ProxyDate) instantiateProxy(pcls, null, null);
|
||||||
_proxies.put(type, proxy);
|
_proxies.put(type, proxy);
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
|
@ -375,9 +384,11 @@ public class ProxyManagerImpl
|
||||||
// we don't lock here; ok if two proxies get generated for same type
|
// we don't lock here; ok if two proxies get generated for same type
|
||||||
ProxyCalendar proxy = (ProxyCalendar) _proxies.get(type);
|
ProxyCalendar proxy = (ProxyCalendar) _proxies.get(type);
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
proxy = (ProxyCalendar) instantiateProxy
|
ClassLoader l = getMostDerivedLoader(type, ProxyCalendar.class);
|
||||||
(generateProxyCalendarBytecode(type), type, ProxyCalendar.class,
|
Class pcls = loadBuildTimeProxy(type, l);
|
||||||
null, null);
|
if (pcls == null)
|
||||||
|
pcls = loadProxy(generateProxyCalendarBytecode(type, true), l);
|
||||||
|
proxy = (ProxyCalendar) instantiateProxy(pcls, null, null);
|
||||||
_proxies.put(type, proxy);
|
_proxies.put(type, proxy);
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
|
@ -388,40 +399,62 @@ public class ProxyManagerImpl
|
||||||
*/
|
*/
|
||||||
private ProxyBean getFactoryProxyBean(Object orig) {
|
private ProxyBean getFactoryProxyBean(Object orig) {
|
||||||
// we don't lock here; ok if two proxies get generated for same type
|
// we don't lock here; ok if two proxies get generated for same type
|
||||||
ProxyBean proxy = (ProxyBean) _proxies.get(orig.getClass());
|
Class type = orig.getClass();
|
||||||
if (proxy == null && !_proxies.containsKey(orig.getClass())) {
|
ProxyBean proxy = (ProxyBean) _proxies.get(type);
|
||||||
BCClass bc = generateProxyBeanBytecode(orig.getClass());
|
if (proxy == null && !_proxies.containsKey(type)) {
|
||||||
if (bc == null)
|
ClassLoader l = getMostDerivedLoader(type, ProxyBean.class);
|
||||||
_proxies.put(orig.getClass(), null);
|
Class pcls = loadBuildTimeProxy(type, l);
|
||||||
else {
|
if (pcls == null) {
|
||||||
BCMethod m = bc.getDeclaredMethod("<init>", (Class[]) null);
|
BCClass bc = generateProxyBeanBytecode(type, true);
|
||||||
proxy = (ProxyBean) instantiateProxy(bc, orig.getClass(),
|
if (bc != null)
|
||||||
ProxyBean.class, findCopyConstructor(orig.getClass()),
|
pcls = loadProxy(bc, l);
|
||||||
new Object[] {orig});
|
|
||||||
_proxies.put(orig.getClass(), proxy);
|
|
||||||
}
|
}
|
||||||
|
if (pcls != null)
|
||||||
|
proxy = (ProxyBean) instantiateProxy(pcls,
|
||||||
|
findCopyConstructor(type), new Object[] {orig});
|
||||||
|
_proxies.put(type, proxy);
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the given proxy bytecode.
|
* Load the proxy class generated at build time for the given type,
|
||||||
|
* returning null if none exists.
|
||||||
*/
|
*/
|
||||||
private Proxy instantiateProxy(BCClass bc, Class type, Class proxy,
|
private static Class loadBuildTimeProxy(Class type, ClassLoader loader) {
|
||||||
Constructor cons, Object[] args) {
|
try {
|
||||||
BCClassLoader loader = new BCClassLoader(bc.getProject(),
|
return Class.forName(getProxyClassName(type, false), true, loader);
|
||||||
getMostDerivedClassLoader(type, proxy));
|
} catch (Throwable t) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the proxy class represented by the given bytecode.
|
||||||
|
*/
|
||||||
|
private Class loadProxy(BCClass bc, ClassLoader loader) {
|
||||||
|
BCClassLoader bcloader = new BCClassLoader(bc.getProject(), loader);
|
||||||
|
try {
|
||||||
|
return Class.forName(bc.getName(), true, bcloader);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new GeneralException(bc.getName()).setCause(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate the given proxy class.
|
||||||
|
*/
|
||||||
|
private Proxy instantiateProxy(Class cls, Constructor cons, Object[] args) {
|
||||||
try {
|
try {
|
||||||
Class cls = Class.forName(bc.getName(), true, loader);
|
|
||||||
if (cons != null)
|
if (cons != null)
|
||||||
return (Proxy) cls.getConstructor(cons.getParameterTypes()).
|
return (Proxy) cls.getConstructor(cons.getParameterTypes()).
|
||||||
newInstance(args);
|
newInstance(args);
|
||||||
return (Proxy) cls.newInstance();
|
return (Proxy) cls.newInstance();
|
||||||
} catch (InstantiationException ie) {
|
} catch (InstantiationException ie) {
|
||||||
throw new UnsupportedException(_loc.get("cant-classforname",
|
throw new UnsupportedException(_loc.get("cant-newinstance",
|
||||||
bc.getSuperclassName()));
|
cls.getSuperclass().getName()));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
throw new GeneralException(t);
|
throw new GeneralException(cls.getName()).setCause(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +462,7 @@ public class ProxyManagerImpl
|
||||||
* Return the more derived loader of the class laoders for the given
|
* Return the more derived loader of the class laoders for the given
|
||||||
* classes.
|
* classes.
|
||||||
*/
|
*/
|
||||||
private static ClassLoader getMostDerivedClassLoader(Class c1, Class c2) {
|
private static ClassLoader getMostDerivedLoader(Class c1, Class c2) {
|
||||||
ClassLoader l1 = c1.getClassLoader();
|
ClassLoader l1 = c1.getClassLoader();
|
||||||
ClassLoader l2 = c2.getClassLoader();
|
ClassLoader l2 = c2.getClassLoader();
|
||||||
if (l1 == l2)
|
if (l1 == l2)
|
||||||
|
@ -448,12 +481,11 @@ public class ProxyManagerImpl
|
||||||
/**
|
/**
|
||||||
* Generate the bytecode for a collection proxy for the given type.
|
* Generate the bytecode for a collection proxy for the given type.
|
||||||
*/
|
*/
|
||||||
protected BCClass generateProxyCollectionBytecode(Class type) {
|
protected BCClass generateProxyCollectionBytecode(Class type,
|
||||||
|
boolean runtime) {
|
||||||
assertNotFinal(type);
|
assertNotFinal(type);
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
BCClass bc = project.loadClass(Strings.getPackageName
|
BCClass bc = project.loadClass(getProxyClassName(type, runtime));
|
||||||
(ProxyManagerImpl.class) + "." + type.getName().replace('.', '$')
|
|
||||||
+ "$" + nextProxyId() + PROXY_SUFFIX);
|
|
||||||
bc.setSuperclass(type);
|
bc.setSuperclass(type);
|
||||||
bc.declareInterface(ProxyCollection.class);
|
bc.declareInterface(ProxyCollection.class);
|
||||||
|
|
||||||
|
@ -463,10 +495,19 @@ public class ProxyManagerImpl
|
||||||
proxyRecognizedMethods(bc, type, ProxyCollections.class,
|
proxyRecognizedMethods(bc, type, ProxyCollections.class,
|
||||||
ProxyCollection.class);
|
ProxyCollection.class);
|
||||||
proxySetters(bc, type);
|
proxySetters(bc, type);
|
||||||
addWriteReplaceMethod(bc);
|
addWriteReplaceMethod(bc, runtime);
|
||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the name of the proxy class to generate for the given type.
|
||||||
|
*/
|
||||||
|
private static String getProxyClassName(Class type, boolean runtime) {
|
||||||
|
String id = (runtime) ? "$" + nextProxyId() : "";
|
||||||
|
return Strings.getPackageName(ProxyManagerImpl.class) + "."
|
||||||
|
+ type.getName().replace('.', '$') + id + PROXY_SUFFIX;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throw appropriate exception if the given type is final.
|
* Throw appropriate exception if the given type is final.
|
||||||
*/
|
*/
|
||||||
|
@ -478,12 +519,10 @@ public class ProxyManagerImpl
|
||||||
/**
|
/**
|
||||||
* Generate the bytecode for a map proxy for the given type.
|
* Generate the bytecode for a map proxy for the given type.
|
||||||
*/
|
*/
|
||||||
protected BCClass generateProxyMapBytecode(Class type) {
|
protected BCClass generateProxyMapBytecode(Class type, boolean runtime) {
|
||||||
assertNotFinal(type);
|
assertNotFinal(type);
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
BCClass bc = project.loadClass(Strings.getPackageName
|
BCClass bc = project.loadClass(getProxyClassName(type, runtime));
|
||||||
(ProxyManagerImpl.class) + "." + type.getName().replace('.', '$')
|
|
||||||
+ "$" + nextProxyId() + PROXY_SUFFIX);
|
|
||||||
bc.setSuperclass(type);
|
bc.setSuperclass(type);
|
||||||
bc.declareInterface(ProxyMap.class);
|
bc.declareInterface(ProxyMap.class);
|
||||||
|
|
||||||
|
@ -492,19 +531,17 @@ public class ProxyManagerImpl
|
||||||
addProxyMapMethods(bc, type);
|
addProxyMapMethods(bc, type);
|
||||||
proxyRecognizedMethods(bc, type, ProxyMaps.class, ProxyMap.class);
|
proxyRecognizedMethods(bc, type, ProxyMaps.class, ProxyMap.class);
|
||||||
proxySetters(bc, type);
|
proxySetters(bc, type);
|
||||||
addWriteReplaceMethod(bc);
|
addWriteReplaceMethod(bc, runtime);
|
||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the bytecode for a date proxy for the given type.
|
* Generate the bytecode for a date proxy for the given type.
|
||||||
*/
|
*/
|
||||||
protected BCClass generateProxyDateBytecode(Class type) {
|
protected BCClass generateProxyDateBytecode(Class type, boolean runtime) {
|
||||||
assertNotFinal(type);
|
assertNotFinal(type);
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
BCClass bc = project.loadClass(Strings.getPackageName
|
BCClass bc = project.loadClass(getProxyClassName(type, runtime));
|
||||||
(ProxyManagerImpl.class) + "." + type.getName().replace('.', '$')
|
|
||||||
+ "$" + nextProxyId() + PROXY_SUFFIX);
|
|
||||||
bc.setSuperclass(type);
|
bc.setSuperclass(type);
|
||||||
bc.declareInterface(ProxyDate.class);
|
bc.declareInterface(ProxyDate.class);
|
||||||
|
|
||||||
|
@ -512,19 +549,18 @@ public class ProxyManagerImpl
|
||||||
addProxyMethods(bc, type, true);
|
addProxyMethods(bc, type, true);
|
||||||
addProxyDateMethods(bc, type);
|
addProxyDateMethods(bc, type);
|
||||||
proxySetters(bc, type);
|
proxySetters(bc, type);
|
||||||
addWriteReplaceMethod(bc);
|
addWriteReplaceMethod(bc, runtime);
|
||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the bytecode for a calendar proxy for the given type.
|
* Generate the bytecode for a calendar proxy for the given type.
|
||||||
*/
|
*/
|
||||||
protected BCClass generateProxyCalendarBytecode(Class type) {
|
protected BCClass generateProxyCalendarBytecode(Class type,
|
||||||
|
boolean runtime) {
|
||||||
assertNotFinal(type);
|
assertNotFinal(type);
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
BCClass bc = project.loadClass(Strings.getPackageName
|
BCClass bc = project.loadClass(getProxyClassName(type, runtime));
|
||||||
(ProxyManagerImpl.class) + "." + type.getName().replace('.', '$')
|
|
||||||
+ "$" + nextProxyId() + PROXY_SUFFIX);
|
|
||||||
bc.setSuperclass(type);
|
bc.setSuperclass(type);
|
||||||
bc.declareInterface(ProxyCalendar.class);
|
bc.declareInterface(ProxyCalendar.class);
|
||||||
|
|
||||||
|
@ -532,14 +568,14 @@ public class ProxyManagerImpl
|
||||||
addProxyMethods(bc, type, true);
|
addProxyMethods(bc, type, true);
|
||||||
addProxyCalendarMethods(bc, type);
|
addProxyCalendarMethods(bc, type);
|
||||||
proxySetters(bc, type);
|
proxySetters(bc, type);
|
||||||
addWriteReplaceMethod(bc);
|
addWriteReplaceMethod(bc, runtime);
|
||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the bytecode for a bean proxy for the given type.
|
* Generate the bytecode for a bean proxy for the given type.
|
||||||
*/
|
*/
|
||||||
protected BCClass generateProxyBeanBytecode(Class type) {
|
protected BCClass generateProxyBeanBytecode(Class type, boolean runtime) {
|
||||||
if (Modifier.isFinal(type.getModifiers()))
|
if (Modifier.isFinal(type.getModifiers()))
|
||||||
return null;
|
return null;
|
||||||
if (ImplHelper.isManagedType(type))
|
if (ImplHelper.isManagedType(type))
|
||||||
|
@ -558,9 +594,7 @@ public class ProxyManagerImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
BCClass bc = project.loadClass(Strings.getPackageName
|
BCClass bc = project.loadClass(getProxyClassName(type, runtime));
|
||||||
(ProxyManagerImpl.class) + "." + type.getName().replace('.', '$')
|
|
||||||
+ "$" + nextProxyId() + PROXY_SUFFIX);
|
|
||||||
bc.setSuperclass(type);
|
bc.setSuperclass(type);
|
||||||
bc.declareInterface(ProxyBean.class);
|
bc.declareInterface(ProxyBean.class);
|
||||||
|
|
||||||
|
@ -569,7 +603,7 @@ public class ProxyManagerImpl
|
||||||
addProxyBeanMethods(bc, type, cons);
|
addProxyBeanMethods(bc, type, cons);
|
||||||
if (!proxySetters(bc, type))
|
if (!proxySetters(bc, type))
|
||||||
return null;
|
return null;
|
||||||
addWriteReplaceMethod(bc);
|
addWriteReplaceMethod(bc, runtime);
|
||||||
return bc;
|
return bc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1409,16 +1443,17 @@ public class ProxyManagerImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a writeReplace implementation that serializes to a non-proxy type
|
* Add a writeReplace implementation that serializes to a non-proxy type
|
||||||
* unless detached.
|
* unless detached and this is a build-time generated class.
|
||||||
*/
|
*/
|
||||||
private void addWriteReplaceMethod(BCClass bc) {
|
private void addWriteReplaceMethod(BCClass bc, boolean runtime) {
|
||||||
BCMethod m = bc.declareMethod("writeReplace", Object.class, null);
|
BCMethod m = bc.declareMethod("writeReplace", Object.class, null);
|
||||||
m.makeProtected();
|
m.makeProtected();
|
||||||
m.getExceptions(true).addException(ObjectStreamException.class);
|
m.getExceptions(true).addException(ObjectStreamException.class);
|
||||||
Code code = m.getCode(true);
|
Code code = m.getCode(true);
|
||||||
code.aload().setThis();
|
code.aload().setThis();
|
||||||
|
code.constant().setValue(!runtime);
|
||||||
code.invokestatic().setMethod(Proxies.class, "writeReplace",
|
code.invokestatic().setMethod(Proxies.class, "writeReplace",
|
||||||
Object.class, new Class[] { Proxy.class });
|
Object.class, new Class[] { Proxy.class, boolean.class });
|
||||||
code.areturn();
|
code.areturn();
|
||||||
code.calculateMaxLocals();
|
code.calculateMaxLocals();
|
||||||
code.calculateMaxStack();
|
code.calculateMaxStack();
|
||||||
|
@ -1474,13 +1509,20 @@ public class ProxyManagerImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usage: java org.apache.openjpa.util.proxy.ProxyManagerImpl
|
* Usage: java org.apache.openjpa.util.proxy.ProxyManagerImpl [option]*
|
||||||
* <class name>+
|
* <class name>+<br />
|
||||||
|
* Where the following options are recognized:
|
||||||
|
* <ul>
|
||||||
|
* <li><i>-utils/-u <number></i>: Generate proxies for the standard
|
||||||
|
* java.util collection, map, date, and calendar classes of the given Java
|
||||||
|
* version. Use 4 for Java 1.4, 5 for Java 5, etc.</li>
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* The main method generates .class files for the proxies to the classes
|
* The main method generates .class files for the proxies to the classes
|
||||||
* given on the command line. The .class files are placed in the same
|
* given on the command line. It writes the generated classes to beside the
|
||||||
* package as this class, or the current directory if the directory for this
|
* ProxyManagerImpl.class file if possible; otherwise it writes to the
|
||||||
* class cannot be accessed.
|
* current directory. The proxy manager looks for these classes
|
||||||
|
* before generating its own proxies at runtime.
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
throws ClassNotFoundException, IOException {
|
throws ClassNotFoundException, IOException {
|
||||||
|
@ -1488,21 +1530,59 @@ public class ProxyManagerImpl
|
||||||
dir = (dir == null) ? new File(System.getProperty("user.dir"))
|
dir = (dir == null) ? new File(System.getProperty("user.dir"))
|
||||||
: dir.getParentFile();
|
: dir.getParentFile();
|
||||||
|
|
||||||
|
Options opts = new Options();
|
||||||
|
args = opts.setFromCmdLine(args);
|
||||||
|
|
||||||
|
List types = new ArrayList();
|
||||||
|
types.addAll(Arrays.asList(args));
|
||||||
|
int utils = opts.removeIntProperty("utils", "u", 0);
|
||||||
|
if (utils >= 4) {
|
||||||
|
types.addAll(Arrays.asList(new String[] {
|
||||||
|
java.sql.Date.class.getName(),
|
||||||
|
java.sql.Time.class.getName(),
|
||||||
|
java.sql.Timestamp.class.getName(),
|
||||||
|
java.util.ArrayList.class.getName(),
|
||||||
|
java.util.Date.class.getName(),
|
||||||
|
java.util.GregorianCalendar.class.getName(),
|
||||||
|
java.util.HashMap.class.getName(),
|
||||||
|
java.util.HashSet.class.getName(),
|
||||||
|
java.util.Hashtable.class.getName(),
|
||||||
|
java.util.LinkedList.class.getName(),
|
||||||
|
java.util.Properties.class.getName(),
|
||||||
|
java.util.TreeMap.class.getName(),
|
||||||
|
java.util.TreeSet.class.getName(),
|
||||||
|
java.util.Vector.class.getName(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (utils >= 5) {
|
||||||
|
types.addAll(Arrays.asList(new String[] {
|
||||||
|
"java.util.EnumMap",
|
||||||
|
"java.util.IdentityHashMap",
|
||||||
|
"java.util.LinkedHashMap",
|
||||||
|
"java.util.LinkedHashSet",
|
||||||
|
"java.util.PriorityQueue",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
ProxyManagerImpl mgr = new ProxyManagerImpl();
|
ProxyManagerImpl mgr = new ProxyManagerImpl();
|
||||||
Class cls;
|
Class cls;
|
||||||
BCClass bc;
|
BCClass bc;
|
||||||
for (int i = 0; i < args.length; i++) {
|
for (int i = 0; i < types.size(); i++) {
|
||||||
cls = Class.forName(args[i]);
|
cls = Class.forName((String) types.get(i));
|
||||||
|
if (loadBuildTimeProxy(cls, getMostDerivedLoader(cls, Proxy.class))
|
||||||
|
!= null)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (Collection.class.isAssignableFrom(cls))
|
if (Collection.class.isAssignableFrom(cls))
|
||||||
bc = mgr.generateProxyCollectionBytecode(cls);
|
bc = mgr.generateProxyCollectionBytecode(cls, false);
|
||||||
else if (Map.class.isAssignableFrom(cls))
|
else if (Map.class.isAssignableFrom(cls))
|
||||||
bc = mgr.generateProxyMapBytecode(cls);
|
bc = mgr.generateProxyMapBytecode(cls, false);
|
||||||
else if (Date.class.isAssignableFrom(cls))
|
else if (Date.class.isAssignableFrom(cls))
|
||||||
bc = mgr.generateProxyDateBytecode(cls);
|
bc = mgr.generateProxyDateBytecode(cls, false);
|
||||||
else if (Calendar.class.isAssignableFrom(cls))
|
else if (Calendar.class.isAssignableFrom(cls))
|
||||||
bc = mgr.generateProxyCalendarBytecode(cls);
|
bc = mgr.generateProxyCalendarBytecode(cls, false);
|
||||||
else
|
else
|
||||||
bc = mgr.generateProxyBeanBytecode(cls);
|
bc = mgr.generateProxyBeanBytecode(cls, false);
|
||||||
|
|
||||||
System.out.println(bc.getName());
|
System.out.println(bc.getName());
|
||||||
bc.write(new File(dir, bc.getClassName() + ".class"));
|
bc.write(new File(dir, bc.getClassName() + ".class"));
|
||||||
|
|
|
@ -49,7 +49,7 @@ no-proxy-intf: Unable to create a second class object proxy for interface \
|
||||||
"{0}". No corresponding concrete types are known.
|
"{0}". No corresponding concrete types are known.
|
||||||
no-proxy-abstract: Unable to create a second class object proxy for abstract \
|
no-proxy-abstract: Unable to create a second class object proxy for abstract \
|
||||||
type "{0}". You must use a concrete type or a recognized interface.
|
type "{0}". You must use a concrete type or a recognized interface.
|
||||||
cant-classforname: Unable to instantiate proxy for type "{0}". Make sure the \
|
cant-newinstance: Unable to instantiate proxy for type "{0}". Make sure the \
|
||||||
class has a default constructor.
|
class has a default constructor.
|
||||||
no-date-cons: Custom date type "{0}" needs a default constructor or a \
|
no-date-cons: Custom date type "{0}" needs a default constructor or a \
|
||||||
millisecond constructor.
|
millisecond constructor.
|
||||||
|
|
Loading…
Reference in New Issue