jaroslav@222: /** jaroslav@222: * Back 2 Browser Bytecode Translator jaroslav@222: * Copyright (C) 2012 Jaroslav Tulach jaroslav@222: * jaroslav@222: * This program is free software: you can redistribute it and/or modify jaroslav@222: * it under the terms of the GNU General Public License as published by jaroslav@222: * the Free Software Foundation, version 2 of the License. jaroslav@222: * jaroslav@222: * This program is distributed in the hope that it will be useful, jaroslav@222: * but WITHOUT ANY WARRANTY; without even the implied warranty of jaroslav@222: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the jaroslav@222: * GNU General Public License for more details. jaroslav@222: * jaroslav@222: * You should have received a copy of the GNU General Public License jaroslav@222: * along with this program. Look for COPYING file in the top folder. jaroslav@222: * If not, see http://opensource.org/licenses/GPL-2.0. jaroslav@222: */ jaroslav@222: package org.apidesign.vm4brwsr; jaroslav@222: jaroslav@222: import java.io.IOException; jaroslav@237: import java.lang.annotation.Annotation; jaroslav@654: import java.lang.annotation.Retention; jaroslav@653: import java.lang.annotation.RetentionPolicy; jaroslav@261: import java.lang.reflect.Method; jaroslav@222: import java.net.MalformedURLException; jaroslav@264: import org.apidesign.bck2brwsr.core.JavaScriptBody; jaroslav@222: jaroslav@222: /** jaroslav@222: * jaroslav@222: * @author Jaroslav Tulach jaroslav@222: */ jaroslav@659: @ClassesMarker(number = 10, nicknames = { "Ten", "Deset" }, count = ClassesMarker.E.TWO, subs = { jaroslav@659: @ClassesMarker.Anno(Integer.SIZE), jaroslav@659: @ClassesMarker.Anno(Integer.MIN_VALUE) jaroslav@659: }) jaroslav@662: @ClassesNamer(name = "my text", anno = @ClassesMarker.Anno(333)) jaroslav@222: public class Classes { jaroslav@303: public static String nameOfIO() { jaroslav@303: return nameFor(IOException.class); jaroslav@303: } jaroslav@303: jaroslav@303: private static String nameFor(Class c) { jaroslav@303: return c.getName(); jaroslav@303: } jaroslav@303: jaroslav@649: private static final Class PRELOAD = Runnable.class; jaroslav@649: jaroslav@355: public static boolean isInterface(String s) throws ClassNotFoundException { jaroslav@355: return Class.forName(s).isInterface(); jaroslav@355: } jaroslav@355: jaroslav@222: public static boolean equalsClassesOfExceptions() { jaroslav@222: return MalformedURLException.class.getSuperclass() == IOException.class; jaroslav@222: } jaroslav@222: public static boolean differenceInClasses() { jaroslav@222: Class c1 = MalformedURLException.class; jaroslav@222: Class c2 = IOException.class; jaroslav@222: return c1 != c2; jaroslav@222: } jaroslav@222: jaroslav@225: public static String classForInstance() { jaroslav@225: return new IOException().getClass().getName().toString(); jaroslav@225: } jaroslav@225: jaroslav@652: @ClassesMarker(number = 1, nicknames = { "One", "Jedna" } ) jaroslav@222: public static String name() { jaroslav@223: return IOException.class.getName().toString(); jaroslav@222: } jaroslav@222: public static String simpleName() { jaroslav@222: return IOException.class.getSimpleName(); jaroslav@222: } jaroslav@222: public static String canonicalName() { jaroslav@222: return IOException.class.getCanonicalName(); jaroslav@222: } jaroslav@654: jaroslav@654: public static String objectName() throws NoSuchMethodException { jaroslav@654: return IOException.class.getMethod("wait").getDeclaringClass().getName(); jaroslav@654: } jaroslav@654: jaroslav@231: public static boolean newInstance() throws Exception { jaroslav@231: IOException ioe = IOException.class.newInstance(); jaroslav@231: if (ioe instanceof IOException) { jaroslav@231: return ioe.getClass() == IOException.class; jaroslav@231: } jaroslav@231: throw new IllegalStateException("Not a subtype: " + ioe); jaroslav@222: } jaroslav@397: public static String newInstanceNoPubConstructor() throws Exception { jaroslav@397: try { jaroslav@397: Float f = Float.class.newInstance(); jaroslav@397: return "wrong, can't instantiate: " + f; jaroslav@397: } catch (Exception ex) { jaroslav@397: return (ex.getClass().getName() + ":" + ex.getMessage()).toString().toString(); jaroslav@397: } jaroslav@397: } jaroslav@235: public static int getMarker() { jaroslav@235: if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) { jaroslav@235: return -2; jaroslav@235: } jaroslav@235: ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class); jaroslav@664: assert cm instanceof Object : "Is object " + cm; jaroslav@664: assert cm instanceof Annotation : "Is annotation " + cm; jaroslav@664: assert !((Object)cm instanceof Class) : "Is not Class " + cm; jaroslav@235: return cm == null ? -1 : cm.number(); jaroslav@235: } jaroslav@652: public static String getMarkerNicknames() { jaroslav@652: ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class); jaroslav@652: if (cm == null) { jaroslav@652: return null; jaroslav@652: } jaroslav@660: jaroslav@660: final Object[] arr = cm.nicknames(); jaroslav@660: assert arr instanceof Object[] : "Instance of Object array: " + arr; jaroslav@660: assert arr instanceof String[] : "Instance of String array: " + arr; jaroslav@660: assert !(arr instanceof Integer[]) : "Not instance of Integer array: " + arr; jaroslav@660: jaroslav@652: StringBuilder sb = new StringBuilder(); jaroslav@652: for (String s : cm.nicknames()) { jaroslav@652: sb.append(s).append("\n"); jaroslav@652: } jaroslav@652: return sb.toString().toString(); jaroslav@652: } jaroslav@654: @Retention(RetentionPolicy.CLASS) jaroslav@654: @interface Ann { jaroslav@654: } jaroslav@654: jaroslav@654: public static String getRetention() throws Exception { jaroslav@654: Retention r = Ann.class.getAnnotation(Retention.class); jaroslav@654: assert r != null : "Annotation is present"; jaroslav@654: assert r.value() == RetentionPolicy.CLASS : "Policy value is OK: " + r.value(); jaroslav@654: return r.annotationType().getName(); jaroslav@654: } jaroslav@653: public static String getMarkerE() { jaroslav@653: ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class); jaroslav@653: if (cm == null) { jaroslav@653: return null; jaroslav@653: } jaroslav@653: return cm.count().name(); jaroslav@653: } jaroslav@237: public static String getNamer(boolean direct) { jaroslav@237: if (direct) { jaroslav@237: ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class); jaroslav@237: return cm == null ? null : cm.name(); jaroslav@237: } jaroslav@237: for (Annotation a : Classes.class.getAnnotations()) { jaroslav@237: if (a instanceof ClassesNamer) { jaroslav@237: return ((ClassesNamer)a).name(); jaroslav@237: } jaroslav@237: } jaroslav@237: return null; jaroslav@237: } jaroslav@662: public static int getInnerNamer() { jaroslav@662: ClassesNamer cm = Classes.class.getAnnotation(ClassesNamer.class); jaroslav@662: assert cm != null : "ClassesNamer is present"; jaroslav@662: return cm.anno().value(); jaroslav@662: } jaroslav@665: public static int getInnerNamers() { jaroslav@665: ClassesMarker cm = Classes.class.getAnnotation(ClassesMarker.class); jaroslav@665: assert cm != null : "ClassesNamer is present"; jaroslav@665: int sum = 0; jaroslav@665: for (ClassesMarker.Anno anno : cm.subs()) { jaroslav@665: sum += anno.value(); jaroslav@665: } jaroslav@665: return sum; jaroslav@665: } jaroslav@261: jaroslav@353: public static String intType() { jaroslav@353: return Integer.TYPE.getName(); jaroslav@353: } jaroslav@353: jaroslav@354: public static int primitive() { jaroslav@354: return 1; jaroslav@354: } jaroslav@355: public static boolean primitiveB() { jaroslav@355: return true; jaroslav@355: } jaroslav@354: jaroslav@355: public static String primitiveType(String method) throws Exception { jaroslav@355: return reflectiveMethodCall(false, method).getClass().getName(); jaroslav@354: } jaroslav@354: jaroslav@264: @JavaScriptBody(args = "msg", body = "throw msg;") jaroslav@264: private static native void thrw(String msg); jaroslav@264: jaroslav@265: public static Object reflectiveMethodCall(boolean direct, String mn) throws Exception { jaroslav@264: Method find = null; jaroslav@264: StringBuilder sb = new StringBuilder(); jaroslav@261: if (!direct) { jaroslav@261: final Class v = ClassesMarker.class; jaroslav@264: for (Method m : Classes.class.getMethods()) { jaroslav@264: sb.append("\n").append(m.getName()); jaroslav@265: if (mn != null) { jaroslav@265: if (m.getName().equals(mn)) { jaroslav@265: find = m; jaroslav@265: break; jaroslav@265: } jaroslav@265: } else { jaroslav@265: if (m.getAnnotation(v) != null) { jaroslav@265: find = m; jaroslav@265: break; jaroslav@265: } jaroslav@261: } jaroslav@261: } jaroslav@264: } else { jaroslav@265: find = Classes.class.getMethod(mn); jaroslav@261: } jaroslav@264: if (find == null) { jaroslav@264: thrw(sb.toString()); jaroslav@264: throw new NullPointerException(sb.toString()); jaroslav@264: } jaroslav@264: return find.invoke(null); jaroslav@261: } jaroslav@418: jaroslav@418: public static int reflectiveSum(int a, int b) throws Exception { jaroslav@418: Method m = StaticMethod.class.getMethod("sum", int.class, int.class); jaroslav@418: return (int) m.invoke(null, a, b); jaroslav@418: } jaroslav@733: jaroslav@733: private abstract class Application { jaroslav@733: public abstract int getID(); jaroslav@733: } jaroslav@733: jaroslav@733: private class MyApplication extends Application { jaroslav@733: @Override jaroslav@733: public int getID() { jaroslav@733: return 1; jaroslav@733: } jaroslav@733: } jaroslav@733: jaroslav@733: public static boolean isClassAssignable() { jaroslav@733: return Application.class.isAssignableFrom(MyApplication.class); jaroslav@733: } jaroslav@733: jaroslav@222: }