Package

Source Code of MixologyService

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.anno.JRubyMethod;
import org.jruby.IncludedModuleWrapper;
import org.jruby.runtime.Block;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.load.BasicLibraryService;

public class MixologyService implements BasicLibraryService {
    public boolean basicLoad(final Ruby runtime) throws IOException {
        RubyModule mixologyModule = runtime.defineModule("Mixology");
        mixologyModule.defineAnnotatedMethods(MixologyService.class);
      runtime.getObject().includeModule(mixologyModule);
        return true;
    }
   

    @JRubyMethod(name = "unmix", required = 1)
    public synchronized static IRubyObject unmix(IRubyObject recv, IRubyObject _module, Block block)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    RubyModule module = (RubyModule)_module;
        for (RubyModule klass = recv.getMetaClass(); klass != recv.getMetaClass().getRealClass(); klass = klass.getSuperClass()) {
            if (klass.getSuperClass() != null &&  klass.getSuperClass().getNonIncludedClass() == module) {
              if(module.getSuperClass() != null && module.getSuperClass() instanceof IncludedModuleWrapper)
                remove_nested_module(klass.getSuperClass(), module);
                  setSuperClass(klass, klass.getSuperClass().getSuperClass());
                  clearCache(klass, module)
            }
        }

        return recv;

    }

        @JRubyMethod(name = "mixin", required = 1)
    public synchronized static IRubyObject mixin(IRubyObject recv, IRubyObject _module, Block block)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    RubyModule module = (RubyModule)_module;
        unmix(recv, module, block);

      RubyClass klass = recv.getSingletonClass();

      int nestedModuleCount = 0;
      for (RubyModule p = module.getSuperClass(); p != null; p = p.getSuperClass())
        nestedModuleCount++;

      IncludedModuleWrapper[] nestedModules = new IncludedModuleWrapper[nestedModuleCount];

       IncludedModuleWrapper nestedModule = (IncludedModuleWrapper)module.getSuperClass();
      for(int index = 0; index < nestedModules.length; index++){
        nestedModules[index] = nestedModule;
        nestedModule =  (IncludedModuleWrapper)nestedModule.getSuperClass();
      }

      for(int index = nestedModules.length; index > 0; index--) {
          add_module(klass, nestedModules[index-1].getNonIncludedClass());
      }

        add_module(klass, module);
        clearCache(klass, klass.getSuperClass())

        return recv;
    }

    protected synchronized static void add_module(RubyClass klass, RubyModule module)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {

        klass.infectBy(module);
       
        IncludedModuleWrapper includedKlass = new IncludedModuleWrapper(klass.getRuntime(), klass.getSuperClass(), module);
       
        setSuperClass(klass, includedKlass);

        clearCache(klass, klass.getSuperClass())
    }

    protected synchronized static void remove_nested_module(RubyClass klass, RubyModule include_class)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
 
        if(! (klass.getSuperClass() instanceof IncludedModuleWrapper) ||
         ((IncludedModuleWrapper)klass.getSuperClass()).getNonIncludedClass() != ((IncludedModuleWrapper)include_class.getSuperClass()).getNonIncludedClass())
          return;
         
 
        if(include_class.getSuperClass().getSuperClass() != null && include_class.getSuperClass() instanceof IncludedModuleWrapper) {
            remove_nested_module(klass.getSuperClass(), include_class.getSuperClass());
        }
     
         setSuperClass(klass, klass.getSuperClass().getSuperClass());

    }

    protected synchronized static void setSuperClass(RubyModule klass, RubyModule superClass)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        Method method = RubyModule.class.getDeclaredMethod("setSuperClass", new Class[] {RubyClass.class} );
        method.setAccessible(true);
        Object[] superClassArg = new Object[] { superClass };
        method.invoke(klass, superClassArg);
    }

    protected static void clearCache(RubyModule klass, RubyModule module) {
      List<String> methodNames = new ArrayList<String>(module.getMethods().keySet());
      for (Iterator iter = methodNames.iterator();
        iter.hasNext();) {
        String methodName = (String) iter.next();
        klass.getRuntime().getCacheMap().remove(klass.searchMethod(methodName));
      }
    }
}
TOP

Related Classes of MixologyService

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.