01: /*
02: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
03: * Distributed under the terms of either:
04: * - the common development and distribution license (CDDL), v1.0; or
05: * - the GNU Lesser General Public License, v2.1 or later
06: * $Id: MetaDataBytecodeTransformer.java 3678 2007-03-01 10:40:23Z gbevin $
07: */
08: package com.uwyn.rife.site.instrument;
09:
10: import com.uwyn.rife.asm.ClassReader;
11: import com.uwyn.rife.asm.ClassVisitor;
12: import com.uwyn.rife.asm.ClassWriter;
13: import com.uwyn.rife.site.MetaDataMerged;
14:
15: /**
16: * This utility class provides an entrance method to modify the bytecode of a
17: * class so that meta data from a sibling class is merged into the first class.
18: * <p>
19: * Basically, this automatically creates an instance of the meta data class and
20: * stores it as a field of the modified class. All the interfaces of the meta
21: * data class are also automatically implemented by the modified class by
22: * delegating all the method calls to the added field instance.
23: * <p>
24: * WARNING: this class is not supposed to be used directly, it is made public
25: * since the general RIFE EngineClassLoader has to be able to access it.
26: *
27: * @author Geert Bevin (gbevin[remove] at uwyn dot com)
28: * @version $Revision: 3678 $
29: * @since 1.6
30: */
31: public abstract class MetaDataBytecodeTransformer {
32: /**
33: * Performs the actual merging of the meta data class' functionalities into
34: * the bytes of the class that were provided.
35: *
36: * @param origBytes the bytes that have to be modied
37: * @param metaData the meta data classes that will be merged into it
38: * @return the modified bytes
39: * @since 1.6
40: */
41: public static byte[] mergeMetaDataIntoBytes(byte[] origBytes,
42: Class metaData) {
43: // only perform the instrumentation if the MetaDataMerged interface is implemented
44: if (!MetaDataMerged.class.isAssignableFrom(metaData)) {
45: return origBytes;
46: }
47:
48: // merge the meta data class into the original bytes
49: ClassReader cr = new ClassReader(origBytes);
50:
51: MetaDataMethodCollector method_collector = new MetaDataMethodCollector();
52: cr.accept(method_collector, true);
53:
54: ClassWriter cw = new ClassWriter(true);
55: ClassVisitor meta_data_adapter = new MetaDataClassAdapter(
56: method_collector.getMethods(), metaData, cw);
57: cr.accept(meta_data_adapter, false);
58:
59: return cw.toByteArray();
60: }
61: }
|