Example #1
0
  @Nullable
  public InstanceFactory findInstanceFactory(@Nonnull Type mockedType) {
    InstanceFactory instanceFactory = mockedTypesAndInstances.get(mockedType);

    if (instanceFactory != null) {
      return instanceFactory;
    }

    Class<?> mockedClass = getClassType(mockedType);
    //noinspection ReuseOfLocalVariable
    instanceFactory = mockedTypesAndInstances.get(mockedClass);

    if (instanceFactory != null) {
      return instanceFactory;
    }

    boolean abstractType = mockedClass.isInterface() || isAbstract(mockedClass.getModifiers());

    for (Entry<Type, InstanceFactory> entry : mockedTypesAndInstances.entrySet()) {
      Type registeredMockedType = entry.getKey();
      Class<?> registeredMockedClass = getClassType(registeredMockedType);

      if (abstractType) {
        registeredMockedClass = getMockedClassOrInterfaceType(registeredMockedClass);
      }

      if (mockedClass.isAssignableFrom(registeredMockedClass)) {
        instanceFactory = entry.getValue();
        break;
      }
    }

    return instanceFactory;
  }
  private Collection createList() throws IOException {
    Collection list = null;

    if (_type == null) list = new ArrayList();
    else if (!_type.isInterface()) {
      try {
        list = (Collection) _type.newInstance();
      } catch (Exception e) {
      }
    }

    if (list != null) {
    } else if (SortedSet.class.isAssignableFrom(_type)) list = new TreeSet();
    else if (Set.class.isAssignableFrom(_type)) list = new HashSet();
    else if (List.class.isAssignableFrom(_type)) list = new ArrayList();
    else if (Collection.class.isAssignableFrom(_type)) list = new ArrayList();
    else {
      try {
        list = (Collection) _type.newInstance();
      } catch (Exception e) {
        throw new IOExceptionWrapper(e);
      }
    }

    return list;
  }
  /**
   * Sets up the mocks defined in the given mock class.
   *
   * <p>If the type {@linkplain MockClass#realClass referred to} by the mock class is actually an
   * interface, then a {@linkplain #newEmptyProxy(ClassLoader, Class) new empty proxy} is created.
   *
   * @param mockClassOrInstance the mock class itself (given by its {@code Class} literal), or an
   *     instance of the mock class
   * @return the new proxy instance created for the mocked interface, or {@code null} otherwise
   * @throws IllegalArgumentException if a given mock class fails to specify the corresponding real
   *     class using the {@code @MockClass(realClass = ...)} annotation; or if a mock class defines
   *     a mock method for which no corresponding real method or constructor exists in the real
   *     class; or if the real method matching a mock method is {@code abstract}
   * @see #setUpMock(Class, Object)
   * @see #setUpMocks(Object...)
   * @see <a
   *     href="http://code.google.com/p/jmockit/source/browse/trunk/main/test/mockit/MockAnnotationsTest.java#696">
   *     Example</a>
   */
  public static <T> T setUpMock(Object mockClassOrInstance) {
    Class<?> mockClass;
    Object mock;

    if (mockClassOrInstance instanceof Class<?>) {
      mockClass = (Class<?>) mockClassOrInstance;
      mock = null;
    } else {
      mockClass = mockClassOrInstance.getClass();
      mock = mockClassOrInstance;
    }

    MockClassSetup setup = new MockClassSetup(mock, mockClass);
    Class<?> realClass = setup.getRealClass();
    T proxy = null;

    if (realClass.isInterface()) {
      //noinspection unchecked
      proxy = (T) newEmptyProxy(mockClass.getClassLoader(), realClass);
      setup.setRealClass(proxy.getClass());
    }

    setup.redefineMethods();

    return proxy;
  }
Example #4
0
  /**
   * check whether a class should not be considered for transformation
   *
   * @param clazz the class to check
   * @return true if clazz should not be considered for transformation otherwise false
   */
  protected boolean isSkipClass(Class<?> clazz) {
    if (!inst.isModifiableClass(clazz)) {
      return true;
    }

    // we can safely skip array classes, interfaces and primitive classes

    if (clazz.isArray()) {
      return true;
    }

    if (clazz.isInterface()) {
      return true;
    }

    if (clazz.isPrimitive()) {
      return true;
    }

    String name = clazz.getName();

    if (isBytemanClass(name) || !isTransformable(name)) {
      return true;
    }

    return false;
  }
 @Override
 public void visit(
     final int version,
     final int access,
     final String name,
     final String signature,
     final String superName,
     final String[] interfaces) {
   Set<String> interfacesSet = new LinkedHashSet<String>();
   if (interfaces != null) Collections.addAll(interfacesSet, interfaces);
   for (Class extraInterface : classList) {
     if (extraInterface.isInterface())
       interfacesSet.add(BytecodeHelper.getClassInternalName(extraInterface));
   }
   final boolean addGroovyObjectSupport = !GroovyObject.class.isAssignableFrom(superClass);
   if (addGroovyObjectSupport) interfacesSet.add("groovy/lang/GroovyObject");
   super.visit(
       V1_5,
       ACC_PUBLIC,
       proxyName,
       signature,
       BytecodeHelper.getClassInternalName(superClass),
       interfacesSet.toArray(new String[interfacesSet.size()]));
   addDelegateFields();
   if (addGroovyObjectSupport) {
     createGroovyObjectSupport();
   }
   for (Class clazz : classList) {
     visitClass(clazz);
   }
 }
 public void addMatchingSetters() {
   check(implInterface || !dataTypeIn.isInterface());
   Set<String> usedFields = new HashSet<>();
   if (constructorParams != null) {
     usedFields.addAll(constructorParams);
   }
   if (factoryParams != null) {
     usedFields.addAll(factoryParams);
   }
   for (List<String> list : setters.values()) {
     usedFields.addAll(list);
   }
   for (String fieldName : fields.keySet()) {
     FieldGen fieldGen = fields.get(fieldName);
     Method getter = fieldGen.method;
     if (getter == null) continue;
     if (usedFields.contains(fieldName)) continue;
     String setterName =
         "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
     try {
       Method setter;
       if (implInterface) setter = dataTypeOut.getMethod(setterName, getter.getReturnType());
       else setter = dataTypeIn.getMethod(setterName, getter.getReturnType());
       if (!isPrivate(setter.getModifiers())) {
         addSetter(setter, asList(fieldName));
       }
     } catch (NoSuchMethodException e) {
       throw new RuntimeException(e);
     }
   }
 }
  /**
   * Create a default object of the given type. Prefers constructors with as few arguments as
   * possible. Creates an empty proxy for interfaces.
   *
   * @param type type to instantiate
   * @return default instance
   * @throws Exception if the default instance could not be created
   */
  private static Object instantiateType(Class<?> type) throws Exception {
    if (type.isPrimitive()) return Defaults.defaultValue(type);
    else if (type == Void.class) return null;
    else if (type.isArray()) return Array.newInstance(type, 0);
    else if (type.isInterface())
      return Proxy.newProxyInstance(
          type.getClassLoader(),
          new Class[] {type},
          new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              return null;
            }
          });

    // Take a constructor with as few params as possible
    Constructor constructor = type.getDeclaredConstructors()[0];
    for (Constructor<?> c : type.getDeclaredConstructors()) {
      if (c.getParameterTypes().length < constructor.getParameterTypes().length) constructor = c;
    }

    Object[] params = new Object[constructor.getParameterTypes().length];
    for (int i = 0; i < constructor.getParameterTypes().length; i++) {
      params[i] = instantiateType(constructor.getParameterTypes()[i]);
    }
    return constructor.newInstance(params);
  }
 public void addSetter(Method method, List<String> fields) {
   check(implInterface || !dataTypeIn.isInterface());
   checkNotNull(method);
   checkNotNull(fields);
   check(!isPrivate(method.getModifiers()), "Setter cannot be private: %s", method);
   check(method.getGenericParameterTypes().length == fields.size());
   check(!setters.containsKey(method));
   setters.put(method, fields);
 }
 public SerializerGenClass(Class<?> type, Class<?> typeImpl) {
   checkNotNull(type);
   checkNotNull(typeImpl);
   check(type.isInterface());
   check(type.isAssignableFrom(typeImpl));
   this.dataTypeIn = type;
   this.dataTypeOut = typeImpl;
   this.implInterface = true;
 }
 public static <T> List<T> createProxy(
     List<T> items, Class<T> type, Map<String, ProxyFilter> prop2Filter) {
   if (type == null || items == null) {
     throw new IllegalArgumentException("parameters are null");
   }
   if (!type.isInterface()) {
     throw new IllegalArgumentException("proxy type is not a interface");
   }
   return new ProxyListHandler<T>(items, type, prop2Filter);
 }
 public void setConstructor(Constructor<?> constructor, List<String> fields) {
   check(implInterface || !dataTypeIn.isInterface());
   checkNotNull(constructor);
   checkNotNull(fields);
   check(this.constructor == null, "Constructor is already set: %s", this.constructor);
   check(!isPrivate(constructor.getModifiers()), "Constructor cannot be private: %s", constructor);
   check(constructor.getGenericParameterTypes().length == fields.size());
   this.constructor = constructor;
   this.constructorParams = fields;
 }
