
com.google.gwt.reflect.client.ConstPool Maven / Gradle / Ivy
package com.google.gwt.reflect.client;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.core.client.UnsafeNativeLong;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.reflect.client.strategy.GwtRetention;
import com.google.gwt.reflect.client.strategy.ReflectionStrategy;
import com.google.gwt.reflect.shared.ClassMap;
import com.google.gwt.reflect.shared.GwtReflect;
import com.google.gwt.reflect.shared.MemberPool;
public class ConstPool extends JavaScriptObject {
static final ConstPool CONSTS;
static {
if (GWT.isClient()) {
CONSTS = initConstPool();
enhance(CONSTS);
}
else {
CONSTS = null;
}
}
private static native ConstPool initConstPool()
/*-{
return $wnd.Reflect;
}-*/;
protected ConstPool() {}
// Allow the gwt compiler to enhance the const pool.
// When eager class loading is enabled, we will hold onto
// this method call, and use it to inject code "backwards in time",
// and thus eagerly load properly annotated types.
private static native ConstPool enhance(ConstPool pool)
/*-{
$wnd.Reflect = pool;
return pool;
}-*/;
/**
* WARNING!!
*
* Use of this method will cause the inclusion of ALL types annotated with {@link ReflectionStrategy},
* and all type and member dependencies declared with {@link GwtRetention}.
*
* The {@link GWT#runAsync} class id for this split point is com.google.gwt.reflect.client.ConstPool.
*
* This _MIGHT_ be what you want,
* but it _WILL_ slow down your compile,
* and cause some code bloat.
*
* In order to mitigate some of these negative effects,
* the code containing this monolithic collection of classes, methodes, fields, constructors,
* annotations and constants will be put behind it's own GWT.runAsync split point.
*
* However, you must still use some responsibility in calling this method.
*
* The best place to call it is AFTER you've loaded your bootstrap code (exclusive code fragments),
* and BEFORE your non-exclusive left-over fragments. This will allow your bootstrap to remain
* lean, and then you suck in all the types and members of core shared code into an
* exclusive fragment, so all your non-exclusive leftovers will only contain unique code,
* with minimal clinit() calls sprinkled around (since all shared code will already have clinit() called).
*
* @param callback
*/
public static void loadConstPool(final Callback callback) {
if (GWT.isClient()) {
com.google.gwt.core.client.GWT.runAsync(ConstPool.class, new RunAsyncCallback() {
@Override
public void onSuccess() {
fillConstPool();
callback.onSuccess(getConstPool());
}
@Override
public void onFailure(Throwable reason) {
callback.onFailure(reason);
}
});
} else {
// no jvm support yet
callback.onSuccess(null);
}
}
public static Object setPrimitiveArray(Class> componentType, Object array) {
assert array != null;
assert isPrimitiveArray(array);
ConstPool.CONSTS.arraySet(GwtReflect.constId(componentType), array);
return array;
}
public static T[] setArray(Class> componentType, T[] array) {
ConstPool.CONSTS.arraySet(GwtReflect.constId(componentType), array);
return array;
}
public static native boolean isPrimitive(int constId)
/*-{
switch(@com.google.gwt.reflect.shared.GwtReflect::constId(Ljava/lang/Class;)(cls)) {
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_byte:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_char:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_double:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_boolean:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_float:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_int:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_long:
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_short:
return true;
default:
return false;
}
}-*/;
@SuppressWarnings("unchecked")
public static Iterable> extractClasses(ClassLoader loader) {
try {
Object classes = GwtReflect.fieldGet(ClassLoader.class, "classes", loader);
if (GWT.isProdMode()) {
// we have a js object of classes
JavaScriptObject all = (JavaScriptObject)classes;
return fillArray(new ArrayList>(), all);
} else {
// standard jvm. Hope this works (should be a Vector)!
return (Collection>)classes;
}
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException)e : new RuntimeException(e);
}
}
protected static boolean isPrimitiveArray(Object array) {
if (array == null)return false;
Class> c = array.getClass().getComponentType();
return c == null ? false : isPrimitive(GwtReflect.constId(c));
}
protected static native void setEnhancedClass(int constId, ClassMap> cls)
/*-{
@com.google.gwt.reflect.client.ConstPool::CONSTS.$[constId]=cls;
}-*/;
public static ConstPool getConstPool() {
return ConstPool.CONSTS;
}
private static void fillConstPool() {
}
private static native Iterable> fillArray(ArrayList> list, JavaScriptObject all)
/*-{
for (var i in all) {
if (all.hasOwnProperty(i))
[email protected]::add(Ljava/lang/Object;)(all[i]);
}
return list;
}-*/;
public final native T getAnnotation(int id)
/*-{
return this.a[id];
}-*/;
public final native Class getClass(int id)
/*-{
return this.c[id];
}-*/;
public final native Class> getClassByName(String className)
/*-{
return this.n[className];
}-*/;
public final native boolean getDouble(int id)
/*-{
return this.d[id];
}-*/;
public final native > E getEnum(int id)
/*-{
return this.e[id];
}-*/;
public final native int getInt(int id)
/*-{
return this.i[id];
}-*/;
@UnsafeNativeLong
public final native long getLong(int id)
/*-{
return this.l[id];
}-*/;
public final native String getString(int id)
/*-{
return this.s[id];
}-*/;
public final native T[] getArrayObjects(int id)
/*-{
return this._o[id];
}-*/;
public final native int[] getArrayInt(int id)
/*-{
return this._i[id];
}-*/;
final ClassMap getClassData(Class> c) {
String pkg = c.getPackage().getName();
return getClassData(c.getPackage().getName(), c.getName().replace(pkg+".", ""));
}
final native ClassMap getClassData(String pkg, String cls)
/*-{
var map = this, i = pkg.indexOf('.'), nextMap;
while (i > -1) {
nextMap = map[pkg.substr(0, next)];
if (nextMap == null) {
return null;
}
pkg = pkg.substr(next+1);
i = name.indexOf('.');
map = nextMap;
}
return map[cls];
}-*/;
protected final native void arraySet(int id, Object array)
/*-{
switch (id) {
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_Annotation:
@com.google.gwt.reflect.client.ConstPool::CONSTS._a[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_byte:
@com.google.gwt.reflect.client.ConstPool::CONSTS._b[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_char:
@com.google.gwt.reflect.client.ConstPool::CONSTS._c[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_double:
@com.google.gwt.reflect.client.ConstPool::CONSTS._d[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_Enum:
@com.google.gwt.reflect.client.ConstPool::CONSTS._e[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_boolean:
@com.google.gwt.reflect.client.ConstPool::CONSTS._z[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_float:
@com.google.gwt.reflect.client.ConstPool::CONSTS._f[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_int:
@com.google.gwt.reflect.client.ConstPool::CONSTS._i[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_long:
@com.google.gwt.reflect.client.ConstPool::CONSTS._j[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_Class:
@com.google.gwt.reflect.client.ConstPool::CONSTS._l[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_short:
@com.google.gwt.reflect.client.ConstPool::CONSTS._s[id] = array;
break;
case @com.google.gwt.reflect.client.ConstPool.Ids::ID_String:
@com.google.gwt.reflect.client.ConstPool::CONSTS._t[id] = array;
break;
default:
@com.google.gwt.reflect.client.ConstPool::CONSTS._o[id] = array;
}
return array;
}-*/;
public final native Iterable> getAllClasses()
/*-{
return @com.google.gwt.reflect.client.ConstPool::fillArray(Ljava/util/ArrayList;Lcom/google/gwt/core/client/JavaScriptObject;)
(@java.util.ArrayList::new()(), this.c);
}-*/;
public final native Iterable> getAllEnhancedClasses()
/*-{
return @com.google.gwt.reflect.client.ConstPool::fillArray(Ljava/util/ArrayList;Lcom/google/gwt/core/client/JavaScriptObject;)
(@java.util.ArrayList::new()(), this.$);
}-*/;
public final native Iterable> getAllReflectionData()
/*-{
return @com.google.gwt.reflect.client.ConstPool::fillArray(Ljava/util/ArrayList;Lcom/google/gwt/core/client/JavaScriptObject;)
(@java.util.ArrayList::new()(), this.$$);
}-*/;
@SuppressWarnings("rawtypes")
public static interface ClassConsts {
Class CLASS_Class = Class.class;
Class