1 package org.apache.bcel.classfile;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2001 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache BCEL" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache BCEL", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56
57 import org.apache.bcel.Constants;
58 import java.io.*;
59
60 /***
61 * This class is derived from <em>Attribute</em> and represents a reference
62 * to a <href="http://wwwipd.ira.uka.de/~pizza/gj/">GJ</a> attribute.
63 *
64 * @version $Id: Signature.java,v 1.3 2002/03/11 16:16:35 mdahm Exp $
65 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
66 * @see Attribute
67 */
68 public final class Signature extends Attribute {
69 private int signature_index;
70
71 /***
72 * Initialize from another object. Note that both objects use the same
73 * references (shallow copy). Use clone() for a physical copy.
74 */
75 public Signature(Signature c) {
76 this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool());
77 }
78
79 /***
80 * Construct object from file stream.
81 * @param name_index Index in constant pool to CONSTANT_Utf8
82 * @param length Content length in bytes
83 * @param file Input stream
84 * @param constant_pool Array of constants
85 * @throws IOException
86 */
87 Signature(int name_index, int length, DataInputStream file,
88 ConstantPool constant_pool) throws IOException
89 {
90 this(name_index, length, file.readUnsignedShort(), constant_pool);
91 }
92
93 /***
94 * @param name_index Index in constant pool to CONSTANT_Utf8
95 * @param length Content length in bytes
96 * @param constant_pool Array of constants
97 * @param Signature_index Index in constant pool to CONSTANT_Utf8
98 */
99 public Signature(int name_index, int length, int signature_index,
100 ConstantPool constant_pool)
101 {
102 super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool);
103 this.signature_index = signature_index;
104 }
105
106 /***
107 * Called by objects that are traversing the nodes of the tree implicitely
108 * defined by the contents of a Java class. I.e., the hierarchy of methods,
109 * fields, attributes, etc. spawns a tree of objects.
110 *
111 * @param v Visitor object
112 */
113 public void accept(Visitor v) {
114 System.err.println("Visiting non-standard Signature object");
115 v.visitSignature(this);
116 }
117
118 /***
119 * Dump source file attribute to file stream in binary format.
120 *
121 * @param file Output file stream
122 * @throws IOException
123 */
124 public final void dump(DataOutputStream file) throws IOException
125 {
126 super.dump(file);
127 file.writeShort(signature_index);
128 }
129
130 /***
131 * @return Index in constant pool of source file name.
132 */
133 public final int getSignatureIndex() { return signature_index; }
134
135 /***
136 * @param Signature_index.
137 */
138 public final void setSignatureIndex(int signature_index) {
139 this.signature_index = signature_index;
140 }
141
142 /***
143 * @return GJ signature.
144 */
145 public final String getSignature() {
146 ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(signature_index,
147 Constants.CONSTANT_Utf8);
148 return c.getBytes();
149 }
150
151 /***
152 * Extends ByteArrayInputStream to make 'unreading' chars possible.
153 */
154 private static final class MyByteArrayInputStream extends ByteArrayInputStream {
155 MyByteArrayInputStream(String data) { super(data.getBytes()); }
156 final int mark() { return pos; }
157 final String getData() { return new String(buf); }
158 final void reset(int p) { pos = p; }
159 final void unread() { if(pos > 0) pos--; }
160 }
161
162 private static boolean identStart(int ch) {
163 return ch == 'T' || ch == 'L';
164 }
165
166 private static boolean identPart(int ch) {
167 return ch == '/' || ch == ';';
168 }
169
170 private static final void matchIdent(MyByteArrayInputStream in, StringBuffer buf) {
171 int ch;
172
173 if((ch = in.read()) == -1)
174 throw new RuntimeException("Illegal signature: " + in.getData() +
175 " no ident, reaching EOF");
176
177 //System.out.println("return from ident:" + (char)ch);
178
179 if(!identStart(ch)) {
180 StringBuffer buf2 = new StringBuffer();
181
182 int count = 1;
183 while(Character.isJavaIdentifierPart((char)ch)) {
184 buf2.append((char)ch);
185 count++;
186 ch = in.read();
187 }
188
189 if(ch == ':') { // Ok, formal parameter
190 in.skip("Ljava/lang/Object".length());
191 buf.append(buf2);
192
193 ch = in.read();
194 in.unread();
195 //System.out.println("so far:" + buf2 + ":next:" +(char)ch);
196 } else {
197 for(int i=0; i < count; i++)
198 in.unread();
199 }
200
201 return;
202 }
203
204 StringBuffer buf2 = new StringBuffer();
205 ch = in.read();
206
207 do {
208 buf2.append((char)ch);
209 ch = in.read();
210 //System.out.println("within ident:"+ (char)ch);
211
212 } while((ch != -1) && (Character.isJavaIdentifierPart((char)ch) || (ch == '/')));
213
214 buf.append(buf2.toString().replace('/', '.'));
215
216 //System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
217
218 if(ch != -1)
219 in.unread();
220 }
221
222 private static final void matchGJIdent(MyByteArrayInputStream in,
223 StringBuffer buf)
224 {
225 int ch;
226
227 matchIdent(in, buf);
228
229 ch = in.read();
230 if((ch == '<') || ch == '(') { // Parameterized or method
231 //System.out.println("Enter <");
232 buf.append((char)ch);
233 matchGJIdent(in, buf);
234
235 while(((ch = in.read()) != '>') && (ch != ')')) { // List of parameters
236 if(ch == -1)
237 throw new RuntimeException("Illegal signature: " + in.getData() +
238 " reaching EOF");
239
240 //System.out.println("Still no >");
241 buf.append(", ");
242 in.unread();
243 matchGJIdent(in, buf); // Recursive call
244 }
245
246 //System.out.println("Exit >");
247
248 buf.append((char)ch);
249 } else
250 in.unread();
251
252 ch = in.read();
253 if(identStart(ch)) {
254 in.unread();
255 matchGJIdent(in, buf);
256 } else if(ch == ')') {
257 in.unread();
258 return;
259 } else if(ch != ';')
260 throw new RuntimeException("Illegal signature: " + in.getData() + " read " +
261 (char)ch);
262 }
263
264 public static String translate(String s) {
265 //System.out.println("Sig:" + s);
266 StringBuffer buf = new StringBuffer();
267
268 matchGJIdent(new MyByteArrayInputStream(s), buf);
269
270 return buf.toString();
271 }
272
273 public static final boolean isFormalParameterList(String s) {
274 return s.startsWith("<") && (s.indexOf(':') > 0);
275 }
276
277 public static final boolean isActualParameterList(String s) {
278 return s.startsWith("L") && s.endsWith(">;");
279 }
280
281 /***
282 * @return String representation
283 */
284 public final String toString() {
285 String s = getSignature();
286
287 return "Signature(" + s + ")";
288 }
289
290 /***
291 * @return deep copy of this attribute
292 */
293 public Attribute copy(ConstantPool constant_pool) {
294 return (Signature)clone();
295 }
296 }
This page was automatically generated by Maven