001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.classreader;
034:
035: public class ClassDependencyCollector extends CollectorBase {
036: private Class_info this Class;
037: private boolean top = true;
038:
039: public void visitClassfile(Classfile classfile) {
040: this Class = classfile.getRawClass();
041:
042: classfile.getConstantPool().accept(this );
043:
044: classfile.getRawSuperclass().accept(this );
045:
046: for (Class_info class_info : classfile.getAllInterfaces()) {
047: class_info.accept(this );
048: }
049:
050: for (Field_info field : classfile.getAllFields()) {
051: field.accept(this );
052: }
053:
054: for (Method_info method : classfile.getAllMethods()) {
055: method.accept(this );
056: }
057: }
058:
059: public void visitClass_info(Class_info entry) {
060: String classname = entry.getName();
061:
062: if (entry != this Class) {
063: if (classname.startsWith("[")) {
064: top = false;
065: entry.getRawName().accept(this );
066: top = true;
067: } else {
068: add(classname);
069: }
070: }
071: }
072:
073: public void visitFieldRef_info(FieldRef_info entry) {
074: if (top) {
075: if (entry.getRawClass() == this Class) {
076: top = false;
077: entry.getRawNameAndType().accept(this );
078: top = true;
079: }
080: } else {
081: entry.getRawNameAndType().accept(this );
082: }
083: }
084:
085: public void visitMethodRef_info(MethodRef_info entry) {
086: if (top) {
087: if (entry.getRawClass() == this Class) {
088: top = false;
089: entry.getRawNameAndType().accept(this );
090: top = true;
091: }
092: } else {
093: entry.getRawNameAndType().accept(this );
094: }
095: }
096:
097: public void visitInterfaceMethodRef_info(
098: InterfaceMethodRef_info entry) {
099: if (top) {
100: if (entry.getRawClass() == this Class) {
101: top = false;
102: entry.getRawNameAndType().accept(this );
103: top = true;
104: }
105: } else {
106: entry.getRawNameAndType().accept(this );
107: }
108: }
109:
110: public void visitString_info(String_info entry) {
111: if (!top) {
112: entry.getRawValue().accept(this );
113: }
114: }
115:
116: public void visitNameAndType_info(NameAndType_info entry) {
117: if (!top) {
118: entry.getRawType().accept(this );
119: }
120: }
121:
122: public void visitUTF8_info(UTF8_info entry) {
123: if (!top) {
124: processSignature(entry.getValue());
125: }
126: }
127:
128: public void visitField_info(Field_info entry) {
129: processSignature(entry.getDescriptor());
130:
131: super .visitField_info(entry);
132: }
133:
134: public void visitMethod_info(Method_info entry) {
135: processSignature(entry.getDescriptor());
136:
137: super .visitMethod_info(entry);
138: }
139:
140: public void visitLocalVariable(LocalVariable helper) {
141: processSignature(helper.getDescriptor());
142:
143: super .visitLocalVariable(helper);
144: }
145:
146: private void processSignature(String str) {
147: int currentPos = 0;
148: int startPos;
149: int endPos;
150:
151: while ((startPos = str.indexOf('L', currentPos)) != -1) {
152: if ((endPos = str.indexOf(';', startPos)) != -1) {
153: String candidate = str.substring(startPos + 1, endPos);
154: if (!this Class.getName().equals(candidate)) {
155: add(SignatureHelper.path2ClassName(candidate));
156: }
157: currentPos = endPos + 1;
158: } else {
159: currentPos = startPos + 1;
160: }
161: }
162: }
163: }
|