Package com.gwtent.gen.reflection

Source Code of com.gwtent.gen.reflection.GeneratorHelper

/*******************************************************************************
*  Copyright 2001, 2007 JamesLuo(JamesLuo.au@gmail.com)
*  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.
*
*  Contributors:
*******************************************************************************/


package com.gwtent.gen.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.typeinfo.JAnnotationMethod;
import com.google.gwt.core.ext.typeinfo.JAnnotationType;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.SourceWriter;
import com.gwtent.common.client.CheckedExceptionWrapper;
import com.gwtent.gen.reflection.accessadapter.JFeildAdapter;
import com.gwtent.gen.reflection.accessadapter.JMethodAdapter;
import com.gwtent.reflection.client.AccessDef;
import com.gwtent.reflection.client.ClassType;
import com.gwtent.reflection.client.ReflectionTarget;
import com.gwtent.reflection.client.ReflectionUtils;
import com.gwtent.reflection.client.impl.TypeOracleImpl;

public class GeneratorHelper {
 
  public static boolean isSystemClass(JClassType type){
    return type.getPackage().getName().startsWith("java.") || type.getPackage().getName().startsWith("javax.");
  }
 
  /**
   * private interface ClassTypeOfA extends ClassType<ClassA>{
   * <p>
   * <p>  }
   *
   * <p> find a Parameterized class/interface in super classs/interfaces,
   * this class should a sub class of ClassType class and will point out what's the class need generate reflection information
   *
   * <p> if can NOT found, give a error, user should correct this before final compile
   * @param classType
   * @return
   */
  public static JClassType getReflectionClassType(TypeOracle oracle, JClassType classType){
    JClassType classClassType;
    try {
      classClassType = oracle.getType(ClassType.class.getCanonicalName());
    } catch (NotFoundException e) {
      throw new RuntimeException("Can not found reflection class, forgot include module xml file?" + e.getMessage());
    }
   
    ReflectionTarget target = classType.getAnnotation(ReflectionTarget.class);
    if (target != null){
      if (target.value() != null && target.value().length() > 0){
        try {
          return oracle.getType(target.value());
        } catch (NotFoundException e) {
         
        }
      }
    }
   
    for (JClassType supClass : classType.getFlattenedSupertypeHierarchy()){
      if (supClass.isParameterized() != null && supClass.isAssignableTo(classClassType)){
        if (supClass.isParameterized().getTypeArgs().length == 1){
          return supClass.isParameterized().getTypeArgs()[0];
        }else{
          throw new RuntimeException("ClassType should have only one Parameterized type, please see document of ClassType interface. Current processing type: " + classType.getQualifiedSourceName() + ", Current parameterized type count:" + classType.isParameterized().getTypeArgs().length);
        }
      }
    }
   
    throw new RuntimeException("ClassType should have at least one Parameterized type or annotated by @ReflectionTarget, please see document of ClassType interface. Current processing type: " + classType.getQualifiedSourceName());
  }
 
 
  public static int AccessDefToInt(AccessDef accessDef){
    int result = 0;
   
    if (accessDef.isFinal()) result += TypeOracleImpl.MOD_FINAL;
    if (accessDef.isPrivate()) result += TypeOracleImpl.MOD_PRIVATE;
    if (accessDef.isProtected()) result += TypeOracleImpl.MOD_PROTECTED;
    if (accessDef.isPublic()) result += TypeOracleImpl.MOD_PUBLIC;
    if (accessDef.isStatic()) result += TypeOracleImpl.MOD_STATIC;
   
    return result;
  }
 
  public static int AccessDefToInt(JField field){
    JFeildAdapter adapter = new JFeildAdapter(field);
    return AccessDefToInt(adapter);
  }
 
  public static int AccessDefToInt(JMethod method){
    JMethodAdapter adapter = new JMethodAdapter(method);
    return AccessDefToInt(adapter);
  }
 
 
  /**
   * Give a array of JClassTypes, return the array of qualified source name of it.
   * @param types
   * @return
   */
  public static String[] convertJClassTypeToStringArray(JClassType[] types){
    String[] result = new String[types.length];
   
    for (int i = 0; i < types.length; i++)
      result[i] = types[i].getQualifiedSourceName();
     
    return result;
  }
 
 
  public static String stringArrayToCode(String[] strs){
    StringBuilder result = new StringBuilder("new String[]{");
   
    for (int i = 0; i < strs.length; i++){
      result.append("\"" + processInvertedComma(strs[i]) + "\"");
     
      if (i < (strs.length - 1)) result.append(", ");
    }
   
    result.append("}");
   
    return result.toString();
  }
 
  /**
   * generator metaData
   * @param dest field or method or class
   * @param source source to print code
   * @param metaData
   */
  public static void addMetaDatas(String dest, SourceWriter source, com.google.gwt.core.ext.typeinfo.HasMetaData metaData) {
    String[] tags = metaData.getMetaDataTags();
    for (int j = 0; j < tags.length; j++){
      String[][] metas = metaData.getMetaData(tags[j]);
      for (int k = 0; k < metas.length; k++){
        source.println(dest + ".addMetaData(\"" + tags[j] + "\", " + GeneratorHelper.stringArrayToCode(metas[k]) ");");
      }
    }
  }
 
