Package sizzle.compiler

Source Code of sizzle.compiler.SizzleCompiler

package sizzle.compiler;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

import org.antlr.stringtemplate.StringTemplateGroup;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
import org.scannotation.ClasspathUrlFinder;

import sizzle.parser.ParseException;
import sizzle.parser.SizzleParser;
import sizzle.parser.syntaxtree.Start;

public class SizzleCompiler {
  private static Logger LOG = Logger.getLogger(SizzleCompiler.class);

  private static final List<String> find(final File f) {
    final List<String> l = new ArrayList<String>();

    if (f.isDirectory()) {
      for (final File g : f.listFiles())
        l.addAll(SizzleCompiler.find(g));
    } else {
      l.add(f.toString());
    }

    return l;
  }

  private static final void delete(final File f) throws IOException {
    if (f.isDirectory())
      for (final File g : f.listFiles())
        SizzleCompiler.delete(g);

    if (!f.delete())
      throw new IOException("unable to delete file " + f);
  }

  private static void write(final InputStream in, final OutputStream out) throws IOException {
    final byte[] b = new byte[4096];
    int len;
    while ((len = in.read(b)) > 0)
      out.write(b, 0, len);
  }

  public static void main(final String[] args) throws IOException, ParseException {
    // parse the command line options
    final Options options = new Options();
    options.addOption("h", "hadoop-base", true, "base directory for Hadoop installation");
    options.addOption("l", "libs", true, "extra jars to be compiled into the jar");
    options.addOption("i", "in", true, "file to be compiled");
    options.addOption("o", "out", true, "the name of the resulting jar");
    options.addOption("n", "name", true, "the name of the job");

    CommandLine cl;
    try {
      cl = new PosixParser().parse(options, args);
    } catch (final org.apache.commons.cli.ParseException e) {
      System.err.println(e.getMessage());

      final HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("SizzleCompiler", options);

      return;
    }

    // get the base of the hadoop installation for compilation purposes
    String hadoopBase;
    if (cl.hasOption('h')) {
      hadoopBase = cl.getOptionValue('h');
    } else {
      System.err.println("missing required option `hadoop-base'");

      final HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("SizzleCompiler", options);

      return;
    }

    // find the location of the jar this class is in
    final String path = ClasspathUrlFinder.findClassBase(SizzleCompiler.class).getPath();
    // find the location of the Sizzle distribution
    final String root = new File(path.substring(path.indexOf(':') + 1, path.indexOf('!'))).getParentFile().getParent();

    // get the filename of the sizzle program we will be compiling
    File in;
    if (cl.hasOption('i'))
      in = new File(cl.getOptionValue('i'));
    else {
      System.err.println("missing required option `in'");

      final HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("SizzleCompiler", options);

      return;
    }
   
    final String filename = in.getName();

    final String name = filename.substring(0, filename.lastIndexOf('.'));

    // get the filename of the jar we will be writing
    String out;
    if (cl.hasOption('o'))
      out = cl.getOptionValue('o');
    else
      out = filename.substring(0, filename.indexOf('.')) + ".jar";

    // check filename for sanity
    if (!(filename.endsWith(".sizzle") || filename.endsWith(".szl")))
      throw new RuntimeException("unsupported extension for " + in.getAbsolutePath());

    // make the output directory
    final File dir = new File(new File(System.getProperty("java.io.tmpdir")), UUID.randomUUID().toString());
    final File dirfile = new File(dir.getPath() + File.separatorChar + "sizzle");
    if (!dirfile.mkdirs())
      throw new IOException("unable to mkdir " + dirfile);

    final List<URL> libs = new ArrayList<URL>();
    if (cl.hasOption('l'))
      for (final String lib : cl.getOptionValues('l'))
        libs.add(new File(lib).toURI().toURL());

    final BufferedOutputStream o = new BufferedOutputStream(new FileOutputStream(dirfile.toString() + File.separatorChar + name + ".java"));
    try {
      final TypeCheckingVisitor typeChecker = new TypeCheckingVisitor();

      final StringTemplateGroup superStg;
      final BufferedReader t = new BufferedReader(new InputStreamReader(CodeGeneratingVisitor.class.getClassLoader().getResource("SizzleJava.stg").openStream()));
      try {
        superStg = new StringTemplateGroup(t);
      } finally {
        t.close();
      }
     
      final StringTemplateGroup stg;
      final BufferedReader s = new BufferedReader(new InputStreamReader(CodeGeneratingVisitor.class.getClassLoader().getResource("SizzleJavaHadoop.stg").openStream()));
      try {
        stg = new StringTemplateGroup(s);
        stg.setSuperGroup(superStg);
      } finally {
        s.close();
      }

      final CodeGeneratingVisitor codeGenerator = new CodeGeneratingVisitor(name, stg);

      final SymbolTable st = new SymbolTable(libs);

      final BufferedReader r = new BufferedReader(new FileReader(in));
     
      try {
        new SizzleParser(r);

        final Start start = SizzleParser.Start();

        typeChecker.visit(start, st);

        final String src = codeGenerator.visit(start, st);

        o.write(src.getBytes());
      } finally {
        r.close();
      }
    } finally {
      o.close();
    }

    final String runtime = root + "/dist/sizzle-runtime.jar";
    final StringBuilder classPath = new StringBuilder(runtime);
    for (final File f : new File(hadoopBase).listFiles())
      if (Pattern.compile("hadoop-[a-z]+-[\\d+\\.]+\\.jar").matcher(f.getName()).matches())
        classPath.append(":" + f);
    for (final File f : new File(hadoopBase + File.separatorChar + "lib").listFiles())
      if (f.toString().endsWith(".jar"))
        classPath.append(":" + f);

    final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    for (final String f1 : SizzleCompiler.find(dir)) {
      SizzleCompiler.LOG.info("compiling " + f1);
      if (f1.toString().endsWith(".java"))
        if (compiler.run(null, null, null, "-cp", classPath.toString(), f1.toString()) != 0)
          throw new RuntimeException("compile failed");
    }

    final JarOutputStream jar = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(new File(out))));
    try {
      final int sub = dir.toString().length() + 1;
      for (final String f : SizzleCompiler.find(dir)) {
        SizzleCompiler.LOG.info("adding " + f + " to " + out);
        jar.putNextEntry(new ZipEntry(f.substring(sub)));

        final InputStream inx = new BufferedInputStream(new FileInputStream(f));
        try {
          SizzleCompiler.write(inx, jar);
        } finally {
          inx.close();
        }

        jar.closeEntry();
      }

      final List<String> libsJars = new ArrayList<String>();
      libsJars.add(runtime);
      if (cl.hasOption('l'))
        libsJars.addAll(Arrays.asList(cl.getOptionValues('l')));
      for (final String lib : libsJars) {
        final File f = new File(lib);

        SizzleCompiler.LOG.info("adding lib/" + f.getName() + " to " + out);
        jar.putNextEntry(new JarEntry("lib" + File.separatorChar + f.getName()));
        final InputStream inx = new BufferedInputStream(new FileInputStream(f));
        try {
          SizzleCompiler.write(inx, jar);
        } finally {
          inx.close();
        }
      }
    } finally {
      jar.close();
    }

    SizzleCompiler.delete(dir);
  }
}
TOP

Related Classes of sizzle.compiler.SizzleCompiler

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.