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
              }
            }
          }
        });
  }
Beispiel #2
0
  /**
   * This method is a default implementation for the invoke method given in InvocationHandler. Any
   * call to a method with a declaring class that is not Object, excluding toString() and default
   * methods is redirected to invokeCustom.
   *
   * <p>Methods like equals and hashcode are called on the class itself instead of the delegate
   * because they are considered fundamental methods that should not be overwritten. The toString()
   * method gets special treatment as it is deemed to be a method that you might wish to override
   * when called from Groovy. Interface default methods from Java 8 on the other hand are considered
   * being default implementations you don't normally want to change. So they are called directly
   * too
   *
   * <p>In many scenarios, it is better to overwrite the invokeCustom method where the core Object
   * related methods are filtered out.
   *
   * @param proxy the proxy
   * @param method the method
   * @param args the arguments
   * @return the result of the invocation by method or delegate
   * @throws Throwable if caused by the delegate or the method
   * @see #invokeCustom(Object, Method, Object[])
   * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
   */
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    VMPlugin plugin = VMPluginFactory.getPlugin();
    if (plugin.getVersion() >= 7 && isDefaultMethod(method)) {
      Object handle = handleCache.get(method);
      if (handle == null) {
        handle = plugin.getInvokeSpecialHandle(method, proxy);
        handleCache.put(method, handle);
      }
      return plugin.invokeHandle(handle, args);
    }

    if (!checkMethod(method)) {
      try {
        if (method.getDeclaringClass() == GroovyObject.class) {
          if ("getMetaClass".equals(method.getName())) {
            return getMetaClass(proxy);
          } else if ("setMetaClass".equals(method.getName())) {
            return setMetaClass((MetaClass) args[0]);
          }
        }
        return invokeCustom(proxy, method, args);
      } catch (GroovyRuntimeException gre) {
        throw ScriptBytecodeAdapter.unwrap(gre);
      }
    }

    try {
      return method.invoke(this, args);
    } catch (InvocationTargetException ite) {
      throw ite.getTargetException();
    }
  }
 /**
  * The complete class structure will be initialized only when really needed to avoid having too
  * many objects during compilation
  */
 private void lazyClassInit() {
   if (lazyInitDone) return;
   synchronized (lazyInitLock) {
     if (redirect != null) {
       throw new GroovyBugError(
           "lazyClassInit called on a proxy ClassNode, that must not happen."
               + "A redirect() call is missing somewhere!");
     }
     if (lazyInitDone) return;
     VMPluginFactory.getPlugin().configureClassNode(compileUnit, this);
     lazyInitDone = true;
   }
 }
Beispiel #4
0
 {
   if (VMPluginFactory.getPlugin().getVersion() >= 7) handleCache = new ConcurrentHashMap();
 }