Example #12
0
  public static void premain(String args, Instrumentation inst) throws Exception {
    try {
      String[] agentArgs;
      if (args == null) agentArgs = new String[] {""};
      else agentArgs = args.split(",");
      if (!agentArgs[0].equals("instrumenting")) jarFileName = agentArgs[0];
      BaseClassTransformer rct = null;
      rct = new BaseClassTransformer();
      if (agentArgs[0].equals("instrumenting")) {
        initVMClasses = new HashSet<String>();
        for (Class<?> c : inst.getAllLoadedClasses()) {
          ((Set<String>) initVMClasses).add(c.getName());
        }
      }
      if (!agentArgs[0].equals("instrumenting")) {

        inst.addTransformer(rct);
        Tracer.setLocals(new CounterThreadLocal());
        Tracer.overrideAll(true);
        for (Class<?> c : inst.getAllLoadedClasses()) {
          try {
            if (c.isInterface()) continue;
            if (c.isArray()) continue;
            byte[] bytes = rct.getBytes(c.getName());
            if (bytes == null) {
              continue;
            }
            inst.redefineClasses(new ClassDefinition[] {new ClassDefinition(c, bytes)});
          } catch (Throwable e) {
            synchronized (System.err) {
              System.err.println("" + c + " failed...");
              e.printStackTrace();
            }
          }
        }
        Runtime.getRuntime()
            .addShutdownHook(
                new Thread() {
                  public void run() {
                    Tracer.mark();
                    try {
                      PrintStream ps = new PrintStream("bailout.txt");
                      ps.println("Bailouts: " + Tracer.getBailoutCount());
                      ps.close();
                    } catch (Exception e) {
                    }
                    Tracer.unmark();
                  }
                });
        if ("true".equals(System.getProperty("bci.observerOn"))) Tracer.overrideAll(false);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Example #13
0
  static JavaMembers lookupClass(
      Scriptable scope, Class<?> dynamicType, Class<?> staticType, boolean includeProtected) {
    JavaMembers members;
    scope = ScriptableObject.getTopLevelScope(scope);
    ClassCache cache = ClassCache.get(scope);
    Map<Class<?>, JavaMembers> ct = cache.getClassCacheMap();

    Class<?> cl = dynamicType;
    for (; ; ) {
      members = ct.get(cl);
      if (members != null) {
        return members;
      }
      try {
        members = new JavaMembers(scope, cl, includeProtected);
        break;
      } catch (SecurityException e) {
        // Reflection may fail for objects that are in a restricted
        // access package (e.g. sun.*).  If we get a security
        // exception, try again with the static type if it is interface.
        // Otherwise, try superclass
        if (staticType != null && staticType.isInterface()) {
          cl = staticType;
          staticType = null; // try staticType only once
        } else {
          Class<?> parent = cl.getSuperclass();
          if (parent == null) {
            if (cl.isInterface()) {
              // last resort after failed staticType interface
              parent = ScriptRuntime.ObjectClass;
            } else {
              throw e;
            }
          }
          cl = parent;
        }
      }
    }

    if (cache.isCachingEnabled()) ct.put(cl, members);
    return members;
  }
Example #14
0
 private T newContextObject() {
   try {
     if (type.isInterface()) {
       return (T) Classes.newDynamicProxy(type);
     } else {
       return (T) type.newInstance();
     }
   } catch (Exception anExc) {
     throw new XmlReadingException(anExc);
   }
 }
 public void setFactory(Method methodFactory, List<String> fields) {
   check(implInterface || !dataTypeIn.isInterface());
   checkNotNull(methodFactory);
   checkNotNull(fields);
   check(this.factory == null, "Factory is already set: %s", this.factory);
   check(!isPrivate(methodFactory.getModifiers()), "Factory cannot be private: %s", methodFactory);
   check(isStatic(methodFactory.getModifiers()), "Factory must be static: %s", methodFactory);
   check(methodFactory.getGenericParameterTypes().length == fields.size());
   this.factory = methodFactory;
   this.factoryParams = fields;
 }
Example #16
0
 public static PropertyDescriptor[] getPropertyDescriptors(Class<?> objectClass) {
   // If the class is an interface, use custom method to get all prop descriptors in the
   // inheritance hierarchy.
   // PropertyUtils.getPropertyDescriptors() does not work correctly for interface inheritance. It
   // finds props in the
   // actual interface ok, but does not find props in the inheritance hierarchy.
   if (objectClass.isInterface()) {
     return getInterfacePropertyDescriptors(objectClass);
   } else {
     return BeanUtils.getPropertyDescriptors(objectClass);
   }
 }
Example #17
0
  /**
   * Create entity factory for entities with a predefined component composition.
   *
   * @param factory type to create.
   * @param <T> type to create. Should implement {@link EntityFactory}.
   * @return Implementation of EntityFactory.
   * @see EntityFactory for instructions about configuration.
   */
  @SuppressWarnings("unchecked")
  public <T extends EntityFactory> T createFactory(Class<?> factory) {
    if (!factory.isInterface())
      throw new MundaneWireException("Expected interface for type: " + factory);

    String impl = factory.getName() + "Impl";
    try {
      Class<?> implClass = ClassReflection.forName(impl);
      Constructor constructor = ClassReflection.getConstructor(implClass, World.class);
      return (T) constructor.newInstance(this);
    } catch (ReflectionException e) {
      throw new RuntimeException(e);
    }
  }
 public void addField(Field field, SerializerGen serializer, int added, int removed) {
   check(implInterface || !dataTypeIn.isInterface());
   check(isPublic(field.getModifiers()));
   String fieldName = field.getName();
   check(!fields.containsKey(fieldName), "Duplicate field '%s'", field);
   FieldGen fieldGen = new FieldGen();
   fieldGen.field = field;
   fieldGen.serializer = serializer;
   fieldGen.versionAdded = added;
   fieldGen.versionDeleted = removed;
   fieldGen.offset = lastOffset;
   lastOffset += getType(field.getType()).getSize();
   fields.put(fieldName, fieldGen);
 }
Example #19
0
  TestedField(
      @Nonnull InjectionState injectionState, @Nonnull Field field, @Nonnull Tested metadata) {
    this.injectionState = injectionState;
    testedField = field;
    this.metadata = metadata;
    fullInjection = metadata.fullyInitialized() ? new FullInjection(injectionState) : null;

    Class<?> fieldType = field.getType();

    if (fieldType.isInterface()) {
      testedObjectCreation = null;
    } else {
      testedObjectCreation = new TestedObjectCreation(injectionState, fullInjection, field);
      injectionState.lifecycleMethods.findLifecycleMethods(fieldType);
    }
  }
Example #20
0
 private Mod loadCustomMod(URLClassLoader loader, String className)
     throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
   Class<?> cl = null;
   try {
     cl = loader.loadClass(className);
   } catch (NoClassDefFoundError e) {
     Logger.log(Logger.LOG_MOD, "WARNING: skipping %s: %s", className, e.toString());
   }
   if (cl != null && !cl.isInterface() && Mod.class.isAssignableFrom(cl)) {
     int flags = cl.getModifiers();
     if (!Modifier.isAbstract(flags) && Modifier.isPublic(flags)) {
       return newModInstance(cl.asSubclass(Mod.class));
     }
   }
   return null;
 }
Example #21
0
  static Object js_createAdpter(Context cx, Scriptable scope, Object[] args) {
    int N = args.length;
    if (N == 0) {
      throw ScriptRuntime.typeError0("msg.adapter.zero.args");
    }

    Class superClass = null;
    Class[] intfs = new Class[N - 1];
    int interfaceCount = 0;
    for (int i = 0; i != N - 1; ++i) {
      Object arg = args[i];
      if (!(arg instanceof NativeJavaClass)) {
        throw ScriptRuntime.typeError2(
            "msg.not.java.class.arg", String.valueOf(i), ScriptRuntime.toString(arg));
      }
      Class c = ((NativeJavaClass) arg).getClassObject();
      if (!c.isInterface()) {
        if (superClass != null) {
          throw ScriptRuntime.typeError2("msg.only.one.super", superClass.getName(), c.getName());
        }
        superClass = c;
      } else {
        intfs[interfaceCount++] = c;
      }
    }

    if (superClass == null) superClass = ScriptRuntime.ObjectClass;

    Class[] interfaces = new Class[interfaceCount];
    System.arraycopy(intfs, 0, interfaces, 0, interfaceCount);
    Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]);

    Class adapterClass = getAdapterClass(scope, superClass, interfaces, obj);

    Class[] ctorParms = {ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass};
    Object[] ctorArgs = {cx.getFactory(), obj};
    try {
      Object adapter = adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
      return getAdapterSelf(adapterClass, adapter);
    } catch (Exception ex) {
      throw Context.throwAsScriptRuntimeEx(ex);
    }
  }
  /**
   * @return all of the classes x in the given directory (recursively) such that
   *     clazz.isAssignableFrom(x).
   */
  private List<Class> getAssignableClasses(File path, Class<TetradSerializable> clazz) {
    if (!path.isDirectory()) {
      throw new IllegalArgumentException("Not a directory: " + path);
    }

    @SuppressWarnings("Convert2Diamond")
    List<Class> classes = new LinkedList<>();
    File[] files = path.listFiles();

    if (files == null) {
      throw new NullPointerException();
    }

    for (File file : files) {
      if (file.isDirectory()) {
        classes.addAll(getAssignableClasses(file, clazz));
      } else {
        String packagePath = file.getPath();
        packagePath = packagePath.replace('\\', '.');
        packagePath = packagePath.replace('/', '.');
        packagePath = packagePath.substring(packagePath.indexOf("edu.cmu"), packagePath.length());
        int index = packagePath.indexOf(".class");

        if (index == -1) {
          continue;
        }

        packagePath = packagePath.substring(0, index);

        try {
          Class _clazz = getClass().getClassLoader().loadClass(packagePath);

          if (clazz.isAssignableFrom(_clazz) && !_clazz.isInterface()) {
            classes.add(_clazz);
          }
        } catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
      }
    }

    return classes;
  }
