Package org.radargun.utils

Source Code of org.radargun.utils.ReflexiveConverters$ListConverter

package org.radargun.utils;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.radargun.Directories;
import org.radargun.config.AnnotatedHelper;
import org.radargun.config.ComplexConverter;
import org.radargun.config.ComplexDefinition;
import org.radargun.config.Definition;
import org.radargun.config.DefinitionElement;
import org.radargun.config.PropertyHelper;
import org.radargun.config.SimpleDefinition;

/**
* Converts a elements in definition into list of instances. Instance class
* is chosen according to element name as specified in {@link org.radargun.config.DefinitionElement#name()}
* on one of the classes passed in the constructor, or classes implementing class passed to the contructor.
* In the latter case, all JARs in lib/ are scanned for these implementations annotated with DefinitionElement
*
* @author Radim Vansa <rvansa@redhat.com>
*/
public class ReflexiveConverters {

   protected static abstract class Base {
      protected final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();

      protected Base(Class<?>[] classes) {
         for (Class<?> clazz : classes) {
            DefinitionElement de = clazz.getAnnotation(DefinitionElement.class);
            if (de == null) {
               throw new IllegalArgumentException(clazz.getName() + " missing @DefinitionElement");
            }
            if (this.classes.containsKey(de.name())) {
               throw new IllegalArgumentException("Trying to register " + clazz.getName() + " as '" + de.name()
                     + "' but this is already used by " + this.classes.get(de.name()));
            }
            this.classes.put(de.name(), clazz);
         }
      }

      protected <T> Base(Class<T> implementedClass) {
         for (File file : Directories.LIB_DIR.listFiles(new Utils.JarFilenameFilter())) {
            for (Class<? extends T> clazz : AnnotatedHelper.getClassesFromJar(file.getPath(), implementedClass, DefinitionElement.class)) {
               DefinitionElement de = clazz.getAnnotation(DefinitionElement.class);
               if (this.classes.containsKey(de.name())) {
                  throw new IllegalArgumentException("Trying to register " + clazz.getName() + " as '" + de.name()
                        + "' but this is already used by " + this.classes.get(de.name()));
               }
               classes.put(de.name(), clazz);
            }
         }
      }

      protected Object instantiate(String name, Definition definition) {
         Class<?> clazz = classes.get(name);
         if (clazz == null) throw new IllegalArgumentException(name);
         Object item;
         try {
            Constructor<?> ctor = clazz.getDeclaredConstructor();
            ctor.setAccessible(true);
            item = ctor.newInstance();
         } catch (Exception e) {
            throw new IllegalArgumentException("Cannot instantiate " + clazz.getName(), e);
         }
         DefinitionElement de = clazz.getAnnotation(DefinitionElement.class);
         if (definition instanceof ComplexDefinition) {
            if (de.resolveType() == DefinitionElement.ResolveType.PASS_BY_MAP) {
               PropertyHelper.setPropertiesFromDefinitions(item, ((ComplexDefinition) definition).getAttributeMap(), false, true);
            } else if (de.resolveType() == DefinitionElement.ResolveType.PASS_BY_DEFINITION) {
               PropertyHelper.setPropertiesFromDefinitions(item, Collections.singletonMap("", definition), false, true);
            } else throw new IllegalStateException(de.resolveType().toString());
         } else if (definition instanceof SimpleDefinition) {
            PropertyHelper.setProperties(item, Collections.singletonMap("", ((SimpleDefinition) definition).value), false, true);
         }
         return item;
      }

      public Collection<Class<?>> content() {
         return classes.values();
      }
   }

   public static class ObjectConverter extends Base implements ComplexConverter<Object> {
      public ObjectConverter(Class<?>[] classes) {
         super(classes);
      }

      public <T> ObjectConverter(Class<T> implementedClass) {
         super(implementedClass);
      }

      @Override
      public Object convert(ComplexDefinition definition, Type type) {
         List<ComplexDefinition.Entry> attributes = definition.getAttributes();
         if (attributes.size() != 1) throw new IllegalArgumentException("Single attribute expected");
         return instantiate(attributes.get(0).name, attributes.get(0).definition);
      }

      @Override
      public String convertToString(Object value) {
         if (value == null) return "null";
         DefinitionElement de = value.getClass().getAnnotation(DefinitionElement.class);
         if (de == null) throw new IllegalArgumentException("Object does not have DefinitionElement attached: " + value);
         return String.format("%s -> %s", de.name(), value);
      }

      @Override
      public int minAttributes() {
         return 1;
      }

      @Override
      public int maxAttributes() {
         return 1;
      }
   }

   public static class ListConverter extends Base implements ComplexConverter<List> {
      public ListConverter(Class<?>[] classes) {
         super(classes);
      }

      public <T> ListConverter(Class<T> implementedClass) {
         super(implementedClass);
      }

      @Override
      public List convert(ComplexDefinition definition, Type type) {
         if (type instanceof Class<?>) {
            Class<?> clazz = (Class<?>) type;
            if (!List.class.isAssignableFrom(clazz)) throw new IllegalArgumentException(type.toString());
         } else if (type instanceof ParameterizedType) {
            ParameterizedType ptype = (ParameterizedType) type;
            if (!List.class.isAssignableFrom((Class<?>) ptype.getRawType())) throw new IllegalArgumentException(type.toString());
         }
         List list = new ArrayList();
         for (ComplexDefinition.Entry entry : definition.getAttributes()) {
            list.add(instantiate(entry.name, entry.definition));
         }
         return list;
      }

      @Override
      public String convertToString(List list) {
         StringBuilder sb = new StringBuilder("[ ");
         boolean first = true;
         for (Object item : list) {
            if (!first) {
               sb.append(", ");
            }
            first = false;
            DefinitionElement de = item.getClass().getAnnotation(DefinitionElement.class);
            if (de != null) {
               sb.append(de.name()).append(" = ");
            }
            sb.append(String.valueOf(item));
         }
         return sb.append(" ]").toString();
      }

      @Override
      public int minAttributes() {
         return 0;
      }

      @Override
      public int maxAttributes() {
         return -1;
      }
   }
}
TOP

Related Classes of org.radargun.utils.ReflexiveConverters$ListConverter

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.