KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > jclasslib > structures > AbstractStructure


1 /*
2     This library is free software; you can redistribute it and/or
3     modify it under the terms of the GNU General Public
4     License as published by the Free Software Foundation; either
5     version 2 of the license, or (at your option) any later version.
6 */

7
8 package org.gjt.jclasslib.structures;
9
10 import org.gjt.jclasslib.io.Log;
11
12 import java.io.*;
13 import java.lang.reflect.Array JavaDoc;
14
15 /**
16  * Base class for all structures defined in the class file format. <p>
17  * Provides common services such as reading, writing and debugging.
18  *
19  * @author <a HREF="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>, <a HREF="mailto:vitor.carreira@gmail.com">Vitor Carreira</a>
20  * @version $Revision: 1.5 $ $Date: 2004/12/28 13:04:32 $
21  */

22 public abstract class AbstractStructure {
23
24     /**
25      * Set this JVM System property to true to switch on debugging for
26      * reading and writing class files.
27      */

28     public static final String JavaDoc SYSTEM_PROPERTY_DEBUG = "jclasslib.io.debug";
29
30     /**
31      * Parent class file for this structure. <tt>Null</tt> for a <tt>ClassFile</tt>
32      * structure.
33      */

34     protected ClassFile classFile;
35
36     /**
37      * Flag for debugging while reading and writing class files.
38      */

39     protected boolean debug;
40
41     /**
42      * Constructor.
43      */

44     protected AbstractStructure() {
45         debug = Boolean.getBoolean(SYSTEM_PROPERTY_DEBUG);
46     }
47
48     /**
49      * Get parent class file.
50      *
51      * @return the class file
52      */

53     public ClassFile getClassFile() {
54         return classFile;
55     }
56
57     /**
58      * Set parent class file. <p>
59      * <p/>
60      * Has to be called at least once on a structure.
61      *
62      * @param classFile the new parent class file
63      */

64     public void setClassFile(ClassFile classFile) {
65         this.classFile = classFile;
66     }
67
68     /**
69      * Read this structure from the given <tt>DataInput</tt>. <p>
70      * <p/>
71      * Excpects <tt>DataInput</tt> to be in JVM class file format and just
72      * before a structure of this kind. No look ahead parsing since
73      * the class file format is deterministic.
74      *
75      * @param in the <tt>DataInput</tt> from which to read
76      * @throws InvalidByteCodeException if the byte code is invalid
77      * @throws IOException if an exception occurs with the <tt>DataInput</tt>
78      */

79     public void read(DataInput in)
80             throws InvalidByteCodeException, IOException {
81     }
82
83     /**
84      * Write this structure to the given <tt>DataOutput</tt>. <p>
85      * <p/>
86      * The written bytes are in JVM class file format.
87      *
88      * @param out the <tt>DataOutput</tt> to which to write
89      * @throws InvalidByteCodeException if the structure is internally inconsistent
90      * @throws IOException if an exception occurs with the <tt>DataOutput</tt>
91      */

92     public void write(DataOutput out)
93             throws InvalidByteCodeException, IOException {
94     }
95
96     /**
97      * Get the debug mode for this structure.
98      *
99      * @return whether debug is on or not
100      */

101     public boolean getDebug() {
102         return debug;
103     }
104
105     /**
106      * Set the debug mode for this structure.
107      *
108      * @param debug the new debug mode
109      */

110     public void setDebug(boolean debug) {
111         this.debug = debug;
112     }
113
114     /**
115      * Utility method for derived structures. Get the
116      * length of an arbitrary array which may hold
117      * primitive types or reference types or may be null.
118      *
119      * @param array the array for which the length is requested
120      * @return the length
121      */

122     protected int getLength(Object JavaDoc array) {
123         if (array == null || !array.getClass().isArray()) {
124             return 0;
125         } else {
126             return Array.getLength(array);
127         }
128     }
129
130     /**
131      * Utility method for derived structures. Dump a specific debug message.
132      *
133      * @param message the debug message
134      */

135     protected void debug(String JavaDoc message) {
136         if (debug) {
137             Log.debug(message);
138         }
139     }
140
141     /**
142      * Utility method for derived structures. Print an int value as a hex string.
143      *
144      * @param bytes the int value to print as a hex string
145      * @return the hex string
146      */

147     protected String JavaDoc printBytes(int bytes) {
148         return padHexString(Integer.toHexString(bytes), 8);
149     }
150
151     /**
152      * Utility method for derived structures. Print an access flag or an
153      * unsigned short value as a hex string.
154      *
155      * @param accessFlags the unsigned short value to print as a hex string
156      * @return the hex string
157      */

158     protected String JavaDoc printAccessFlags(int accessFlags) {
159         return padHexString(Integer.toHexString(accessFlags), 4);
160     }
161
162     private String JavaDoc padHexString(String JavaDoc hexString, int length) {
163         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("0x");
164
165         for (int i = hexString.length(); i < length; i++) {
166             buffer.append('0');
167         }
168         buffer.append(hexString);
169
170         return buffer.toString();
171     }
172
173     /**
174      * Utility method for derived structures. Print an access flag as
175      * a space separated list of verbose java access modifiers.
176      *
177      * @param accessFlags the unsigned short value to print as a hex string
178      * @return the hex string
179      */

180     abstract protected String JavaDoc printAccessFlagsVerbose(int accessFlags);
181
182     /**
183      * Utility method for derived structures. Print an access flag as
184      * a space separated list of verbose java access modifiers.
185      *
186      * @param availableAccessFlags array with the access flags available
187      * for the derived structure
188      * @param availableAccessFlagsVerbose array with verbose description
189      * of the access flags available for the derived structure
190      * @param accessFlags the unsigned short value to print as a hex string
191      * @return the access flags verbose description
192      */

193     protected String JavaDoc printAccessFlagsVerbose(int[] availableAccessFlags, String JavaDoc[] availableAccessFlagsVerbose,
194                                              int accessFlags) {
195         StringBuffer JavaDoc accessFlagsVerbose = new StringBuffer JavaDoc();
196
197
198         int all = 0;
199         for (int i = 0; i < availableAccessFlags.length; i++) {
200             all |= availableAccessFlags[i];
201             if ((accessFlags & availableAccessFlags[i]) != 0) {
202                 accessFlagsVerbose.append(availableAccessFlagsVerbose[i]).append(' ');
203             }
204         }
205         
206         // Check if every possible flag has been processed
207
if ((all | accessFlags) != all) {
208             accessFlagsVerbose.append("? ");
209         }
210         if (accessFlagsVerbose.length() > 0) {
211             accessFlagsVerbose.setLength(accessFlagsVerbose.length() - 1);
212         }
213         return accessFlagsVerbose.toString();
214     }
215
216 }
217
Popular Tags