Example #23
0
  /**
   * @param classloader
   * @param superClass
   * @param classes
   * @param className
   */
  @SuppressWarnings("unchecked")
  private static void checkAndAddClass(
      ClassLoader classloader, Class superClass, LinkedList<Class> classes, String className) {
    if (className.indexOf('$') > -1) return;

    try {
      Class subClass = classloader.loadClass(className);

      if (subClass != null
          && !superClass.equals(subClass)
          && superClass.isAssignableFrom(subClass)
          && !subClass.isInterface()
          && !classes.contains(subClass)) {
        classes.add(subClass);
      }
    } catch (Throwable th) {
      logger.log(Level.WARNING, "checkAndAddClass error", th);
    }
  }
Example #24
0
  /**
   * Search the Interfaces implemented by this Class for in-bound Facets
   *
   * @param objectClass
   * @return Set of Facet classes for the class
   */
  public static Set<Class<?>> getFacetClasses(Class<?> objectClass) {
    Set<Class<?>> facetClasses = new HashSet<Class<?>>();

    // TODO check for @Facet annotated Fields with IN direction

    if (objectClass.isInterface()) {
      addIfFacet(objectClass, facetClasses);
    } else {
      while (Facet.class.isAssignableFrom(objectClass)) {
        Class<?>[] interfaceClasses = objectClass.getInterfaces();

        for (int index = 0; index < interfaceClasses.length; ++index) {
          addIfFacet(interfaceClasses[index], facetClasses);
        }

        objectClass = objectClass.getSuperclass();
      }
    }

    return facetClasses;
  }
