Package com.google.gwt.maeglin89273.game.mengine.rebind

Source Code of com.google.gwt.maeglin89273.game.mengine.rebind.AssetsBundleGenerator

/**
*
*/
package com.google.gwt.maeglin89273.game.mengine.rebind;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.resources.client.ClientBundleWithLookup;
import com.google.gwt.resources.client.DataResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.ResourcePrototype;
import com.google.gwt.resources.client.TextResource;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

/**
* @author Maeglin Liao
*
*/
public class AssetsBundleGenerator extends Generator {
  private static final String WEB_INF_CLASSES="WEB-INF/classes/";
  private static final Map<String,Class<? extends ResourcePrototype>> EXTENSION_TYPE_MAP=new HashMap<String,Class<? extends ResourcePrototype>>();
  private static FileFilter dirFilter=new FileFilter(){

    @Override
    public boolean accept(File pathname) {
      return pathname.isDirectory();
    }
   
  };
  private static FileFilter fileFilter=new FileFilter(){

    @Override
    public boolean accept(File pathname) {
      return pathname.isFile();
    }
   
  };
  static {
    EXTENSION_TYPE_MAP.put(".png", ImageResource.class);
    EXTENSION_TYPE_MAP.put(".jpg", ImageResource.class);
    EXTENSION_TYPE_MAP.put(".jpeg", ImageResource.class);
    EXTENSION_TYPE_MAP.put(".gif", ImageResource.class);
    EXTENSION_TYPE_MAP.put(".json", DataResource.class);
  }
 

  /* (non-Javadoc)
   * @see com.google.gwt.core.ext.Generator#generate(com.google.gwt.core.ext.TreeLogger, com.google.gwt.core.ext.GeneratorContext, java.lang.String)
   */
  @Override
  public String generate(TreeLogger logger, GeneratorContext context,
      String typeName) throws UnableToCompleteException {
    JClassType userType;
    try {
      userType=context.getTypeOracle().getType(typeName);
    } catch (NotFoundException e) {
      logger.log(Type.ERROR, "cannot find the type:"+typeName, e);
      throw new UnableToCompleteException();
    }
    if(userType.isInterface()==null){
      logger.log(Type.ERROR, typeName+"is not an interface.");
      throw new UnableToCompleteException();
    }
   
    String packageName=userType.getPackage().getName();
    String implClassName=userType.getName()+"Impl";
    File baseDir=getClassesFile(logger);
   
    Set<File> files=getInnerFiles(new File(baseDir,packageName.replace('.', '/')));
    Set<String> methodNames=new HashSet<String>();
   
    ClassSourceFileComposerFactory cf=new ClassSourceFileComposerFactory(packageName,implClassName);
   
    cf.addImport(ClientBundleWithLookup.class.getCanonicalName());
    cf.addImport(GWT.class.getCanonicalName());
    cf.addImport(ResourcePrototype.class.getCanonicalName());
    cf.addImport(ImageResource.class.getCanonicalName());
    cf.addImport(TextResource.class.getCanonicalName());
    cf.addImport(DataResource.class.getCanonicalName());
   
    cf.addImplementedInterface(userType.getQualifiedSourceName());
   
    PrintWriter pw=context.tryCreate(logger, packageName, implClassName);
    if(pw!=null){
      SourceWriter sw=cf.createSourceWriter(context, pw);
     
      logger.log(Type.INFO, "Start generating assets bundle...");
      sw.println("@Override");
      sw.println("public ResourcePrototype[] getResources() {");
      sw.indent();
      sw.print("return MyClientBundleWithLookup.INSTANCE.getResources();");
      sw.outdent();
      sw.println("}");
     
      sw.println("static interface MyClientBundleWithLookup extends ClientBundleWithLookup{");
      sw.indent();
      sw.println("MyClientBundleWithLookup INSTANCE=GWT.create(MyClientBundleWithLookup.class);");
     
      for(File file:files){
        String sourcePath=file.getPath().replace(baseDir.getPath()+"\\","").replace('\\', '/');
        Class<? extends ResourcePrototype> returnType=matchReturnType(file.getName());
        if(returnType==null){
          continue;
        }
        String methodName=stripExtension(file.getName());
       
        if(!isValidMethodName(methodName)){
          logger.log(TreeLogger.WARN, "Skipping invalid method name (" + methodName + ") due to: "
                      + sourcePath);
                  continue;
        }else if(!methodNames.add(methodName)){
          logger.log(TreeLogger.WARN, "Skipping duplicate method name :"+methodName+
              ". Maybe you have the files with the same name in different directories.");
        }
        logger.log(TreeLogger.DEBUG, "Generating method for: " + sourcePath+", and method name is: "+methodName);
        sw.println("@Source(\""+sourcePath+"\")");
        sw.println("public "+returnType.getName()+" "+methodName+"();");
      }
     
      sw.outdent();
      sw.println("}");
     
      sw.commit(logger);
      logger.log(Type.INFO, "Generated assets bundle successfully.");
    }
    return cf.getCreatedClassName();
  }
  private Class<? extends ResourcePrototype> matchReturnType(String filename) {
    return EXTENSION_TYPE_MAP.get(getExtension(filename));
   
  }

 
  private String stripExtension(String filename){
    return filename.substring(0, filename.lastIndexOf('.'));
  }
  private String getExtension(String filename) {
    return filename.substring(filename.lastIndexOf('.')).toLowerCase();
  }
  private boolean isValidMethodName(String methodName){
    return methodName.matches("^[a-zA-Z_$][a-zA-Z0-9_$]*$");
  }
  private File getClassesFile(TreeLogger logger) throws UnableToCompleteException{
    File warDir=new File(".");
    try {
      if(warDir.getCanonicalPath().endsWith("war")){
        return new File(warDir,WEB_INF_CLASSES);
      }else{
        return new File("war/"+WEB_INF_CLASSES);
      }
     
    } catch (IOException e) {
      logger.log(Type.ERROR, "Failed to get canonical path.",e);
      throw new UnableToCompleteException();
    }
  }
  private Set<File> getInnerFiles(File dir){
    if(!dir.isDirectory()){
      return null;
    }
    Set<File> innerFiles=new HashSet<File>();
    File[] dirs=dir.listFiles(dirFilter);
    innerFiles.addAll(Arrays.asList(dir.listFiles(fileFilter)));
    for(File innerDir:dirs){
      innerFiles.addAll(getInnerFiles(innerDir));
    }
    return innerFiles;
  }
 
}
TOP

Related Classes of com.google.gwt.maeglin89273.game.mengine.rebind.AssetsBundleGenerator

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.