lubomir@1084: /** lubomir@1084: * Back 2 Browser Bytecode Translator lubomir@1084: * Copyright (C) 2012 Jaroslav Tulach lubomir@1084: * lubomir@1084: * This program is free software: you can redistribute it and/or modify lubomir@1084: * it under the terms of the GNU General Public License as published by lubomir@1084: * the Free Software Foundation, version 2 of the License. lubomir@1084: * lubomir@1084: * This program is distributed in the hope that it will be useful, lubomir@1084: * but WITHOUT ANY WARRANTY; without even the implied warranty of lubomir@1084: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the lubomir@1084: * GNU General Public License for more details. lubomir@1084: * lubomir@1084: * You should have received a copy of the GNU General Public License lubomir@1084: * along with this program. Look for COPYING file in the top folder. lubomir@1084: * If not, see http://opensource.org/licenses/GPL-2.0. lubomir@1084: */ lubomir@1084: package org.apidesign.vm4brwsr; lubomir@1084: lubomir@1084: import java.io.IOException; lubomir@1084: import java.io.InputStream; lubomir@1084: import java.util.HashMap; lubomir@1084: import java.util.Map; lubomir@1084: import org.apidesign.bck2brwsr.core.ExtraJavaScript; lubomir@1084: import org.apidesign.vm4brwsr.ByteCodeParser.ClassData; lubomir@1085: import org.apidesign.vm4brwsr.ByteCodeParser.FieldData; lubomir@1085: import org.apidesign.vm4brwsr.ByteCodeParser.MethodData; lubomir@1084: lubomir@1084: @ExtraJavaScript(processByteCode = false, resource="") lubomir@1084: final class ClassDataCache { lubomir@1084: private static final Object MISSING_CLASS = new Object(); lubomir@1084: lubomir@1084: private final Bck2Brwsr.Resources resources; lubomir@1084: private final Map classDataMap; lubomir@1084: lubomir@1084: ClassDataCache(final Bck2Brwsr.Resources resources) { lubomir@1084: this.resources = resources; lubomir@1084: lubomir@1084: classDataMap = new HashMap(); lubomir@1084: } lubomir@1084: lubomir@1085: ClassData getClassData(String className) throws IOException { lubomir@1085: if (className.startsWith("[")) { lubomir@1085: // required for accessVirtualMethod, shouldn't be problematic for lubomir@1085: // calls from other sources lubomir@1085: className = "java/lang/Object"; lubomir@1085: } lubomir@1084: Object cacheEntry = classDataMap.get(className); lubomir@1084: if (cacheEntry == null) { lubomir@1084: final InputStream is = loadClass(resources, className); lubomir@1084: cacheEntry = (is != null) ? new ClassData(is) : MISSING_CLASS; lubomir@1084: classDataMap.put(className, cacheEntry); lubomir@1084: } lubomir@1084: lubomir@1084: return (cacheEntry != MISSING_CLASS) ? (ClassData) cacheEntry : null; lubomir@1084: } lubomir@1084: lubomir@1085: MethodData findMethod(final String startingClass, lubomir@1085: final String name, lubomir@1085: final String signature) throws IOException { lubomir@1085: return findMethod(getClassData(startingClass), name, signature); lubomir@1085: } lubomir@1085: lubomir@1085: FieldData findField(final String startingClass, lubomir@1085: final String name, lubomir@1085: final String signature) throws IOException { lubomir@1085: return findField(getClassData(startingClass), name, signature); lubomir@1085: } lubomir@1085: lubomir@1085: MethodData findMethod(ClassData currentClass, lubomir@1085: final String name, lubomir@1085: final String signature) throws IOException { lubomir@1085: while (currentClass != null) { lubomir@1085: final MethodData methodData = lubomir@1085: currentClass.findMethod(name, signature); lubomir@1085: if (methodData != null) { lubomir@1085: return methodData; lubomir@1085: } lubomir@1085: lubomir@1085: final String superClassName = currentClass.getSuperClassName(); lubomir@1085: if (superClassName == null) { lubomir@1085: break; lubomir@1085: } lubomir@1085: currentClass = getClassData(superClassName); lubomir@1085: } lubomir@1085: lubomir@1085: return null; lubomir@1085: } lubomir@1085: lubomir@1085: FieldData findField(ClassData currentClass, lubomir@1085: final String name, lubomir@1085: final String signature) throws IOException { lubomir@1085: while (currentClass != null) { lubomir@1085: final FieldData fieldData = lubomir@1085: currentClass.findField(name, signature); lubomir@1085: if (fieldData != null) { lubomir@1085: return fieldData; lubomir@1085: } lubomir@1085: lubomir@1085: final String superClassName = currentClass.getSuperClassName(); lubomir@1085: if (superClassName == null) { lubomir@1085: break; lubomir@1085: } lubomir@1085: currentClass = getClassData(superClassName); lubomir@1085: } lubomir@1085: lubomir@1085: return null; lubomir@1085: } lubomir@1085: lubomir@1084: private static InputStream loadClass(Bck2Brwsr.Resources l, String name) lubomir@1084: throws IOException { lubomir@1084: return l.get(name + ".class"); // NOI18N lubomir@1084: } lubomir@1084: }