Example #25
0
  public Type navigateParameterized(String name, Type[] params) throws OclTypeException {
    Type ret = Basic.navigateAnyParameterized(name, params);
    if (ret != null) return ret;

    Method foundmethod = null;

    // this is very similar to tudresden.ocl.lib.OclAnyImpl.findMethod
    // if you find a bug here, its probably there as well.

    // suprisingly one has not to go after interfaces since methods
    // inherited from interfaces are automatically included into the
    // implementing class. This does not happen for methods inherited
    // from the superclass, so we have to ascend to all superclasses.

    // unfortunately the above is only true for classes, getSuperclass invoked
    // on an interface returns null, regardless of the interfaces extended by the
    // interface. Therefore, we need to check out getInterfaces() if iclass is
    // an interface
    HashSet hsVisited = new HashSet();
    LinkedList llToVisit = new LinkedList();
    if (c.isInterface()) {
      // as we're dealing with actual instances, it can be assumed that Object is
      // a superclass
      llToVisit.add(java.lang.Object.class);
    }

    classloop:
    for (Class iclass = c; iclass != null; ) // iclass=iclass.getSuperclass())
    {
      Method[] methods = iclass.getDeclaredMethods();
      methodloop:
      for (int i = 0; i < methods.length; i++) {
        if (!name.equals(methods[i].getName())) continue methodloop;
        Class[] methodparams = methods[i].getParameterTypes();
        if (params.length != methodparams.length) continue methodloop;

        System.err.print("Checking method " + name + " (");
        for (int j = 0; j < methodparams.length; j++) {
          if (j != 0) {
            System.err.print(", ");
          }

          System.err.print(methodparams[j]);
        }
        System.err.println(")");

        for (int j = 0; j < params.length; j++)
          if (!params[j].conformsTo(getTypeForClass(methodparams[j]))) {
            System.err.println("No conformance for paramter # " + j);
            continue methodloop;
          }
        if (foundmethod == null) foundmethod = methods[i];
        else throw new OclTypeException("ambigious method " + name + " of " + c + ") queried.");
        break classloop;
      }

      // determine classes to be visited
      if (iclass.isInterface()) {
        Class[] ca = iclass.getInterfaces();
        for (int i = 0; i < ca.length; i++) {
          if (!hsVisited.contains(ca[i])) {
            llToVisit.add(ca[i]);
          }
        }
      } else {
        if (!hsVisited.contains(iclass.getSuperclass())) {
          llToVisit.add(iclass.getSuperclass());
        }
      }

      // mark current class visited
      hsVisited.add(iclass);

      // go to next class
      if (!llToVisit.isEmpty()) {
        iclass = (Class) llToVisit.remove(0);
      } else {
        iclass = null;
      }
    }

    if (foundmethod == null) {
      StringBuffer sb = new StringBuffer();
      sb.append(c.toString() + " has no method " + name + " with parameters (");
      for (int i = 0; i < params.length; i++) {
        if (i != 0) sb.append(", ");
        sb.append(params[i] + "/" + params[i]);
      }
      sb.append(")");
      throw new OclTypeException(sb.toString());
    }

    return getTypeForClass(foundmethod.getReturnType());
  }
  /**
   * Process and loop until told to stop. A callback_done will stop the loop and will return a
   * result. Otherwise null is returned.
   */
  public Object run() throws CommandException {
    Object result = null;
    boolean shutdown = false;
    boolean closeWhenDone = true;
    Commands.ValueObject valueObject =
        new Commands.ValueObject(); // Working value object so not continually recreated.
    InvokableValueSender valueSender =
        new InvokableValueSender(); // Working valuesender so not continually recreated.
    try {
      boolean doLoop = true;

      /**
       * Note: In the cases below you will see a lot of finally clauses that null variables out.
       * This is because this is a long running loop, and variables declared within blocks are not
       * garbage collected until the method is terminated, so these variables once set would never
       * be GC'd. The nulling at the end of the case makes sure that any of those objects set are
       * now available for garbage collection when necessary.
       */
      while (doLoop && isConnected()) {
        byte cmd = 0;
        try {
          if (LINUX_1_3) socket.setSoTimeout(1000); // Linux 1.3 bug, see comment on LINUX_1_3
          cmd = in.readByte();
          if (LINUX_1_3 && isConnected())
            socket.setSoTimeout(0); // Linux 1.3 bug, see comment on LINUX_1_3
        } catch (InterruptedIOException e) {
          continue; // Timeout, try again
        }
        switch (cmd) {
          case Commands.QUIT_CONNECTION:
            doLoop = false;
            break; // Close this connection

          case Commands.TERMINATE_SERVER:
            doLoop = false;
            shutdown = true; // Shutdown everything
            break;

          case Commands.GET_CLASS:
            String className = in.readUTF();
            Class aClass = null;
            Class superClass = null;
            String superClassName = null;
            boolean added = false;
            try {
              aClass =
                  Class.forName(
                      className); // Turns out using JNI format for array type will work fine.

              added = server.getIdentityID(aClass, valueObject);
              boolean isInterface = aClass.isInterface();
              boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
              superClass = aClass.getSuperclass();
              superClassName = (superClass != null) ? superClass.getName() : ""; // $NON-NLS-1$
              out.writeByte(Commands.GET_CLASS_RETURN);
              out.writeInt(valueObject.objectID);
              out.writeBoolean(isInterface);
              out.writeBoolean(isAbstract);
              out.writeUTF(superClassName);
              out.flush();
            } catch (ClassNotFoundException e) {
              valueObject.set();
              Commands.sendErrorCommand(out, Commands.GET_CLASS_NOT_FOUND, valueObject);
            } catch (ExceptionInInitializerError e) {
              sendException(e.getException(), valueObject, out);
            } catch (LinkageError e) {
              sendException(e, valueObject, out);
            } catch (Throwable e) {
              // Something bad, did we add a class? If we did remove it from the table.
              if (added) server.removeObject(server.getObject(valueObject.objectID));
              throw e;
            } finally {
              // clear out for GC to work.
              className = null;
              aClass = null;
              superClass = null;
              superClassName = null;
              valueObject.set();
            }
            break;

          case Commands.GET_CLASS_FROM_ID:
            int classID = in.readInt();
            try {
              aClass = (Class) server.getObject(classID);
              boolean isInterface = aClass.isInterface();
              boolean isAbstract = java.lang.reflect.Modifier.isAbstract(aClass.getModifiers());
              superClass = aClass.getSuperclass();
              superClassName = (superClass != null) ? superClass.getName() : ""; // $NON-NLS-1$
              out.writeByte(Commands.GET_CLASS_ID_RETURN);
              out.writeUTF(aClass.getName());
              out.writeBoolean(isInterface);
              out.writeBoolean(isAbstract);
              out.writeUTF(superClassName);
              out.flush();
            } catch (ClassCastException e) {
              valueObject.set();
              Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
            } finally {
              // clear out for GC to work.
              aClass = null;
              superClass = null;
              superClassName = null;
              valueObject.set();
            }
            break;

          case Commands.GET_OBJECT_DATA:
            int objectID = in.readInt();
            Object anObject = null;
            try {
              anObject = server.getObject(objectID);
              valueObject.setObjectID(objectID, server.getIdentityID(anObject.getClass()));
              Commands.writeValue(out, valueObject, true);
            } catch (ClassCastException e) {
              valueObject.set();
              Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
            } finally {
              anObject = null; // Clear out for GC to work
              valueObject.set();
            }
            break;

          case Commands.RELEASE_OBJECT:
            int id = in.readInt();
            server.removeObject(server.getObject(id));
            break;

          case Commands.NEW_INIT_STRING:
            classID = in.readInt(); // ID Of class to do new upon.
            String initString = in.readUTF(); // The init string.
            Object newValue = null;
            Class theClass = null;
            try {
              theClass = (Class) server.getObject(classID);
              if (theClass == null) {
                // The class wasn't found. So imply ClassNotFound exception.
                throw new ClassNotFoundException();
              }

              InitializationStringParser parser = null;
              try {
                parser = InitializationStringParser.createParser(initString);
                newValue = parser.evaluate();
                boolean primitive = parser.isPrimitive();
                // If expected class is Void.TYPE, that means don't test the type of the result
                // to verify if correct type, just return what it really is.
                if (theClass != Void.TYPE && primitive != theClass.isPrimitive()) {
                  valueObject.set();
                  Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
                  continue; // Goto next command.
                }
                if (primitive) {
                  try {
                    // Need to do special tests for compatibility and assignment.
                    sendObject(
                        newValue,
                        classID != Commands.VOID_TYPE
                            ? classID
                            : server.getIdentityID(parser.getExpectedType()),
                        valueObject,
                        out,
                        true); // This will make sure it goes out as the correct primitive type
                  } catch (ClassCastException e) {
                    // The returned type is not of the correct type for what is expected.
                    valueObject.set();
                    Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
                    continue; // Goto next command
                  }
                } else {
                  if (newValue != null) {
                    // Test to see if they are compatible. (Null can be assigned to any object,
                    // so that is why it was tested out above).
                    // If expected class is Void.TYPE, that means don't test the type of the result
                    // to verify if correct type, just return what it really is.
                    if (theClass != Void.TYPE && !theClass.isInstance(newValue)) {
                      // The returned type is not of the correct type for what is expected.
                      valueObject.set();
                      Commands.sendErrorCommand(out, Commands.CLASS_CAST_EXCEPTION, valueObject);
                      continue; // Goto next command
                    }
                  }
                  sendObject(
                      newValue, NOT_A_PRIMITIVE, valueObject, out, true); // Send out as an object.
                }
              } catch (InitializationStringEvaluationException e) {
                if (e instanceof EvaluationException) {
                  // Want to return the real exception.
                  sendException(e.getOriginalException(), valueObject, out);
                } else {
                  // Couldn't be evaluated, return an error for this.
                  setExceptionIntoValue(e.getOriginalException(), valueObject);
                  Commands.sendErrorCommand(out, Commands.CANNOT_EVALUATE_STRING, valueObject);
                }
              } finally {
                parser = null; // Clear out for GC to work
              }
            } catch (Throwable e) {
              sendException(e, valueObject, out);
            } finally {
              // Clear out for GC to work
              initString = null;
              theClass = null;
              newValue = null;
              valueObject.set();
            }
            break;

          case Commands.INVOKE:
            Object target = null;
            Object[] parms = null;
            Class returnType = null;
            java.lang.reflect.Method aMethod = null;
            try {
              int methodID = in.readInt(); // ID of method to invoke
              aMethod = (java.lang.reflect.Method) server.getObject(methodID); // Method to invoke
              Commands.readValue(in, valueObject);
              target = getInvokableObject(valueObject);
              Commands.readValue(in, valueObject);
              if (valueObject.type == Commands.ARRAY_IDS) {
                // It is an array containing IDs, as it normally would be.
                valueSender.initialize(valueObject);
                Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                parms = (Object[]) valueSender.getArray();
              } else {
                // It is all objects or null, so it should be an Object[] or null. If not, then this
                // is an error.
                parms = (Object[]) valueObject.anObject;
              }

              if (!aMethod.isAccessible())
                aMethod.setAccessible(
                    true); // We will allow all to occur. Let access control be handled by IDE and
                           // compiler.
              newValue = aMethod.invoke(target, parms);
              returnType = aMethod.getReturnType();
              if (returnType.isPrimitive()) {
                int returnTypeID = server.getIdentityID(returnType);
                // Need to tell sendObject the correct primitive type.
                sendObject(newValue, returnTypeID, valueObject, out, true);

              } else {
                sendObject(
                    newValue,
                    NOT_A_PRIMITIVE,
                    valueObject,
                    out,
                    true); // Just send the object back. sendObject knows how to iterpret the type
              }
            } catch (CommandException e) {
              throw e; // Throw it again. These we don't want to come up as an exception proxy.
                       // These should end the thread.
            } catch (java.lang.reflect.InvocationTargetException e) {
              // This is a wrappered exception. Return the wrappered one so it looks like
              // it was the real one. (Sometimes the method being invoked is on a
              // java.lang.reflect.Constructor.newInstance,
              // which in turn is an InvocationTargetException, so we will go until we don't have an
              // InvocationTargetException.
              Throwable t = e;
              do {
                t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
              } while (t instanceof java.lang.reflect.InvocationTargetException);
              sendException(t, valueObject, out);
            } catch (Throwable e) {
              sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
            } finally {
              // Clear out for GC to work
              valueObject.set();
              parms = null;
              target = null;
              aMethod = null;
              returnType = null;
              newValue = null;
              valueSender.clear();
            }
            break;

          case Commands.INVOKE_WITH_METHOD_PASSED:
            aClass = null;
            String methodName = null;
            Class[] parmTypes = null;
            target = null;
            parms = null;
            returnType = null;
            aMethod = null;

            try {
              Commands.readValue(in, valueObject);
              aClass = (Class) getInvokableObject(valueObject); // The class that has the method.
              methodName = in.readUTF();
              Commands.readValue(in, valueObject);
              if (valueObject.type == Commands.ARRAY_IDS) {
                // It is an array containing IDs, as it normally would be.
                valueSender.initialize(valueObject);
                Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                parmTypes = (Class[]) valueSender.getArray();
              } else {
                // It null, so it should be an null. If not, then this is an error.
                parmTypes = null;
              }
              aMethod = aClass.getMethod(methodName, parmTypes);

              // Now we get the info for the invocation of the method and execute it.
              Commands.readValue(in, valueObject);
              target = getInvokableObject(valueObject);
              Commands.readValue(in, valueObject);
              if (valueObject.type == Commands.ARRAY_IDS) {
                // It is an array containing IDs, as it normally would be.
                valueSender.initialize(valueObject);
                Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                parms = (Object[]) valueSender.getArray();
              } else {
                // It is all objects or null, so it should be an Object[] or null. If not, then this
                // is an error.
                parms = (Object[]) valueObject.anObject;
              }

              if (!aMethod.isAccessible())
                aMethod.setAccessible(
                    true); // We will allow all to occur. Let access control be handled by IDE and
                           // compiler.
              newValue = aMethod.invoke(target, parms);
              returnType = aMethod.getReturnType();
              if (returnType.isPrimitive()) {
                int returnTypeID = server.getIdentityID(returnType);
                // Need to tell sendObject the correct primitive type.
                sendObject(newValue, returnTypeID, valueObject, out, true);

              } else {
                sendObject(
                    newValue,
                    NOT_A_PRIMITIVE,
                    valueObject,
                    out,
                    true); // Just send the object back. sendObject knows how to iterpret the type
              }
            } catch (CommandException e) {
              throw e; // Throw it again. These we don't want to come up as an exception proxy.
                       // These should end the thread.
            } catch (java.lang.reflect.InvocationTargetException e) {
              // This is a wrappered exception. Return the wrappered one so it looks like
              // it was the real one. (Sometimes the method being invoked is on a
              // java.lang.reflect.Constructor.newInstance,
              // which in turn is an InvocationTargetException, so we will go until we don't have an
              // InvocationTargetException.
              Throwable t = e;
              do {
                t = ((java.lang.reflect.InvocationTargetException) t).getTargetException();
              } while (t instanceof java.lang.reflect.InvocationTargetException);
              sendException(t, valueObject, out);

            } catch (Throwable e) {
              sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
            } finally {
              aClass = null;
              methodName = null;
              parmTypes = null;
              // Clear out for GC to work
              valueObject.set();
              parms = null;
              target = null;
              aMethod = null;
              returnType = null;
              newValue = null;
              valueSender.clear();
            }
            break;

          case Commands.GET_ARRAY_CONTENTS:
            try {
              target = server.getObject(in.readInt()); // Array to get the ids for.
              valueObject.setArrayIDS(
                  new ArrayContentsRetriever(target),
                  Array.getLength(target),
                  Commands.OBJECT_CLASS);
              Commands.writeValue(out, valueObject, true); // Write it back as a value command.
            } catch (CommandException e) {
              throw e; // Throw it again. These we don't want to come up as an exception proxy.
                       // These should end the thread.
            } catch (Throwable e) {
              sendException(e, valueObject, out); // Turn it into a exception proxy on the client.
            } finally {
              target = null;
              valueObject.set();
            }
            break;

          case Commands.CALLBACK_DONE:
            try {
              if (connectionThread != null) {
                valueObject.set();
                Commands.sendErrorCommand(out, Commands.UNKNOWN_COMMAND_SENT, valueObject);
              } else {
                try {
                  Commands.readBackValue(in, valueObject, Commands.NO_TYPE_CHECK);
                  if (valueObject.type == Commands.ARRAY_IDS) {
                    // It is an array containing IDs, as it normally would be.
                    valueSender.initialize(valueObject);
                    Commands.readArray(in, valueObject.anInt, valueSender, valueObject, false);
                    result = valueSender.getArray();
                  } else {
                    result = getInvokableObject(valueObject);
                  }
                  doLoop = false; // We need to terminate and return result
                  closeWhenDone = false; // Don't close, we will continue.
                } catch (CommandErrorException e) {
                  // There was an command error on the other side. This means
                  // connection still good, but don't continue the callback processing.
                  doLoop = false; // We need to terminate and return result
                  closeWhenDone = false; // Don't close, we will continue.
                  throw e; // Let it go on out.
                }
              }
            } finally {
              valueObject.set();
              valueSender.clear();
            }
            break;

          case Commands.ERROR:
            try {
              // Got an error command. Don't know what to do but read the
              // value and simply print it out.
              Commands.readValue(in, valueObject);
              result = getInvokableObject(valueObject);
              System.out.println("Error sent to server: Result=" + result); // $NON-NLS-1$
            } finally {
              valueObject.set();
            }
            break;

          case Commands.EXPRESSION_TREE_COMMAND:
            try {
              processExpressionCommand(valueObject, valueSender);
            } finally {
              valueObject.set();
              valueSender.clear();
            }
            break;

          default:
            // Unknown command. We don't know how long it is, so we need to shut the connection
            // down.
            System.err.println("Error: Invalid cmd send to server: Cmd=" + cmd); // $NON-NLS-1$
            doLoop = false;
            closeWhenDone = true;
            break;
        }
      }
    } catch (EOFException e) {
      // This is ok. It means that the connection on the other side was terminated.
      // So just accept this and go down.
    } catch (CommandException e) {
      throw e;
    } catch (SocketException e) {
      if (socket != null)
        throw new UnexpectedExceptionCommandException(
            false, e); // socket null means a valid close request
    } catch (Throwable e) {
      e.printStackTrace();
    } finally {
      if (closeWhenDone) {
        try {
          for (Iterator itr = expressionProcessors.values().iterator(); itr.hasNext(); ) {
            ExpressionProcesserController exp = (ExpressionProcesserController) itr.next();
            exp.close();
          }
        } finally {
          expressionProcessors.clear();
        }

        if (in != null)
          try {
            in.close();
          } catch (Exception e) {
          }
        in = null;
        if (out != null)
          try {
            out.close();
          } catch (Exception e) {
          }
        out = null;
        close();
      }
    }

    if (closeWhenDone && connectionThread != null) server.removeConnectionThread(connectionThread);
    if (shutdown) server.requestShutdown();

    return result;
  }
  /**
   * Parse the BSHBlock for for the class definition and generate the class using ClassGenerator.
   */
  public static Class generateClassImpl(
      String name,
      Modifiers modifiers,
      Class[] interfaces,
      Class superClass,
      BSHBlock block,
      boolean isInterface,
      CallStack callstack,
      Interpreter interpreter)
      throws EvalError {
    // Scripting classes currently requires accessibility
    // This can be eliminated with a bit more work.
    try {
      Capabilities.setAccessibility(true);
    } catch (Capabilities.Unavailable e) {
      throw new EvalError(
          "Defining classes currently requires reflective Accessibility.", block, callstack);
    }

    NameSpace enclosingNameSpace = callstack.top();
    String packageName = enclosingNameSpace.getPackage();
    String className =
        enclosingNameSpace.isClass ? (enclosingNameSpace.getName() + "$" + name) : name;
    String fqClassName = packageName == null ? className : packageName + "." + className;

    BshClassManager bcm = interpreter.getClassManager();
    // Race condition here...
    bcm.definingClass(fqClassName);

    // Create the class static namespace
    NameSpace classStaticNameSpace = new NameSpace(enclosingNameSpace, className);
    classStaticNameSpace.isClass = true;

    callstack.push(classStaticNameSpace);

    // Evaluate any inner class class definitions in the block
    // effectively recursively call this method for contained classes first
    block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSCLASSES);

    // Generate the type for our class
    Variable[] variables = getDeclaredVariables(block, callstack, interpreter, packageName);
    DelayedEvalBshMethod[] methods = getDeclaredMethods(block, callstack, interpreter, packageName);

    ClassGeneratorUtil classGenerator =
        new ClassGeneratorUtil(
            modifiers,
            className,
            packageName,
            superClass,
            interfaces,
            variables,
            methods,
            classStaticNameSpace,
            isInterface);
    byte[] code = classGenerator.generateClass();

    // if debug, write out the class file to debugClasses directory
    if (DEBUG_DIR != null)
      try {
        FileOutputStream out = new FileOutputStream(DEBUG_DIR + '/' + className + ".class");
        out.write(code);
        out.close();
      } catch (IOException e) {
        throw new IllegalStateException(
            "cannot create file " + DEBUG_DIR + '/' + className + ".class", e);
      }

    // Define the new class in the classloader
    Class genClass = bcm.defineClass(fqClassName, code);

    // import the unq name into parent
    enclosingNameSpace.importClass(fqClassName.replace('$', '.'));

    try {
      classStaticNameSpace.setLocalVariable(
          ClassGeneratorUtil.BSHINIT, block, false /*strictJava*/);
    } catch (UtilEvalError e) {
      throw new InterpreterError("unable to init static: " + e);
    }

    // Give the static space its class static import
    // important to do this after all classes are defined
    classStaticNameSpace.setClassStatic(genClass);

    // evaluate the static portion of the block in the static space
    block.evalBlock(callstack, interpreter, true /*override*/, ClassNodeFilter.CLASSSTATIC);

    callstack.pop();

    if (!genClass.isInterface()) {
      // Set the static bsh This callback
      String bshStaticFieldName = ClassGeneratorUtil.BSHSTATIC + className;
      try {
        LHS lhs = Reflect.getLHSStaticField(genClass, bshStaticFieldName);
        lhs.assign(classStaticNameSpace.getThis(interpreter), false /*strict*/);
      } catch (Exception e) {
        throw new InterpreterError("Error in class gen setup: " + e);
      }
    }

    bcm.doneDefiningClass(fqClassName);
    return genClass;
  }
