/** * Sets a handle internally used to create MetaClass implementations. When replacing the handle * with a custom version, you should reuse the old handle to keep custom logic and to use the * default logic as fall back. WARNING: experimental code, likely to change soon * * @param handle the handle */ public void setMetaClassCreationHandle(MetaClassCreationHandle handle) { if (handle == null) throw new IllegalArgumentException("Cannot set MetaClassCreationHandle to null value!"); ClassInfo.clearModifiedExpandos(); handle.setDisableCustomMetaClassLookup( metaClassCreationHandle.isDisableCustomMetaClassLookup()); metaClassCreationHandle = handle; }
public MetaClassRegistryImpl(final int loadDefault, final boolean useAccessible) { this.useAccessible = useAccessible; if (loadDefault == LOAD_DEFAULT) { Map<CachedClass, List<MetaMethod>> map = new HashMap<CachedClass, List<MetaMethod>>(); // let's register the default methods registerMethods(null, true, true, map); final Class[] additionals = DefaultGroovyMethods.additionals; for (int i = 0; i != additionals.length; ++i) { createMetaMethodFromClass(map, additionals[i]); } Class[] pluginDGMs = VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods(); for (Class plugin : pluginDGMs) { registerMethods(plugin, false, true, map); } registerMethods(DefaultGroovyStaticMethods.class, false, false, map); Class[] staticPluginDGMs = VMPluginFactory.getPlugin().getPluginStaticGroovyMethods(); for (Class plugin : staticPluginDGMs) { registerMethods(plugin, false, false, map); } for (Map.Entry<CachedClass, List<MetaMethod>> e : map.entrySet()) { CachedClass cls = e.getKey(); cls.setNewMopMethods(e.getValue()); } } installMetaClassCreationHandle(); final MetaClass emcMetaClass = metaClassCreationHandle.create(ExpandoMetaClass.class, this); emcMetaClass.initialize(); ClassInfo.getClassInfo(ExpandoMetaClass.class).setStrongMetaClass(emcMetaClass); addMetaClassRegistryChangeEventListener( new MetaClassRegistryChangeEventListener() { public void updateConstantMetaClass(MetaClassRegistryChangeEvent cmcu) { synchronized (metaClassInfo) { metaClassInfo.add(cmcu.getNewMetaClass()); DefaultMetaClassInfo.getNewConstantMetaClassVersioning(); Class c = cmcu.getClassToUpdate(); DefaultMetaClassInfo.setPrimitiveMeta(c, cmcu.getNewMetaClass() == null); Field sdyn; try { sdyn = c.getDeclaredField(Verifier.STATIC_METACLASS_BOOL); sdyn.setBoolean(null, cmcu.getNewMetaClass() != null); } catch (Throwable e) { // DO NOTHING } } } }); }
public void setMetaClass(Object obj, MetaClass theMetaClass) { Class theClass = obj.getClass(); final ClassInfo info = ClassInfo.getClassInfo(theClass); MetaClass oldMC = null; info.lock(); try { oldMC = info.getPerInstanceMetaClass(obj); info.setPerInstanceMetaClass(obj, theMetaClass); } finally { info.unlock(); } fireConstantMetaClassUpdate(obj, theClass, oldMC, theMetaClass); }
/** * if oldMc is null, newMc will replace whatever meta class was used before. if oldMc is not null, * then newMc will be used only if he stored mc is the same as oldMc */ private void setMetaClass(Class theClass, MetaClass oldMc, MetaClass newMc) { final ClassInfo info = ClassInfo.getClassInfo(theClass); MetaClass mc = null; info.lock(); try { mc = info.getStrongMetaClass(); info.setStrongMetaClass(newMc); } finally { info.unlock(); } if ((oldMc == null && mc != newMc) || (oldMc != null && mc != newMc && mc != oldMc)) { fireConstantMetaClassUpdate(null, theClass, mc, newMc); } }
public MetaClass getMetaClass(Object obj) { return ClassInfo.getClassInfo(obj.getClass()).getMetaClass(obj); }
public final MetaClass getMetaClass(Class theClass) { return ClassInfo.getClassInfo(theClass).getMetaClass(); }