Package org.jboss.errai.ioc.rebind.ioc.codegen.meta

Source Code of org.jboss.errai.ioc.rebind.ioc.codegen.meta.MetaClassFactory

/*
* Copyright 2011 JBoss, a divison Red Hat, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.jboss.errai.ioc.rebind.ioc.codegen.meta;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

import javax.enterprise.util.TypeLiteral;

import org.jboss.errai.ioc.rebind.ioc.codegen.Context;
import org.jboss.errai.ioc.rebind.ioc.codegen.Statement;
import org.jboss.errai.ioc.rebind.ioc.codegen.builder.callstack.LoadClassReference;
import org.jboss.errai.ioc.rebind.ioc.codegen.meta.impl.gwt.GWTClass;
import org.jboss.errai.ioc.rebind.ioc.codegen.meta.impl.java.JavaReflectionClass;
import org.mvel2.ConversionHandler;
import org.mvel2.DataConversion;

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import sun.reflect.generics.tree.TypeTree;

/**
* @author Mike Brock <cbrock@redhat.com>
*/
public final class MetaClassFactory {
  static {

    DataConversion.addConversionHandler(Class.class, new ConversionHandler() {
      @Override
      public Object convertFrom(Object in) {
        if (MetaClass.class.isAssignableFrom(in.getClass())) {
          return ((MetaClass) in).asClass();
        }
        else {
          throw new RuntimeException("cannot convert from " + in.getClass() + "; to " + Class.class.getName());
        }
      }

      @Override
      public boolean canConvertFrom(Class cls) {
        return MetaType.class.isAssignableFrom(cls);
      }
    });

    DataConversion.addConversionHandler(Class[].class, new ConversionHandler() {
      @Override
      public Object convertFrom(Object in) {
        int length = Array.getLength(in);

        Class[] cls = new Class[length];
        for (int i = 0; i < length; i++) {
          Object el = Array.get(in, i);

          if (el instanceof MetaClass) {
            cls[i] = ((MetaClass) el).asClass();
          }
          else if (el != null && el.getClass().isArray()) {
            cls[i] = (Class) convertFrom(el);
          }
          else {
            cls[i] = null;
          }
        }
        return cls;
      }

      @Override
      public boolean canConvertFrom(Class cls) {
        while (cls.isArray()) {
          cls = cls.getComponentType();
        }
        return MetaClass.class.isAssignableFrom(cls) || MetaType.class.isAssignableFrom(cls);
      }
    });
  }

  private static final Map<String, MetaClass> CLASS_CACHE = new HashMap<String, MetaClass>();

  public static MetaClass get(String fullyQualifiedClassName) {
    return createOrGet(fullyQualifiedClassName);
  }

  public static MetaClass get(TypeOracle typeOracle, String fullyQualifiedClassName) {
    return createOrGet(typeOracle, fullyQualifiedClassName);
  }

  public static MetaClass get(TypeOracle typeOracle, Class<?> clazz) {
    return get(typeOracle, clazz.getName());
  }

  public static MetaClass get(JType clazz) {
    return createOrGet(clazz);
  }

  public static MetaClass get(Class<?> clazz) {
    return createOrGet(clazz);
  }

  public static MetaClass get(Class<?> clazz, Type type) {
    return createOrGet(clazz, type);
  }

  public static MetaClass get(TypeLiteral<?> literal) {
    return createOrGet(literal);
  }

  public static MetaMethod get(Method method) {
    return get(method.getDeclaringClass()).getDeclaredMethod(method.getName(), method.getParameterTypes());
  }

  public static MetaField get(Field field) {
    return get(field.getDeclaringClass()).getDeclaredField(field.getName());
  }

  public static Statement getAsStatement(Class<?> clazz) {
    final MetaClass metaClass = createOrGet(clazz);
    return new Statement() {
      @Override
      public String generate(Context context) {
        return LoadClassReference.getClassReference(metaClass, context);
      }

      @Override
      public MetaClass getType() {
        return MetaClassFactory.get(Class.class);
      }

      public Context getContext() {
        return null;
      }
    };
  }

  public static boolean isCached(String name) {
    return CLASS_CACHE.containsKey(name);
  }

  private static MetaClass createOrGet(String fullyQualifiedClassName) {
    if (!CLASS_CACHE.containsKey(fullyQualifiedClassName)) {
      return createOrGet(load(fullyQualifiedClassName));
    }

    return CLASS_CACHE.get(fullyQualifiedClassName);
  }

