Package de.matrixweb.smaller.closure

Source Code of de.matrixweb.smaller.closure.ClosureProcessor$LoggerOutputStream

package de.matrixweb.smaller.closure;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.javascript.jscomp.ClosureCodingConvention;
import com.google.javascript.jscomp.CompilationLevel;
import com.google.javascript.jscomp.Compiler;
import com.google.javascript.jscomp.CompilerOptions;
import com.google.javascript.jscomp.Result;
import com.google.javascript.jscomp.SourceFile;
import com.google.javascript.jscomp.SourceMap.DetailLevel;
import com.google.javascript.jscomp.SourceMap.Format;

import de.matrixweb.smaller.common.SmallerException;
import de.matrixweb.smaller.resource.Processor;
import de.matrixweb.smaller.resource.ProcessorUtil;
import de.matrixweb.smaller.resource.ProcessorUtil.ProcessorCallback;
import de.matrixweb.smaller.resource.Resource;
import de.matrixweb.smaller.resource.Type;
import de.matrixweb.vfs.VFS;

/**
* @author marwol
*/
public class ClosureProcessor implements Processor {

  private static final Logger LOGGER = LoggerFactory
      .getLogger(ClosureProcessor.class);

  private static final LoggerOutputStream LOGGER_OUTPUT_STREAM = new LoggerOutputStream();

  /**
   * @see de.matrixweb.smaller.resource.Processor#supportsType(de.matrixweb.smaller.resource.Type)
   */
  @Override
  public boolean supportsType(final Type type) {
    return type == Type.JS;
  }

  /**
   * @see de.matrixweb.smaller.resource.Processor#execute(de.matrixweb.vfs.VFS,
   *      de.matrixweb.smaller.resource.Resource, java.util.Map)
   */
  @Override
  public Resource execute(final VFS vfs, final Resource resource,
      final Map<String, Object> options) throws IOException {
    return ProcessorUtil.process(vfs, resource, "js", new ProcessorCallback() {
      @Override
      public void call(final Reader reader, final Writer writer)
          throws IOException {
        compile(reader, writer, options);
      }
    });
  }

  /**
   * @see de.matrixweb.smaller.resource.Processor#dispose()
   */
  @Override
  public void dispose() {
  }

  private void compile(final Reader reader, final Writer writer,
      final Map<String, Object> options) throws IOException {
    Compiler.setLoggingLevel(Level.SEVERE);
    final Compiler compiler = new Compiler(new PrintStream(
        LOGGER_OUTPUT_STREAM, false, "UTF-8"));
    final CompilerOptions compilerOptions = new CompilerOptions();
    CompilationLevel.SIMPLE_OPTIMIZATIONS
        .setOptionsForCompilationLevel(compilerOptions);
    compilerOptions.setCodingConvention(new ClosureCodingConvention());
    if (isSourceMappingEnabled(options)) {
      compilerOptions.setSourceMapFormat(Format.V3);
      compilerOptions.setSourceMapDetailLevel(DetailLevel.ALL);
    }
    setupOptions(compilerOptions, options);
    compiler.initOptions(compilerOptions);

    final Result result = compiler.compile(SourceFile.fromCode("externs", ""),
        SourceFile.fromReader("source.js", reader), compilerOptions);
    if (result.success) {
      writer.write(compiler.toSource());
    } else {
      if (result.errors.length > 0) {
        throw new SmallerException("Closure Failed: "
            + result.errors[0].toString());
      }
    }
  }

  private boolean isSourceMappingEnabled(final Map<String, Object> options) {
    final Object value = options.get("source-maps");
    return Boolean.valueOf(value != null ? value.toString() : "false");
  }

  private void setupOptions(final CompilerOptions co,
      final Map<String, Object> map) {
    for (final Entry<String, Object> entry : map.entrySet()) {
      final String name = entry.getKey();
      if (!"version".equals(name)) {
        try {
          final Field field = co.getClass().getField(name);
          field.set(co, map.get(name));
        } catch (final Exception e) {
          LOGGER.warn("Failed to set compiler-option '" + name + "' to '"
              + map.get(name) + "'");
        }
      }
    }
  }

  private static class LoggerOutputStream extends OutputStream {

    private static final Logger LOGGER = LoggerFactory
        .getLogger(ClosureProcessor.class);

    private final StringBuilder sb = new StringBuilder();

    /**
     * @see java.io.OutputStream#write(int)
     */
    @Override
    public void write(final int b) throws IOException {
      this.sb.append((char) b);
      if ((char) b == '\n') {
        print();
      }
    }

    /**
     * @see java.io.OutputStream#flush()
     */
    @Override
    public void flush() throws IOException {
      print();
      super.flush();
    }

    /**
     * @see java.io.OutputStream#close()
     */
    @Override
    public void close() throws IOException {
      print();
      super.close();
    }

    private void print() {
      if (this.sb.length() > 0) {
        LOGGER.info(this.sb.toString());
        this.sb.setLength(0);
      }
    }

  }

}
TOP

Related Classes of de.matrixweb.smaller.closure.ClosureProcessor$LoggerOutputStream

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.