001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.transformer;
032:
033: import net.sf.retrotranslator.runtime.asm.*;
034: import net.sf.retrotranslator.runtime.impl.*;
035:
036: /**
037: * @author Taras Puchko
038: */
039: class MemberFinder extends EmptyVisitor {
040:
041: private final TargetEnvironment environment;
042: private final boolean method;
043: private final boolean stat;
044: private final String name;
045: private final String desc;
046:
047: private String super Name;
048: private String[] interfaces;
049: private int found;
050:
051: public MemberFinder(TargetEnvironment environment, boolean method,
052: boolean stat, String name, String desc) {
053: this .environment = environment;
054: this .method = method;
055: this .stat = stat;
056: this .name = name;
057: this .desc = desc;
058: }
059:
060: public int findIn(String className, String location)
061: throws ClassNotFoundException {
062: if (className == null)
063: return 0;
064: try {
065: environment.getClassReader(className).accept(this , true);
066: } catch (ClassNotFoundException e) {
067: if (location == null)
068: throw e;
069: throw new ClassNotFoundException(e.getMessage()
070: + ", location: " + location, e);
071: }
072: if (found > 0 || name.equals(RuntimeTools.CONSTRUCTOR_NAME)) {
073: return found;
074: }
075: String super ClassName = super Name;
076: for (String interfaceName : interfaces) {
077: if (findIn(interfaceName, className) > 0)
078: return found;
079: }
080: return findIn(super ClassName, className);
081: }
082:
083: public void visit(int version, int access, String name,
084: String signature, String super Name, String[] interfaces) {
085: this .super Name = super Name;
086: this .interfaces = interfaces;
087: }
088:
089: public FieldVisitor visitField(int access, String name,
090: String desc, String signature, Object value) {
091: if (!method)
092: check(access, name, desc);
093: return null;
094: }
095:
096: public MethodVisitor visitMethod(int access, String name,
097: String desc, String signature, String[] exceptions) {
098: if (method)
099: check(access, name, desc);
100: return null;
101: }
102:
103: private void check(int access, String name, String desc) {
104: if (name.equals(this .name) && desc.equals(this .desc)
105: && stat == ((access & Opcodes.ACC_STATIC) != 0))
106: found++;
107: }
108: }
|