Package com.gwtmobile.persistence.rebind

Source Code of com.gwtmobile.persistence.rebind.GenUtils

/*
* Copyright 2010 Zhihua (Dennis) Jiang
*
* 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 com.gwtmobile.persistence.rebind;

import java.io.PrintWriter;
import java.util.List;
import java.util.Set;

import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

public class GenUtils {
  private TreeLogger logger;
  private GeneratorContext context;
  private SourceWriter sw;
  private ClassSourceFileComposerFactory factory;
 
  public GenUtils(TreeLogger logger, GeneratorContext context) {
    this.logger = logger;
    this.context = context;
  }
 
  public String generateClass(String requestedTypeName, String gennedTypeNameSuffix,
      ClassGenerator classGenerator) {
        // The package the class is going to be in.
        String packageName = getPackageName(requestedTypeName);
        String gennedTypeName = getClassName(requestedTypeName) + gennedTypeNameSuffix;
        PrintWriter pw = context.tryCreate(logger, packageName, gennedTypeName);
      
        // No PrintWriter means we've generated the same code before.
        if (pw != null) {
            factory = new ClassSourceFileComposerFactory(packageName, gennedTypeName);
            classGenerator.classSetup();
            sw = factory.createSourceWriter(context, pw);                       
            classGenerator.generateClass();
            sw.commit(logger);
        }
        return packageName + "." + gennedTypeName;
  }

  public void generateInnerClass(String modifiers, String className, String superClass, String[] interfaces,
      ClassGenerator classGenerator) {
    sw.println();
    print("%s class %s", modifiers, className);
    if (superClass != null) {
      print(" extends %s", superClass);
    }
    if (interfaces != null) {
      print(" implements ");
      for (int i = 0; i < interfaces.length; i++) {
        if (i > 0) {
          print(",");
        }
        print(interfaces[i]);
      }
    }
    println(" {");
    sw.indent();
    classGenerator.classSetup();
    classGenerator.generateClass();
    sw.outdent();
    println("}");
  }
 
  public void genrateStaticConstructor(MethodGenerator bodyGenerator) {
    sw.println();
    sw.println("static {");
    sw.indent();
    bodyGenerator.generateMethod();
    sw.outdent();
    sw.println("}");
  }

  public boolean generateMethod(String modifiers, String returnType,
      String methodName, String[][] params, MethodGenerator methodGenerator) {
    return generateMethod(modifiers, returnType, methodName, params, false, methodGenerator)
  }
 
  public boolean generateNativeMethod(String modifiers, String returnType,
      String methodName, String[][] params, MethodGenerator methodGenerator) {
    return generateMethod(modifiers, returnType, methodName, params, true, methodGenerator)
  }
 
  private boolean generateMethod(String modifiers, String returnType,
      String methodName, String[][] params, boolean isNative, MethodGenerator methodGenerator) {
   
    sw.println();
    sw.print(modifiers + " ");
    if (isNative) {
      sw.print("native ");
    }
    if (returnType != null) {
      sw.print(returnType + " ");
    }
    sw.print(methodName + "(");
    if (params != null ) {
      for (int i = 0; i < params.length; i++) {
        print("%s %s", params[i][0], params[i][1]);
        if (i < params.length - 1) {
          print(", ");
        }
      }
    }
    sw.print(") ");
    if (isNative) {
      sw.print("/*-");
    }
    sw.println("{");
    sw.indent();
    if (methodGenerator != null) {
      methodGenerator.generateMethod();     
    }
    sw.outdent();
    sw.print("}");
    if (isNative) {
      sw.print("-*/;");
    }
    sw.println();
    return true;   
  }
 
  public SourceWriter sw() {
    return sw;
  }
 
  ClassSourceFileComposerFactory factory() {
    return factory;
  }

  public void print(String format, Object... args) {
    sw.print(String.format(format, args));
  }

  public void println(String format, Object... args) {
    sw.println(String.format(format, args));
  }
 
  public void addVariable(String modifiers, String type, String name) {
    sw.println(String.format("%s %s %s;", modifiers, type, name));
  }

  public void addVariable(String modifiers, String type, String name, String initValue) {
    sw.println(String.format("%s %s %s = %s;", modifiers, type, name, initValue));
  }

  public String getPackageName(String typeName) {
        final JClassType classType = getClassType(typeName);
        if (classType != null) {
          return classType.getPackage().getName();
        }
        return null;
  }

  public String getClassName(String typeName) {
        final JClassType classType = getClassType(typeName);
        if (classType != null) {
          return classType.getName();
        }
        return null;
  }
 
  public Boolean isInterface(String typeName) {
    JClassType classType = getClassType(typeName);
    return classType.isInterface() != null;
  }
 
  public JClassType getClassType(String typeName) {
    if (typeName.indexOf('.') < 0) {
      typeName = factory.getCreatedPackage() + "." + typeName;     
    }
        TypeOracle typeOracle = context.getTypeOracle();
        return typeOracle.findType(typeName);
  }
 
  public String getSQLiteType(JType returnType) {
    String sqliteType = null;
    JPrimitiveType primitiveReturnType = returnType.isPrimitive();
    if (primitiveReturnType != null) {
      if (primitiveReturnType == JPrimitiveType.INT)
      {
        sqliteType = "INTEGER";
      }
      else if (primitiveReturnType == JPrimitiveType.BOOLEAN)
      {
        sqliteType = "BOOL";
      }
      else {
        sqliteType = primitiveReturnType.getSimpleSourceName().toUpperCase();
      }
    }
    else
    {
      String returnTypeName = returnType.getSimpleSourceName();
      if (returnTypeName.equals("String")) {
        sqliteType = "TEXT";       
      }
      else if (isSubclassOf(returnType, "JSONValue")) {
        sqliteType = "JSON";
      }
      else {
        sqliteType = returnTypeName.toUpperCase();
      }
    }
    return sqliteType;
  }
 
  public void inspectType(String typeName, List<JMethod> getters, List<JMethod> hasManyRels, List<JMethod> hasOneRels) throws UnableToCompleteException {
    JClassType classType = getClassType(typeName);
    for (JMethod method : classType.getOverridableMethods()) {
      if (!method.isAbstract()) {
        continue;
      }
      String methodName = method.getName();
      if (methodName.startsWith("get")) {
        String propertyName = methodName.substring(3)// getId() is reserved.
        if (propertyName.equals("Id")) {
          continue;
        }
        JType returnType = method.getReturnType();
        String returnTypeName = returnType.getSimpleSourceName();
        if (returnType.isPrimitive() != null && !returnTypeName.equals("long")
            || returnTypeName.equals("String")
            || returnTypeName.equals("Date")
            || isSubclassOf(returnType, "JSONValue")) {
          getters.add(method);
          continue;
        }
        if (returnTypeName.equals("long")) {
          logger.log(TreeLogger.ERROR,
                      "GWT JSNI does not support 'long' as return type on getter '" + methodName + "'. Use 'double' instead.");
            throw new UnableToCompleteException();
        }
       
        if (returnTypeName.startsWith("Collection")) {
          hasManyRels.add(method);
          continue;
        }
       
        if (isSubclassOf(returnType, "Persistable")) {
          hasOneRels.add(method);
          continue;
        }

        logger.log(TreeLogger.ERROR,
                  "Unsupported return type '" + returnTypeName + "' on getter '" + methodName + "'.");
        throw new UnableToCompleteException();
      }
      else {
        // TODO: check if method is a setter. ignore if so, error if not.
      }
       
    }
  }
 
  public boolean isSubclassOf(JType type, String superClass) {
    JClassType classType = type.isInterface();
    if (classType == null) {
      classType = type.isClass();
    }
    if (classType == null) {
      return false;
    }
    Set<? extends JClassType> superTypes = classType.getFlattenedSupertypeHierarchy();
    for (JClassType superType : superTypes) {
      if (superType.getSimpleSourceName().equals(superClass)) {
        return true;
      }
    }
    return false;
  }
 
  public String getGenericTypeShortName(String collectionTypeName) {
    int beginIndex = collectionTypeName.indexOf('<') + 1;
    int endIndex = collectionTypeName.indexOf('>');
    String genericTypeName = collectionTypeName.substring(beginIndex, endIndex);
    beginIndex = genericTypeName.lastIndexOf('.');
    if (beginIndex >= 0) {
      return genericTypeName.substring(beginIndex + 1);
    }
    else {
      return genericTypeName;
    }   
  }
}
TOP

Related Classes of com.gwtmobile.persistence.rebind.GenUtils

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.