Example #28
0
  /**
   * Gets registered object from CacheMap. The algorithm used to look up is <br>
   * 1. First check for exact match with clazz and context.<br>
   * 2. If didn't find, look for interfaces that clazz implements using the exact context.<br>
   * 3. If still didn't find, look for super class of clazz using the exact context. <br>
   * 4. If still didn't find, using the exact clazz with default context.<br>
   * 5. If still didn't find, return null.<br>
   * If found a match in step 1, 2, 3 or 4, it will return the registered object immediately.
   *
   * @param clazz the class which is used as the primary key.
   * @param context the context which is used as the secondary key. This parameter could be null in
   *     which case the default context is used.
   * @return registered object the object associated with the class and the context.
   */
  public T getRegisteredObject(Class<?> clazz, K context) {
    if (clazz == null) {
      return null;
    }

    Cache<K, T> cache = getCache(clazz);

    if (cache == null || !cache.containsKey(context)) {
      List<Class<?>> classesToSearch = new ArrayList<>();

      classesToSearch.add(clazz);
      if (TypeUtils.isPrimitive(clazz)) {
        classesToSearch.add(TypeUtils.convertPrimitiveToWrapperType(clazz));
      } else if (TypeUtils.isPrimitiveWrapper(clazz)) {
        classesToSearch.add(TypeUtils.convertWrapperToPrimitiveType(clazz));
      }

      // Direct super interfaces, recursively
      addAllInterfaces(classesToSearch, clazz);

      Class<?> superClass = clazz;
      // Direct super class, recursively
      while (!superClass.isInterface()) {
        superClass = superClass.getSuperclass();
        if (superClass != null) {
          classesToSearch.add(superClass);
          addAllInterfaces(classesToSearch, superClass);
        } else {
          break;
        }
      }

      if (!classesToSearch.contains(Object.class)) {
        classesToSearch.add(Object.class); // use Object as default fallback.
      }

      // search to match context first
      for (Class<?> c : classesToSearch) {
        Cache<K, T> cacheForClass = getCache(c);
        if (cacheForClass != null) {
          T object = cacheForClass.getObject(context);
          if (object != null) {
            return object;
          }
        }
      }

      // fall back to default context
      if (!_defaultContext.equals(context)) {
        for (Class<?> c : classesToSearch) {
          Cache<K, T> cacheForClass = getCache(c);
          if (cacheForClass != null) {
            T object = cacheForClass.getObject(_defaultContext);
            if (object != null) {
              return object;
            }
          }
        }
      }
    }

    if (cache != null) {
      T object = cache.getObject(context);
      if (object == null && !_defaultContext.equals(context)) {
        return getRegisteredObject(clazz, _defaultContext);
      }
      if (object != null) {
        return object;
      }
    }

    return null;
  }
