Package net.sourceforge.javautil.groovy.dsl

Source Code of net.sourceforge.javautil.groovy.dsl.GroovyMetaClass

package net.sourceforge.javautil.groovy.dsl;

import java.util.List;

import org.codehaus.groovy.ast.ClassNode;

import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.groovy.util.MetaClassWrapper;
import groovy.lang.Binding;
import groovy.lang.GroovySystem;
import groovy.lang.MetaClass;
import groovy.lang.MetaMethod;
import groovy.lang.MetaProperty;
import groovy.lang.MissingMethodException;
import groovy.lang.MissingPropertyException;

/**
* This will wrap ALL {@link MetaClass}'s generated by the {@link GroovySystem} and intervene
* where in order to provide the added functionality according to the {@link GroovyDSLContext}.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class GroovyMetaClass extends MetaClassWrapper {
 
  protected GroovyDSLManager manager;
 
  public GroovyMetaClass(MetaClass metaClass) {
    super(metaClass);
  }

  @Override public Object invokeStaticMethod(Object object, String methodName, Object[] arguments) {
    try {
      return super.invokeStaticMethod(object, methodName, arguments);
    } catch (MissingMethodException e) {
      return this.invokeGraceletDSLMethod(object, methodName, arguments, e);
    }
  }

  @Override public Object invokeMethod(Object object, String methodName, Object[] arguments) {
    try {
      return super.invokeMethod(object, methodName, arguments);
    } catch (MissingMethodException e) {
      return this.invokeGraceletDSLMethod(object, methodName, arguments, e);
    }
  }

  @Override public Object getProperty(Object object, String property) {
    try {
      return super.getProperty(object, property);
    } catch (MissingPropertyException e) {
      return this.invokeGraceletDSLProperty(object, property, null, true);
    }
  }

  @Override public void setProperty(Object object, String property, Object newValue) {
    try {
      super.setProperty(object, property, newValue);
    } catch (MissingPropertyException e) {
      this.invokeGraceletDSLProperty(object, property, newValue, false);
    }
  }

  @Override public Object getProperty(Class sender, Object receiver, String property, boolean isCallToSuper, boolean fromInsideClass) {
    try {
      return super.getProperty(sender, receiver, property, isCallToSuper, fromInsideClass);
    } catch (MissingPropertyException e) {
      return this.invokeGraceletDSLProperty(receiver, property, null, true);
    }
  }

  @Override public void setProperty(Class sender, Object receiver, String property, Object value, boolean isCallToSuper, boolean fromInsideClass) {
    try {
      super.setProperty(sender, receiver, property, value, isCallToSuper, fromInsideClass);
    } catch (MissingPropertyException e) {
      this.invokeGraceletDSLProperty(receiver, property, value, false);
    }
  }

  public Object invokeGraceletDSLMethod(Object instance, String methodName, Object[] arguments, MissingMethodException me) {
    if (manager == null) manager = GroovyDSLContext.getManager();
    if (manager == null) throw me;
   
    GroovyDSLMethod method = null;
    MetaClass mc = this;
    while (true) {
      method = manager.findMethod(mc, instance, methodName, arguments);
      if (method != null) break;
      else if (mc.getTheClass() != Object.class) mc = GroovySystem.getMetaClassRegistry().getMetaClass(mc.getTheClass().getSuperclass());
      else break;
    }
    if (method == null) {
      try {
        Binding dsl = GroovyDSLBinding.getInstance();
        if (dsl != null) return dsl.invokeMethod(methodName, arguments); else throw me;
      } catch (MissingMethodException eee) {
        throw me;
      }
    }
    try {
      return method.invoke(this, instance, methodName, arguments);
    } catch (Exception e) {
      throw ThrowableManagerRegistry.caught(e);
    }
  }

  public Object invokeGraceletDSLProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
    try {
      return super.invokeMissingProperty(instance, propertyName, optionalValue, isGetter);
    } catch (MissingPropertyException e) {
      if (manager == null) manager = GroovyDSLContext.getManager();
      if (manager == null) throw e;

      GroovyDSLProperty property = null;
      MetaClass mc = this;
      while (true) {
        property = manager.findProperty(mc, instance, propertyName);
        if (property != null) break;
        else if (mc.getTheClass() != Object.class) mc = GroovySystem.getMetaClassRegistry().getMetaClass(mc.getTheClass().getSuperclass());
        else break;
      }
     
      if (property == null) {
        try {
          Binding dsl = GroovyDSLBinding.getInstance();
          if (dsl != null) {
            if (isGetter) return dsl.getVariable(propertyName); else dsl.setVariable(propertyName, optionalValue);
          } else throw e;
        } catch (MissingPropertyException ee) {
          throw e;
        }
      }
     
      try {
        if (isGetter) return property.get(this, instance, propertyName);
        else property.set(this, instance, propertyName, optionalValue);
        return null;
      } catch (Exception e1) {
        throw ThrowableManagerRegistry.caught(e1);
      }
    }
  }

}
TOP

Related Classes of net.sourceforge.javautil.groovy.dsl.GroovyMetaClass

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.