Package com.github.sommeri.less4j.core

Source Code of com.github.sommeri.less4j.core.ThreadUnsafeLessCompiler

package com.github.sommeri.less4j.core;

import java.io.File;
import java.net.URI;
import java.net.URL;
import java.util.Collection;

import com.github.sommeri.less4j.Less4jException;
import com.github.sommeri.less4j.LessCompiler;
import com.github.sommeri.less4j.LessSource;
import com.github.sommeri.less4j.LessSource.CannotReadFile;
import com.github.sommeri.less4j.LessSource.FileNotFound;
import com.github.sommeri.less4j.core.ast.ASTCssNode;
import com.github.sommeri.less4j.core.ast.StyleSheet;
import com.github.sommeri.less4j.core.compiler.LessToCssCompiler;
import com.github.sommeri.less4j.core.parser.ANTLRParser;
import com.github.sommeri.less4j.core.parser.ASTBuilder;
import com.github.sommeri.less4j.core.problems.GeneralProblem;
import com.github.sommeri.less4j.core.problems.ProblemsHandler;
import com.github.sommeri.less4j.platform.Constants;
import com.github.sommeri.less4j.utils.CssPrinter;
import com.github.sommeri.less4j.utils.PrintUtils;
import com.github.sommeri.less4j.utils.URIUtils;

public class ThreadUnsafeLessCompiler implements LessCompiler {
  private ProblemsHandler problemsHandler;
  private ASTBuilder astBuilder;
  private LessToCssCompiler compiler;

  private ANTLRParser parser = new ANTLRParser();

  @Override
  public CompilationResult compile(String lessContent) throws Less4jException {
    return compile(new LessSource.StringSource(lessContent), null);
  }

  @Override
  public CompilationResult compile(String lessContent, Configuration options) throws Less4jException {
    return compile(new LessSource.StringSource(lessContent), options);
  }

  @Override
  public CompilationResult compile(File lessFile) throws Less4jException {
    LessSource.FileSource lessSource = new LessSource.FileSource(lessFile);
    return compile(lessSource, null);
  }

  @Override
  public CompilationResult compile(File lessFile, Configuration options) throws Less4jException {
    return compile(new LessSource.FileSource(lessFile, "utf-8"), options);
  }

  @Override
  public CompilationResult compile(URL lessURL) throws Less4jException {
    return compile(new LessSource.URLSource(lessURL));
  }

  @Override
  public CompilationResult compile(URL lessURL, Configuration options) throws Less4jException {
    return compile(new LessSource.URLSource(lessURL), options);
  }

  @Override
  public CompilationResult compile(LessSource source) throws Less4jException {
    return compile(source, new Configuration());
  }

  @Override
  public CompilationResult compile(LessSource source, Configuration options) throws Less4jException {
    if (options==null)
      options = new Configuration();
     
    problemsHandler = new ProblemsHandler();
    astBuilder = new ASTBuilder(problemsHandler);
    compiler = new LessToCssCompiler(problemsHandler, options);
    CompilationResult compilationResult = doCompile(source, options);
    if (problemsHandler.hasErrors()) {
      throw new Less4jException(problemsHandler.getErrors(), compilationResult);
    }
    return compilationResult;
  }

  private CompilationResult doCompile(LessSource source, Configuration options) throws Less4jException {
    ANTLRParser.ParseResult result = toAntlrTree(source);
    StyleSheet lessStyleSheet = astBuilder.parse(result.getTree());
    ASTCssNode cssStyleSheet = compiler.compileToCss(lessStyleSheet, source, options);

    CompilationResult compilationResult = createCompilationResult(cssStyleSheet, source, compiler.getImportedsources(), options);
    return compilationResult;
  }

  private ANTLRParser.ParseResult toAntlrTree(LessSource source) throws Less4jException {
    ANTLRParser.ParseResult result;
    try {
      result = parser.parseStyleSheet(source.getContent(), source);
    } catch (FileNotFound ex) {
      throw new Less4jException(new GeneralProblem("The file " + source + " does not exists."), new CompilationResult(null));
    } catch (CannotReadFile ex) {
      throw new Less4jException(new GeneralProblem("Cannot read the file " + source + "."), new CompilationResult(null));
    }

    if (result.hasErrors()) {
      CompilationResult compilationResult = new CompilationResult("Errors during parsing phase, partial result is not available.");
      throw new Less4jException(result.getErrors(), compilationResult);
    }
    return result;
  }

  private CompilationResult createCompilationResult(ASTCssNode cssStyleSheet, LessSource lessSource, Collection<LessSource> additionalSourceFiles, Configuration options) {
    LessSource cssDestination = options == null ? null : options.getCssResultLocation();
    if (cssDestination==null) {
      String guessedCssName = URIUtils.changeSuffix(lessSource.getName(), Constants.CSS_SUFFIX);
      URI guessedURI = URIUtils.changeSuffix(lessSource.getURI(), Constants.CSS_SUFFIX);
      cssDestination = new LessSource.StringSource("", guessedCssName, guessedURI);
    }
   
    CssPrinter builder = new CssPrinter(lessSource, cssDestination, additionalSourceFiles, options);
    builder.append(cssStyleSheet);
    StringBuilder css = builder.toCss();
    String sourceMap = builder.toSourceMap();
   
    handleSourceMapLink(cssStyleSheet, css, options, lessSource, sourceMap);

    CompilationResult compilationResult = new CompilationResult(css.toString(), sourceMap, problemsHandler.getWarnings());
    return compilationResult;
  }

  private void handleSourceMapLink(ASTCssNode cssAst, StringBuilder css, Configuration options, LessSource source, String sourceMap) {
    String cssResultLocation = getCssResultLocationName(options, source);
    LessCompiler.SourceMapConfiguration sourceMapConfiguration = options.getSourceMapConfiguration();
    if (!sourceMapConfiguration.shouldLinkSourceMap() && !sourceMapConfiguration.isInline())
      return;
   
    if (!sourceMapConfiguration.isInline() && cssResultLocation==null) {
      problemsHandler.warnSourceMapLinkWithoutCssResultLocation(cssAst);
      return ;
    }

    addNewLine(css);

    String commentText;
    String encodingCharset = sourceMapConfiguration.getEncodingCharset();
    if (sourceMapConfiguration.isInline()) {
      String encodedSourceMap = PrintUtils.base64Encode(sourceMap, encodingCharset, problemsHandler, cssAst);
      commentText = "/*# sourceMappingURL=data:application/json;base64," + encodedSourceMap + " */";
    } else {
      //compose linking comment
      String url = sourceMapConfiguration.getSourceMapNameGenerator().generateUrl(cssResultLocation);
      String encodedUrl = PrintUtils.urlEncode(url, encodingCharset, problemsHandler, cssAst);
      commentText = "/*# sourceMappingURL=" + encodedUrl + " */";
    }

    css.append(commentText).append("\n");
  }

  private void addNewLine(StringBuilder css) {
    if (css==null)
      return ;
   
    int length = css.length();
    if (length==0) {
      css.append("\n");
      return ;
    }
    String endingSymbol = css.substring(length-1);
    if ("\n".equals(endingSymbol))
      return ;
     
    css.append("\n");
  }

  private String getCssResultLocationName(Configuration options, LessSource source) {
    LessSource location = options.getCssResultLocation();
    String name = location == null ? null : location.getName();

    if (name == null)
      name = URIUtils.changeSuffix(source.getName(), Constants.CSS_SUFFIX);

    return name;
  }

}
TOP

Related Classes of com.github.sommeri.less4j.core.ThreadUnsafeLessCompiler

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.