  private static MetaClass createOrGet(TypeOracle oracle, String fullyQualifiedClassName) {
    if (!CLASS_CACHE.containsKey(fullyQualifiedClassName)) {
      return createOrGet(load(oracle, fullyQualifiedClassName));
    }

    return CLASS_CACHE.get(fullyQualifiedClassName);
  }

  private static MetaClass createOrGet(TypeLiteral type) {
    if (type == null) return null;

    if (!CLASS_CACHE.containsKey(type.toString())) {
      MetaClass gwtClass = JavaReflectionClass.newUncachedInstance(type);

      addLookups(type, gwtClass);
      return gwtClass;
    }

    return CLASS_CACHE.get(type.toString());
  }


  private static MetaClass createOrGet(JType type) {
    if (type == null) return null;

    if (type.isParameterized() != null) {
      return GWTClass.newUncachedInstance(type, true);
    }

    if (!CLASS_CACHE.containsKey(type.getQualifiedSourceName())) {
      MetaClass gwtClass = GWTClass.newUncachedInstance(type);

      addLookups(type, gwtClass);
      return gwtClass;
    }

    return CLASS_CACHE.get(type.getQualifiedSourceName());
  }


  private static MetaClass createOrGet(Class cls) {
    if (cls == null) return null;

    if (cls.getTypeParameters() != null) {
      return JavaReflectionClass.newUncachedInstance(cls, true);
    }

    if (!CLASS_CACHE.containsKey(cls.getName())) {
      MetaClass javaReflectionClass = JavaReflectionClass.newUncachedInstance(cls);

      addLookups(cls, javaReflectionClass);
      return javaReflectionClass;
    }

    return CLASS_CACHE.get(cls.getName());
  }

  private static MetaClass createOrGet(Class cls, Type type) {
    if (cls == null) return null;

    if (cls.getTypeParameters() != null) {
      return JavaReflectionClass.newUncachedInstance(cls, type);
    }

    if (!CLASS_CACHE.containsKey(cls.getName())) {
      MetaClass javaReflectionClass = JavaReflectionClass.newUncachedInstance(cls, type);

      addLookups(cls, javaReflectionClass);
      return javaReflectionClass;
    }

    return CLASS_CACHE.get(cls.getName());
  }

  private static void addLookups(TypeLiteral literal, MetaClass metaClass) {
    CLASS_CACHE.put(literal.toString(), metaClass);
  }

  private static void addLookups(Class cls, MetaClass metaClass) {
    CLASS_CACHE.put(cls.getName(), metaClass);
  }

  private static void addLookups(JType cls, MetaClass metaClass) {
    CLASS_CACHE.put(cls.getQualifiedSourceName(), metaClass);
  }

  private static Class<?> load(String fullyQualifiedName) {
    try {
      return Class.forName(fullyQualifiedName, false, Thread.currentThread().getContextClassLoader());
    }
    catch (ClassNotFoundException e) {
      throw new RuntimeException("Could not load class: " + fullyQualifiedName);
    }
  }

  private static JClassType load(TypeOracle oracle, String fullyQualifiedName) {
    try {
      return oracle.getType(fullyQualifiedName);
    }
    catch (NotFoundException e) {
      throw new RuntimeException("Could not load class: " + fullyQualifiedName);
    }
  }

  public static MetaClass[] fromClassArray(Class<?>[] classes) {
    MetaClass[] newClasses = new MetaClass[classes.length];
    for (int i = 0; i < classes.length; i++) {
      newClasses[i] = createOrGet(classes[i]);
    }
    return newClasses;
  }

  public static Class<?>[] asClassArray(MetaParameter[] parms) {
    MetaType[] type = new MetaType[parms.length];
    for (int i = 0; i < parms.length; i++) {
      type[i] = parms[i].getType();
    }
    return asClassArray(type);
  }

  public static Class<?>[] asClassArray(MetaType[] cls) {
    Class<?>[] newClasses = new Class<?>[cls.length];
    for (int i = 0; i < cls.length; i++) {
      if (cls[i] instanceof MetaParameterizedType) {
        newClasses[i] = ((MetaClass) ((MetaParameterizedType) cls[i]).getRawType()).asClass();
      }
      else {
        newClasses[i] = ((MetaClass) cls[i]).asClass();
      }
    }
    return newClasses;
  }
}
TOP

Related Classes of org.jboss.errai.ioc.rebind.ioc.codegen.meta.MetaClassFactory

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.