Package com.darylteo.gradle.javassist.tasks

Source Code of com.darylteo.gradle.javassist.tasks.TransformationAction$LoaderAction

package com.darylteo.gradle.javassist.tasks;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import javassist.build.IClassTransformer;
import org.gradle.api.GradleException;
import org.gradle.api.internal.file.CopyActionProcessingStreamAction;
import org.gradle.api.internal.file.copy.CopyAction;
import org.gradle.api.internal.file.copy.CopyActionProcessingStream;
import org.gradle.api.internal.file.copy.FileCopyDetailsInternal;
import org.gradle.api.internal.tasks.SimpleWorkResult;
import org.gradle.api.tasks.WorkResult;

import java.io.*;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
* Created by dteo on 30/05/2014.
*/
class TransformationAction implements CopyAction {

  private File destinationDir;
  private IClassTransformer transformation;

  private List<File> sources = new LinkedList<File>();
  private Collection<File> classpath = new LinkedList<File>();

  public TransformationAction(File destinationDir, Collection<File> sources, Collection<File> classpath, IClassTransformer transformation) {
    this.destinationDir = destinationDir;
    this.sources.addAll(sources);
    this.classpath.addAll(classpath);
    this.transformation = transformation;
  }

  @Override
  public WorkResult execute(CopyActionProcessingStream stream) {
    try {
      final ClassPool pool = createPool();
      final LoaderAction action = new LoaderAction(pool, destinationDir, this.transformation);

      stream.process(action);
    } catch (Exception e) {
      throw new GradleException("Could not execute transformation", e);
    }

    return new SimpleWorkResult(true);
  }

  private ClassPool createPool() throws NotFoundException {
    final ClassPool pool = new ClassPool(true);

    // set up the classpath for the classpool
    if (classpath != null) {
      for (File f : this.classpath) {
        pool.appendClassPath(f.toString());
      }
    }

    // add the files to process
    for (File f : this.sources) {
      pool.appendClassPath(f.toString());
    }
    return pool;
  }

  // preloads all class files into the classpool and stores a list of class names
  private class LoaderAction implements CopyActionProcessingStreamAction {
    private final ClassPool pool;
    private final String destinationDir;
    private IClassTransformer transformation;

    public LoaderAction(ClassPool pool, File destinationDir, IClassTransformer transformation) {
      this.pool = pool;
      this.destinationDir = destinationDir.toString();

      this.transformation = transformation;
    }

    @Override
    public void processFile(FileCopyDetailsInternal details) {
      try {
        if (!details.isDirectory()) {
          CtClass clazz = loadClassFile(details.getFile());

          if (this.transformation.shouldTransform(clazz)) {
            clazz.defrost();
            this.transformation.applyTransformations(clazz);
            clazz.writeFile(this.destinationDir);
          }
        }
      } catch (Exception e) {
        throw new GradleException("An error occurred while trying to process class file ", e);
      }
    }

    private CtClass loadClassFile(File classFile) throws IOException {
      // read the file first to get the classname
      // much easier than trying to extrapolate from the filename (i.e. with anonymous classes etc.)
      InputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(classFile)));
      CtClass clazz = pool.makeClass(stream);

      stream.close();

      return clazz;
    }
  }
}
TOP

Related Classes of com.darylteo.gradle.javassist.tasks.TransformationAction$LoaderAction

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.