blob: 48c0e8dcbb39e323ed6fbd9d2f1fa1db408b4d31 [file] [log] [blame]
briangoetzef42f9a2013-05-06 11:43:51 -04001/*
2 * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24package separate;
25
26import java.io.*;
27import java.util.*;
28
29public class ClassToInterfaceConverter implements ClassFilePreprocessor {
30
31 private String whichClass;
32
33 public ClassToInterfaceConverter(String className) {
34 this.whichClass = className;
35 }
36
37 private boolean utf8Matches(ClassFile.CpEntry entry, String v) {
38 if (!(entry instanceof ClassFile.CpUtf8)) {
39 return false;
40 }
41 ClassFile.CpUtf8 utf8 = (ClassFile.CpUtf8)entry;
42 if (v.length() != utf8.bytes.length) {
43 return false;
44 }
45 for (int i = 0; i < v.length(); ++i) {
46 if (v.charAt(i) != utf8.bytes[i]) {
47 return false;
48 }
49 }
50 return true;
51 }
52
53 private void convertToInterface(ClassFile cf) {
54 cf.access_flags = 0x0601; // ACC_INTERFACE | ACC_ABSTRACT | ACC_PUBLIC
55 ArrayList<ClassFile.Method> new_methods = new ArrayList<>();
56 // Find <init> method and delete it
57 for (int i = 0; i < cf.methods.size(); ++i) {
58 ClassFile.Method method = cf.methods.get(i);
59 ClassFile.CpEntry name = cf.constant_pool.get(method.name_index);
60 if (!utf8Matches(name, "<init>")) {
61 new_methods.add(method);
62 }
63 }
64 cf.methods = new_methods;
65 }
66
67 public byte[] preprocess(String classname, byte[] bytes) {
68 ClassFile cf = new ClassFile(bytes);
69
70 ClassFile.CpEntry entry = cf.constant_pool.get(cf.this_class);
71 ClassFile.CpEntry name = cf.constant_pool.get(
72 ((ClassFile.CpClass)entry).name_index);
73 if (utf8Matches(name, whichClass)) {
74 convertToInterface(cf);
75 return cf.toByteArray();
76 } else {
77 return bytes; // unmodified
78 }
79 }
80
81/*
82 public static void main(String argv[]) throws Exception {
83 File input = new File(argv[0]);
84 byte[] buffer = new byte[(int)input.length()];
85 new FileInputStream(input).read(buffer);
86
87 ClassFilePreprocessor cfp = new ClassToInterfaceConverter("Hello");
88 byte[] cf = cfp.preprocess(argv[0], buffer);
89 new FileOutputStream(argv[0] + ".mod").write(cf);
90 }
91*/
92}