1 | /*
|
---|
2 | * Copyright 2000,2002,2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.taskdefs.optional.jlink;
|
---|
18 |
|
---|
19 | import java.io.DataInput;
|
---|
20 | import java.io.DataInputStream;
|
---|
21 | import java.io.IOException;
|
---|
22 | import java.io.InputStream;
|
---|
23 |
|
---|
24 | /**
|
---|
25 | * Reads just enough of a class file to determine the class' full name.
|
---|
26 | *
|
---|
27 | * <p>Extremely minimal constant pool implementation, mainly to support extracting
|
---|
28 | * strings from a class file.
|
---|
29 | */
|
---|
30 | class ConstantPool {
|
---|
31 |
|
---|
32 | static final
|
---|
33 | byte UTF8 = 1, UNUSED = 2, INTEGER = 3, FLOAT = 4, LONG = 5, DOUBLE = 6,
|
---|
34 | CLASS = 7, STRING = 8, FIELDREF = 9, METHODREF = 10,
|
---|
35 | INTERFACEMETHODREF = 11, NAMEANDTYPE = 12;
|
---|
36 |
|
---|
37 | byte[] types;
|
---|
38 |
|
---|
39 | Object[] values;
|
---|
40 |
|
---|
41 | ConstantPool(DataInput data) throws IOException {
|
---|
42 | super();
|
---|
43 |
|
---|
44 | int count = data.readUnsignedShort();
|
---|
45 | types = new byte [ count ];
|
---|
46 | values = new Object [ count ];
|
---|
47 | // read in all constant pool entries.
|
---|
48 | for (int i = 1; i < count; i++) {
|
---|
49 | byte type = data.readByte();
|
---|
50 | types[i] = type;
|
---|
51 | switch (type) {
|
---|
52 | case UTF8 :
|
---|
53 | values[i] = data.readUTF();
|
---|
54 | break;
|
---|
55 |
|
---|
56 | case UNUSED :
|
---|
57 | break;
|
---|
58 |
|
---|
59 | case INTEGER :
|
---|
60 | values[i] = new Integer(data.readInt());
|
---|
61 | break;
|
---|
62 |
|
---|
63 | case FLOAT :
|
---|
64 | values[i] = new Float(data.readFloat());
|
---|
65 | break;
|
---|
66 |
|
---|
67 | case LONG :
|
---|
68 | values[i] = new Long(data.readLong());
|
---|
69 | ++i;
|
---|
70 | break;
|
---|
71 |
|
---|
72 | case DOUBLE :
|
---|
73 | values[i] = new Double(data.readDouble());
|
---|
74 | ++i;
|
---|
75 | break;
|
---|
76 |
|
---|
77 | case CLASS :
|
---|
78 | case STRING :
|
---|
79 | values[i] = new Integer(data.readUnsignedShort());
|
---|
80 | break;
|
---|
81 |
|
---|
82 | case FIELDREF :
|
---|
83 | case METHODREF :
|
---|
84 | case INTERFACEMETHODREF :
|
---|
85 | case NAMEANDTYPE :
|
---|
86 | values[i] = new Integer(data.readInt());
|
---|
87 | break;
|
---|
88 | }
|
---|
89 | }
|
---|
90 | }
|
---|
91 | }
|
---|
92 |
|
---|
93 | /**
|
---|
94 | * Provides a quick and dirty way to determine the true name of a class
|
---|
95 | * given just an InputStream. Reads in just enough to perform this
|
---|
96 | * minimal task only.
|
---|
97 | */
|
---|
98 | public class ClassNameReader extends Object {
|
---|
99 |
|
---|
100 | public static String getClassName(InputStream input) throws IOException {
|
---|
101 | DataInputStream data = new DataInputStream(input);
|
---|
102 | // verify this is a valid class file.
|
---|
103 | int cookie = data.readInt();
|
---|
104 | if (cookie != 0xCAFEBABE) {
|
---|
105 | return null;
|
---|
106 | }
|
---|
107 | /* int version = */ data.readInt();
|
---|
108 | // read the constant pool.
|
---|
109 | ConstantPool constants = new ConstantPool(data);
|
---|
110 | Object[] values = constants.values;
|
---|
111 | // read access flags and class index.
|
---|
112 | /* int accessFlags = */ data.readUnsignedShort();
|
---|
113 | int classIndex = data.readUnsignedShort();
|
---|
114 | Integer stringIndex = (Integer) values[classIndex];
|
---|
115 | String className = (String) values[stringIndex.intValue()];
|
---|
116 | return className;
|
---|
117 | }
|
---|
118 |
|
---|
119 |
|
---|
120 | }
|
---|
121 |
|
---|
122 |
|
---|