Example #29
0
  public DataValueModelImpl(Class<T> type) {
    this.type = type;

    if (!type.isInterface())
      throw new IllegalArgumentException("type must be an interface, was " + type);

    Method[] methods = type.getMethods();
    for (Method method : methods) {
      Class<?> declaringClass = method.getDeclaringClass();
      if (declaringClass == Object.class
          || declaringClass == Externalizable.class
          || declaringClass == BytesMarshallable.class
          || declaringClass == Copyable.class
          || declaringClass == Byteable.class) continue;

      // ignore the default or static methods
      if (isMethodDefaultOrStatic(method)) continue;

      String name = method.getName();
      Class<?>[] parameterTypes = method.getParameterTypes();
      final Class<?> returnType = method.getReturnType();
      switch (parameterTypes.length) {
        case 0:
          {
            String name5 = getUnlock(name);
            if (name5 != null && returnType == void.class) {
              FieldModelImpl fm = acquireField(name5);
              fm.unlock(method);
              break;
            }
            String name4 = getBusyLock(name);
            if (name4 != null && returnType == void.class) {
              FieldModelImpl fm = acquireField(name4);
              fm.busyLock(method);
              break;
            }
            String name3 = getTryLock(name);
            if (name3 != null && returnType == boolean.class) {
              FieldModelImpl fm = acquireField(name3);
              fm.tryLock(method);
              break;
            }
            String name6 = getSizeOf(name);
            if (name6 != null && returnType == int.class) {
              FieldModelImpl fm = acquireField(name6);
              fm.sizeOf(method);
              break;
            }
            if (returnType == void.class)
              throw new IllegalArgumentException("void () not supported " + method);

            String name2 = getGetter(name, returnType);
            if (isVolatileGetter(name2)) {
              FieldModelImpl fm = acquireField(volatileGetterFieldName(name2));
              fm.volatileGetter(method);
              fm.setVolatile(true);

            } else {
              FieldModelImpl fm = acquireField(name2);
              fm.getter(method);
            }

            break;
          }

        case 1:
          {
            String name7 = getUsing(name, method);
            if (name7 != null) {
              FieldModelImpl fm = acquireField(name7);
              fm.getUsing(method);
              break;
            }

            String name5 = getTryLockNanos(name);
            if (name5 != null && returnType == boolean.class) {
              FieldModelImpl fm = acquireField(name5);
              fm.tryLockNanos(method);
              break;
            }

            String name4 = getAtomicAdder(name);
            if (name4 != null) {
              FieldModelImpl fm = acquireField(name4);
              fm.atomicAdder(method);
              break;
            }

            String name3 = getAdder(name);
            if (name3 != null) {
              FieldModelImpl fm = acquireField(name3);
              fm.adder(method);
              break;
            }

            String name6 = getGetterAt(name, returnType);
            if (name6 != null && parameterTypes[0] == int.class && returnType != void.class) {
              if (isVolatileGetter(name6)) {
                FieldModelImpl fm = acquireField(volatileGetterFieldName(name6));
                fm.volatileIndexedGetter(method);
                fm.setVolatile(true);

              } else {
                FieldModelImpl fm = acquireField(name6);
                fm.indexedGetter(method);
              }
              break;
            }

            if (returnType != void.class)
              throw new IllegalArgumentException("setter must be void " + method);

            String name2 = getSetter(name);
            if (isOrderedSetter(name2)) {
              FieldModelImpl fm = acquireField(orderedSetterFieldName(name2));
              fm.orderedSetter(method);

            } else {
              FieldModelImpl fm = acquireField(name2);
              fm.setter(method);
            }
            break;
          }

        case 2:
          {
            String name2 = getCAS(name);
            if (name2 != null && returnType == boolean.class) {
              FieldModelImpl fm = acquireField(name2);
              fm.cas(method);
              break;
            }
            String name3 = getSetterAt(name);
            if (name3 != null && parameterTypes[0] == int.class && returnType == void.class) {
              if (isOrderedSetter(name3)) {
                FieldModelImpl fm = acquireField(orderedSetterFieldName(name3));
                fm.orderedIndexedSetter(method);

              } else {
                FieldModelImpl fm = acquireField(name3);
                fm.indexedSetter(method);
              }
              break;
            }
          }

        default:
          {
            throw new IllegalArgumentException("method not supported " + method);
          }
      }
    }

    for (Map.Entry<String, FieldModelImpl> entry : fieldModelMap.entrySet()) {
      FieldModelImpl model = entry.getValue();
      if ((model.getter() == null && model.getUsing() == null)
          || (model.setter() == null && model.getter().getReturnType().isPrimitive()))
        if (model.volatileGetter() == null
            || (model.orderedSetter() == null
                && model.volatileGetter().getReturnType().isPrimitive()))
          if (model.indexedGetter() == null
              || (model.indexedSetter() == null
                  && model.indexedGetter().getReturnType().isPrimitive()))
            if (model.volatileIndexedGetter() == null
                || (model.orderedIndexedSetter() == null
                    && model.volatileIndexedGetter().getReturnType().isPrimitive()))
              if (model.busyLock() == null || model.unlock() == null)
                throw new IllegalArgumentException(
                    "Field "
                        + entry.getKey()
                        + " must have a getter & setter, or getAt & setAt, or busyLock & unlock.");
      if (model.indexedGetter() != null || model.indexedSetter() != null)
        if (model.indexSize() == null)
          throw new IllegalStateException(
              "You must set a MaxSize for the range of the index for the getter or setter");

      Class ftype = model.type();
      if (!isScalar(ftype) && !nestedMap.containsKey(ftype))
        nestedMap.put(ftype, new DataValueModelImpl(ftype));
    }
  }
  /**
   * Construct a proxy generator. This generator is used when we need to create a proxy object for a
   * class or an interface given a map of closures.
   *
   * @param closureMap the delegates implementations
   * @param superClass corresponding to the superclass class visitor
   * @param interfaces extra interfaces the proxy should implement
   * @param proxyLoader the class loader which should be used to load the generated proxy
   * @param delegateClass if not null, generate a delegate field with the corresponding class
   * @param emptyBody if set to true, the unimplemented abstract methods will receive an empty body
   *     instead of throwing an {@link UnsupportedOperationException}.
   */
  public ProxyGeneratorAdapter(
      final Map<Object, Object> closureMap,
      final Class superClass,
      final Class[] interfaces,
      final ClassLoader proxyLoader,
      final boolean emptyBody,
      final Class delegateClass) {
    super(new ClassWriter(0));
    this.visitedMethods = new LinkedHashSet<Object>();
    this.delegatedClosures =
        closureMap.isEmpty() ? EMPTY_DELEGATECLOSURE_MAP : new HashMap<String, Boolean>();
    boolean wildcard = false;
    for (Map.Entry<Object, Object> entry : closureMap.entrySet()) {
      String name = entry.getKey().toString();
      if ("*".equals(name)) {
        wildcard = true;
      }
      this.delegatedClosures.put(name, Boolean.FALSE);
    }
    this.hasWildcard = wildcard;

    // if we have to delegate to another object, generate the appropriate delegate field
    // and collect the name of the methods for which delegation is active
    this.generateDelegateField = delegateClass != null;
    this.objectDelegateMethods =
        generateDelegateField
            ? createDelegateMethodList(delegateClass, interfaces)
            : EMPTY_STRING_SET;
    this.delegateClass = delegateClass;

    // a proxy is supposed to be a concrete class, so it cannot extend an interface.
    // If the provided superclass is an interface, then we replace the superclass with Object
    // and add this interface to the list of implemented interfaces
    boolean isSuperClassAnInterface = superClass.isInterface();
    this.superClass = isSuperClassAnInterface ? Object.class : superClass;

    // create the base list of classes which have possible methods to be overloaded
    this.classList = new LinkedList<Class>();
    this.classList.add(superClass);
    if (generateDelegateField) {
      classList.add(delegateClass);
    }
    if (interfaces != null) {
      Collections.addAll(this.classList, interfaces);
    }
    this.proxyName = proxyName();
    this.loader = proxyLoader != null ? new InnerLoader(proxyLoader) : findClassLoader(superClass);
    this.emptyBody = emptyBody;

    // generate bytecode
    ClassWriter writer = (ClassWriter) cv;
    ClassReader cr = createClassVisitor(Object.class);
    cr.accept(this, 0);
    byte[] b = writer.toByteArray();
    //        CheckClassAdapter.verify(new ClassReader(b), true, new PrintWriter(System.err));
    cachedClass = loader.defineClass(proxyName.replace('/', '.'), b);
    // cache no-arg constructor
    Class[] args =
        generateDelegateField ? new Class[] {Map.class, delegateClass} : new Class[] {Map.class};
    Constructor constructor;
    try {
      constructor = cachedClass.getConstructor(args);
    } catch (NoSuchMethodException e) {
      constructor = null;
    }
    cachedNoArgConstructor = constructor;
  }