KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > util > DjClassInspector


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, is permitted
5  * provided that the following conditions are met:
6  * - Redistributions of source code must retain the above copyright notice, this list of conditions
7  * and the following disclaimer.
8  * - Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * - All advertising materials mentioning features or use of this software must display the
12  * following acknowledgment: "This product includes Djeneric."
13  * - Products derived from this software may not be called "Djeneric" nor may
14  * "Djeneric" appear in their names without prior written permission of Genimen BV.
15  * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
16  * product includes Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.util;
31
32 import java.io.BufferedInputStream JavaDoc;
33 import java.io.File JavaDoc;
34 import java.io.FileInputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.util.ArrayList JavaDoc;
37
38 import com.genimen.djeneric.language.Messages;
39 import com.genimen.djeneric.repository.exceptions.DjenericException;
40
41 public class DjClassInspector
42 {
43   final static int CONSTANT_Utf8 = 1;
44   final static int CONSTANT_Integer = 3;
45   final static int CONSTANT_Float = 4;
46   final static int CONSTANT_Long = 5;
47   final static int CONSTANT_Double = 6;
48   final static int CONSTANT_Class = 7;
49   final static int CONSTANT_String = 8;
50   final static int CONSTANT_Fieldref = 9;
51   final static int CONSTANT_Methodref = 10;
52   final static int CONSTANT_InterfaceMethodref = 11;
53   final static int CONSTANT_NameAndType = 12;
54
55   private byte[] _classDefinition;
56
57   public DjClassInspector()
58   {
59   }
60
61   public DjClassInspector(byte[] classBytes)
62   {
63     setClassDefinition(classBytes);
64   }
65
66   public static byte[] readclass(String JavaDoc fileName) throws IOException JavaDoc
67   {
68     File JavaDoc infile = new File JavaDoc(fileName);
69     long size = infile.length();
70
71     FileInputStream JavaDoc fis = new FileInputStream JavaDoc(infile);
72     BufferedInputStream JavaDoc bis = new BufferedInputStream JavaDoc(fis);
73
74     byte[] buffer = new byte[(int) size];
75     int offset = 0;
76     int totalRead = 0;
77     while (totalRead < size)
78     {
79       totalRead += bis.read(buffer, offset, (int) (size - totalRead));
80     }
81     bis.close();
82     return buffer;
83   }
84
85   int asInt(byte b)
86   {
87     if ((b & 0x80) != 0) return (b & 0x7f) | 0x80;
88     return b;
89
90   }
91
92   long asLong(byte b)
93   {
94     if ((b & 0x80) != 0) return (b & 0x7f) | 0x80;
95     return b;
96   }
97
98   int asInt(byte[] buffer, int offset)
99   {
100     return asInt(buffer[offset]) << 8 | asInt(buffer[offset + 1]);
101   }
102
103   long asLong(byte[] buffer, int offset)
104   {
105     return asLong(buffer[offset]) << 24 | asLong(buffer[offset + 1]) << 16 | asLong(buffer[offset + 2]) << 8
106            | asLong(buffer[offset + 3]);
107   }
108
109   public boolean isValidClass()
110   {
111     byte[] clz = getClassDefinition();
112
113     if (clz == null) return false;
114
115     return asLong(clz, 0) == 0xcafebabeL;
116   }
117
118   public String JavaDoc getClassName() throws DjenericException
119   {
120     byte[] clz = getClassDefinition();
121
122     if (clz == null) return null;
123
124     // int major = asInt(clz, 6);
125
// int minor = asInt(clz, 4);
126
int numConstPoolEntries = asInt(clz, 8);
127
128     if (!isValidClass())
129     {
130       throw new DjenericException(Messages.getString("DjClassInspector.NotAClassFile"));
131     }
132
133     // System.out.println("Class version " + major + "." + minor);
134
// System.out.println("Constpool size " + numConstPoolEntries + " entries");
135

136     ArrayList JavaDoc names = new ArrayList JavaDoc();
137
138     IndexInfo indexInfo = new IndexInfo();
139     indexInfo.idx = 10;
140     indexInfo.poolSize = numConstPoolEntries - 1;
141
142     int i = 0;
143     while (i < indexInfo.poolSize)
144     {
145       readConstant(clz, names, indexInfo);
146       i++;
147     }
148
149     // int accessFlags = asInt(clz, indexInfo.idx);
150
indexInfo.idx += 2;
151
152     int ident = asInt(clz, indexInfo.idx) - 1;
153     int classIdx = Integer.parseInt(names.get(ident).toString());
154
155     return names.get(classIdx - 1).toString();
156   }
157
158   private void readConstant(byte[] clz, ArrayList JavaDoc names, IndexInfo indexInfo)
159   {
160     byte tag = clz[indexInfo.idx++];
161
162     if (tag == CONSTANT_Utf8)
163     {
164       int length = asInt(clz, indexInfo.idx);
165       indexInfo.idx += 2;
166       String JavaDoc name = new String JavaDoc(clz, indexInfo.idx, length);
167       names.add(name);
168       indexInfo.idx += length;
169     }
170     else if (tag == CONSTANT_Class)
171     {
172       int subscript = asInt(clz, indexInfo.idx);
173       indexInfo.idx += 2;
174       names.add(String.valueOf(subscript));
175     }
176     else if (tag == CONSTANT_String)
177     {
178       names.add("S" + asInt(clz, indexInfo.idx));
179       indexInfo.idx += 2;
180     }
181     else if (tag == CONSTANT_Fieldref || tag == CONSTANT_Methodref || tag == CONSTANT_InterfaceMethodref
182              || tag == CONSTANT_NameAndType || tag == CONSTANT_Integer || tag == CONSTANT_Float)
183     {
184       indexInfo.idx += 4;
185       names.add("R" + asLong(clz, indexInfo.idx));
186     }
187     else if (tag == CONSTANT_Long || tag == CONSTANT_Double)
188     {
189       names.add("L");
190       indexInfo.idx += 8;
191       indexInfo.poolSize--;
192     }
193   }
194
195   public byte[] getClassDefinition()
196   {
197     return _classDefinition;
198   }
199
200   public void setClassDefinition(byte[] bs)
201   {
202     _classDefinition = bs;
203   }
204
205   class IndexInfo
206   {
207     public int idx;
208     public int poolSize;
209
210   }
211 }
Popular Tags