001: // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
002:
003: package jodd.proxetta;
004:
005: import org.objectweb.asm.ClassReader;
006:
007: import java.io.IOException;
008: import java.io.InputStream;
009:
010: import jodd.util.ClassLoaderUtil;
011:
012: /**
013: * Proxetta creates proxy classes in the run-time.
014: * <p>
015: * For proxy creation it is needed to have the target class (or name or <code>InputStream</code>)
016: * and one or more {@link ProxyDefinition proxy definitions}.
017: * Proxetta will scan target class and check if there are methods to proxyfy (upon definition
018: * in provided proxy definitions}. If there are matched methods, new proxy class
019: * will be created.
020: * <p>
021: * If no matching method founded, Proxetta may or may not create an empty proxy class.
022: * This behaviour is defined by using <b>forced</b> mode during creation.
023: */
024: public class Proxetta {
025:
026: // ---------------------------------------------------------------- read proxy
027:
028: protected static ClassReader newClassReader(String targetName) {
029: try {
030: return new ClassReader(targetName);
031: } catch (IOException ioex) {
032: throw new ProxettaException(ioex);
033: }
034: }
035:
036: protected static ClassReader newClassReader(InputStream in) {
037: try {
038: return new ClassReader(in);
039: } catch (IOException ioex) {
040: throw new ProxettaException(ioex);
041: }
042: }
043:
044: // ---------------------------------------------------------------- create
045:
046: /**
047: * Generates class bytecodes for proxy for provided class.
048: * Proxy is created <b>only</b> if there are matched methods for proxyfying.
049: * Otherwise, it returs <code>null</code>.
050: * @see #createProxy(String, ProxyDefinition[])
051: */
052: public static byte[] createProxy(Class target,
053: ProxyDefinition... proxyDefinitions) {
054: return createProxy(target.getName(), proxyDefinitions);
055: }
056:
057: /**
058: * Generates class bytecodes for proxy for provided class name.
059: * It allows <b>forced</b> creation, when proxy is created even if there are no
060: * matched methods for proxyfying.
061: */
062: public static byte[] createProxy(Class target, boolean forced,
063: ProxyDefinition... proxyDefinitions) {
064: return createProxy(target.getName(), forced, proxyDefinitions);
065: }
066:
067: /**
068: * Generates class bytecodes for proxy for provided class name.
069: * Proxy is created <b>only</b> if there are matched methods for proxyfying.
070: * Otherwise, it returs <code>null</code>.
071: * @see #createProxy(String, boolean, ProxyDefinition[])
072: */
073: public static byte[] createProxy(String targetName,
074: ProxyDefinition... proxyDefinitions) {
075: return createProxy(targetName, false, proxyDefinitions);
076: }
077:
078: /**
079: * Generates class bytecodes for proxy for provided class name.
080: * It allows <b>forced</b> creation, when proxy is created even if there are no
081: * matched methods for proxyfying.
082: */
083: public static byte[] createProxy(String targetName, boolean forced,
084: ProxyDefinition... proxyDefinitions) {
085: ProxyCreator pc = new ProxyCreator(proxyDefinitions);
086: byte[] result = pc.accept(newClassReader(targetName))
087: .toByteArray();
088: if ((forced == false) && (pc.isProxyApplied() == false)) {
089: return null;
090: }
091: return result;
092: }
093:
094: /**
095: * Generates class bytecodes for proxy for class provided from <code>InputStream</code>.
096: * Proxy is created <b>only</b> if there are matched methods for proxyfying.
097: * Otherwise, it returs <code>null</code>.
098: * @see #createProxy(java.io.InputStream, boolean, ProxyDefinition[])
099: */
100: public static byte[] createProxy(InputStream in,
101: ProxyDefinition... proxyDefinitions) {
102: return createProxy(in, false, proxyDefinitions);
103: }
104:
105: /**
106: * Generates class bytecodes for proxy for class provided from <code>InputStream</code>.
107: * It allows <b>forced</b> creation, when proxy is created even if there are no
108: * matched methods for proxyfying.
109: */
110: public static byte[] createProxy(InputStream in, boolean forced,
111: ProxyDefinition... proxyDefinitions) {
112: ProxyCreator pc = new ProxyCreator(proxyDefinitions);
113: byte[] result = pc.accept(newClassReader(in)).toByteArray();
114: if ((forced == false) && (pc.isProxyApplied() == false)) {
115: return null;
116: }
117: return result;
118: }
119:
120: // ---------------------------------------------------------------- define
121:
122: public static Class defineProxy(Class target,
123: ProxyDefinition... proxyDefinitions) {
124: return defineProxy(target, null, false, proxyDefinitions);
125: }
126:
127: public static Class defineProxy(Class target, boolean forced,
128: ProxyDefinition... proxyDefinitions) {
129: return defineProxy(target, null, forced, proxyDefinitions);
130: }
131:
132: public static Class defineProxy(Class target,
133: ClassLoader classLoader,
134: ProxyDefinition... proxyDefinitions) {
135: return defineProxy(target, classLoader, false, proxyDefinitions);
136: }
137:
138: public static Class defineProxy(Class target,
139: ClassLoader classLoader, boolean forced,
140: ProxyDefinition... proxyDefinitions) {
141: String targetName = target.getName();
142: ProxyCreator pc = new ProxyCreator(proxyDefinitions);
143: pc.accept(newClassReader(targetName));
144: if ((forced == false) && (pc.isProxyApplied() == false)) {
145: return target;
146: }
147: if (classLoader == null) {
148: return ClassLoaderUtil.defineClass(targetName
149: + ProxyCreator.SUBCLASS_SUFFIX, pc.toByteArray());
150: }
151: return ClassLoaderUtil.defineClass(targetName
152: + ProxyCreator.SUBCLASS_SUFFIX, pc.toByteArray(),
153: classLoader);
154: }
155:
156: public static Class defineProxy(String targetName,
157: ProxyDefinition... proxyDefinitions) {
158: return defineProxy(targetName, null, false, proxyDefinitions);
159: }
160:
161: public static Class defineProxy(String targetName, boolean forced,
162: ProxyDefinition... proxyDefinitions) {
163: return defineProxy(targetName, null, forced, proxyDefinitions);
164: }
165:
166: public static Class defineProxy(String targetName,
167: ClassLoader classLoader,
168: ProxyDefinition... proxyDefinitions) {
169: return defineProxy(targetName, classLoader, false,
170: proxyDefinitions);
171: }
172:
173: public static Class defineProxy(String targetName,
174: ClassLoader classLoader, boolean forced,
175: ProxyDefinition... proxyDefinitions) {
176: ProxyCreator pc = new ProxyCreator(proxyDefinitions);
177: pc.accept(newClassReader(targetName));
178: if ((forced == false) && (pc.isProxyApplied() == false)) {
179: try {
180: return classLoader.loadClass(targetName);
181: } catch (ClassNotFoundException cnfex) {
182: throw new ProxettaException(cnfex);
183: }
184: }
185: if (classLoader == null) {
186: return ClassLoaderUtil.defineClass(targetName
187: + ProxyCreator.SUBCLASS_SUFFIX, pc.toByteArray());
188: }
189: return ClassLoaderUtil.defineClass(targetName
190: + ProxyCreator.SUBCLASS_SUFFIX, pc.toByteArray(),
191: classLoader);
192: }
193: }
|