Package juzu.plugin.less.impl

Source Code of juzu.plugin.less.impl.LessMetaModelPlugin

/*
* Copyright 2013 eXo Platform SAS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package juzu.plugin.less.impl;

import juzu.impl.common.Name;
import juzu.impl.plugin.module.metamodel.ModuleMetaModel;
import juzu.impl.plugin.module.metamodel.ModuleMetaModelPlugin;
import juzu.impl.metamodel.AnnotationKey;
import juzu.impl.metamodel.AnnotationState;
import juzu.impl.compiler.BaseProcessor;
import juzu.impl.compiler.Message;
import juzu.impl.compiler.ProcessingException;
import juzu.impl.compiler.ElementHandle;
import juzu.impl.compiler.MessageCode;
import juzu.impl.compiler.ProcessingContext;
import juzu.impl.common.Logger;
import juzu.impl.common.Path;
import juzu.impl.common.Tools;
import juzu.plugin.less.Less;
import juzu.plugin.less.impl.lesser.Compilation;
import juzu.plugin.less.impl.lesser.Failure;
import juzu.plugin.less.impl.lesser.JSContext;
import juzu.plugin.less.impl.lesser.LessError;
import juzu.plugin.less.impl.lesser.Lesser;
import juzu.plugin.less.impl.lesser.Result;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.PackageElement;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
public class LessMetaModelPlugin extends ModuleMetaModelPlugin {

  /** . */
  public static final MessageCode COMPILATION_ERROR = new MessageCode(
    "LESS_COMPILATION_ERROR",
    "%1$s in %2$s on line %3$s, column %4$s:\n%5$s");

  /** . */
  public static final MessageCode MALFORMED_PATH = new MessageCode("LESS_MALFORMED_PATH", "The resource path %1$s is malformed");

  /** . */
  static final Logger log = BaseProcessor.getLogger(LessMetaModelPlugin.class);

  /** . */
  private HashMap<Name, AnnotationState> annotations;

  public LessMetaModelPlugin() {
    super("less");
  }

  @Override
  public void init(ModuleMetaModel metaModel) {
    annotations = new HashMap<Name, AnnotationState>();
  }

  @Override
  public Set<Class<? extends java.lang.annotation.Annotation>> init(ProcessingContext env) {
    return Collections.<Class<? extends java.lang.annotation.Annotation>>singleton(Less.class);
  }

  @Override
  public void processAnnotationAdded(ModuleMetaModel metaModel, AnnotationKey key, AnnotationState added) {
    Name pkg = key.getElement().getPackageName();
    log.info("Adding less annotation for package " + pkg);
    annotations.put(pkg, added);
  }

  @Override
  public void processAnnotationRemoved(ModuleMetaModel metaModel, AnnotationKey key, AnnotationState removed) {
    Name pkg = key.getElement().getPackageName();
    log.info("Removing less annotation for package " + pkg);
    annotations.remove(pkg);
  }

  @Override
  public void postActivate(ModuleMetaModel metaModel) {
    annotations = new HashMap<Name, AnnotationState>();
  }

  @Override
  public void prePassivate(ModuleMetaModel metaModel) {
    // First clear annotation map
    HashMap<Name, AnnotationState> clone = annotations;
    annotations = null;

    //
    for (Map.Entry<Name, AnnotationState> entry : clone.entrySet()) {
      AnnotationState annotation = entry.getValue();
      Name pkg = entry.getKey();
      ProcessingContext env = metaModel.processingContext;
      ElementHandle.Package pkgHandle = ElementHandle.Package.create(pkg);
      PackageElement pkgElt = env.get(pkgHandle);
      Boolean minify = (Boolean)annotation.get("minify");
      List<String> resources = (List<String>)annotation.get("value");

      // WARNING THIS IS NOT CORRECT BUT WORK FOR NOW
      AnnotationMirror annotationMirror = Tools.getAnnotation(pkgElt, Less.class.getName());

      //
      log.info("Handling less annotation for package " + pkg + ": minify=" + minify + " resources=" + resources);

      //
      if (resources != null && resources.size() > 0) {

        // For now we use the hardcoded assets package
        Name assetPkg = pkg.append("assets");

        //
        CompilerLessContext clc = new CompilerLessContext(env, pkgHandle, assetPkg);

        //
        for (String resource : resources) {
          log.info("Processing declared resource " + resource);

          //
          Path path;
          try {
            path = Path.parse(resource);
          }
          catch (IllegalArgumentException e) {
            throw MALFORMED_PATH.failure(pkgElt, annotationMirror, resource).initCause(e);
          }

          //
          Path.Absolute to = assetPkg.resolve(path.as("css"));
          log.info("Resource " + resource + " destination resolved to " + to);

          //
          Lesser lesser;
          Result result;
          try {
            lesser = new Lesser(JSContext.create());
            result = lesser.compile(clc, resource, Boolean.TRUE.equals(minify));
          }
          catch (Exception e) {
            log.info("Unexpected exception", e);
            throw new UnsupportedOperationException(e);
          }

          //
          if (result instanceof Compilation) {
            try {
              log.info("Resource " + resource + " compiled about to write on disk as " + to);
              Compilation compilation = (Compilation)result;
              FileObject fo = env.createResource(StandardLocation.CLASS_OUTPUT, to);
              Writer writer = fo.openWriter();
              try {
                writer.write(compilation.getValue());
              }
              finally {
                Tools.safeClose(writer);
              }
            }
            catch (IOException e) {
              log.info("Resource " + to + " could not be written on disk", e);
            }
          }
          else {
            Failure failure = (Failure)result;
            LinkedList<LessError> errors = failure.getErrors();
            ArrayList<Message> messages = new ArrayList<Message>(errors.size());
            StringBuilder sb = new StringBuilder();
            for (LessError error : errors) {
              String text = error.message != null ? error.message : "There is an error in your .less file";
              int index = error.line - (error.extract.length - 1) / 2;
              for (String line : error.extract) {
                sb.append("[").append(index).append("]");
                sb.append(index == error.line ? " -> " : "    ");
                sb.append(line).append("\n");
                index++;
              }
              Message msg = new Message(COMPILATION_ERROR,
                text,
                error.src,
                error.line,
                error.column + 1,
                sb);
              log.info(msg.toDisplayString());
              messages.add(msg);
            }
            throw new ProcessingException(pkgElt, annotationMirror, messages);
          }
        }
      }
    }
  }
}
TOP

Related Classes of juzu.plugin.less.impl.LessMetaModelPlugin

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.