  public static String processInvertedComma(String str){
//    return str.replaceAll("\"", "\\\"");
    StringBuffer sb = new StringBuffer();
    int length = str.length();
    for (int i = 0; i < length; i++){
      //not first char and last char  (i != 0) && (i != (length - 1)) &&
      if ((str.charAt(i) == '"')){
        sb.append("\\\"");
      }else{
        sb.append(str.charAt(i));
      }
    }
    return sb.toString();
   
  }
 
  private static String toString(Object object){
    if (object instanceof Class)
      return ((Class)object).getName();
    else if (object.getClass().isArray()){
      StringBuilder sb = new StringBuilder();
      sb.append("[");
      for (int i = 0; i < Array.getLength(object); i++){
        if (i > 0)
          sb.append(", ");
        sb.append(Array.get(object, i).toString());
      }
      sb.append("]");
      return sb.toString();
    }
    else
      return object.toString();
  }
 
 
  public static void addAnnotations_AnnotationImpl(com.google.gwt.core.ext.typeinfo.TypeOracle typeOracle,
      String dest, SourceWriter source, Annotation[] annotations, TreeLogger logger){
 
    if (annotations.length <= 0)
      return;
   
    for (Annotation annotation : annotations) {
      JClassType classType = typeOracle.findType(ReflectionUtils.getQualifiedSourceName(annotation.annotationType()));
      if (classType != null){
        source.print(dest + ".addAnnotation(" + createAnnotationValues(typeOracle, annotation, logger) + ");");
       
      }else{
        logger.log(Type.ERROR, "Annotation (" + ReflectionUtils.getQualifiedSourceName(annotation.annotationType()) + ") not exists in compiled client source code, please ensure this class is exists and included in your module(.gwt.xml) file. GWTENT reflection process will ignore it and continue. ");
      }
    }
  }
 
  public static String createAnnotationValues(com.google.gwt.core.ext.typeinfo.TypeOracle typeOracle,
      Annotation annotation, TreeLogger logger){
    StringBuilder sb = new StringBuilder();
    JClassType classType = typeOracle.findType(ReflectionUtils.getQualifiedSourceName(annotation.annotationType()));
    if (classType != null){
      sb.append("com.gwtent.reflection.client.impl.AnnotationValues.toAnnotation(new com.gwtent.reflection.client.impl.AnnotationValues(");
      sb.append("\"" + classType.getQualifiedSourceName() + "\", new Object[]{");
     
      JAnnotationType annoType = classType.isAnnotation();
      // JAnnotationMethod[] methods = annoType.getMethods();
      JAnnotationMethod[] methods = (JAnnotationMethod[]) annoType.getMethods();
      int index = 0;
      for (JAnnotationMethod method : methods) {
        Object value = null;
        try {
          value = annotation.annotationType().getMethod(method.getName(), new Class[]{}).invoke(annotation);
          if (index > 0)
            sb.append(", ");
          sb.append(annoValueToCode(typeOracle, value, logger));
          index ++;
        } catch (Exception e){
          throw new CheckedExceptionWrapper(e);
        }
      }
      sb.append("}))");
     
    }else{
      logger.log(Type.ERROR, "Annotation (" + ReflectionUtils.getQualifiedSourceName(annotation.annotationType()) + ") not exists in compiled client source code, please ensure this class is exists and included in your module(.gwt.xml) file. GWTENT reflection process will ignore it and continue. ");
    }
    return sb.toString();
  }
 
  /**
   * value type: primitive, String, Class, enumerated, annotation, array of
   *
   * primitive need take care.
   * For example float 2.0, it need changed to 2.0F, otherwise it's becomes a Double
   *
   * @param object
   * @return
   */
  public static String annoValueToCode(com.google.gwt.core.ext.typeinfo.TypeOracle typeOracle, Object object, TreeLogger logger){
    if (object == null)
      return "null";
   
    if (object instanceof String){
      return "\"" + object.toString().replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
    }else if (object instanceof Class){
      return ((Class)object).getCanonicalName() + ".class";    //inner class will got problem
    }else if (object.getClass().isArray()){
      StringBuilder sb = new StringBuilder();
      //new ElementType[]{ElementType.ANNOTATION_TYPE};
      Class<?> compType = object.getClass().getComponentType();
      sb.append("new ").append(compType.getCanonicalName()).append("[] {");
      for (int i = 0; i < Array.getLength(object); i++){
        if (i > 0)
          sb.append(", ");
        if (compType.isAnnotation())
          sb.append("(").append(compType.getCanonicalName()).append(")");
        sb.append(annoValueToCode(typeOracle, Array.get(object, i), logger));
      }
      sb.append("}");
      return sb.toString();
    } else if (object.getClass().isEnum()){
      return object.getClass().getCanonicalName() + "." + ((Enum)object).name();
    }else if (object instanceof Annotation){
      return createAnnotationValues(typeOracle, (Annotation)object, logger);
    }else if (object instanceof Float){
      return object.toString() + "F";
    }else if (object instanceof Double){
      return object.toString() + "D";
    } else if (object instanceof Long){
      return object.toString() + "L";
    }
   
    return object.toString();
  }
 
 
 
}
TOP

Related Classes of com.gwtent.gen.reflection.GeneratorHelper

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.