Package juzu.impl.plugin.template.metamodel

Source Code of juzu.impl.plugin.template.metamodel.AbstractEmitter

/*
* 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.impl.plugin.template.metamodel;

import juzu.impl.common.FileKey;
import juzu.impl.compiler.BaseProcessor;
import juzu.impl.template.spi.EmitContext;
import juzu.impl.template.spi.TemplateProvider;
import juzu.impl.common.Logger;
import juzu.impl.common.Path;
import juzu.impl.common.Tools;
import juzu.template.TagHandler;

import javax.lang.model.element.Element;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;

/**
* The template emitter.
*
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
*/
abstract class AbstractEmitter implements Serializable {

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

  /** . */
  final AbstractContainerMetaModel owner;

  /** . */
  private Set<Path.Absolute> emitted;

  /** . */
  private Map<Path.Absolute, FileObject> classCache;

  AbstractEmitter(AbstractContainerMetaModel owner) {
    this.owner = owner;
    this.emitted = new HashSet<Path.Absolute>();
    this.classCache = new HashMap<Path.Absolute, FileObject>();
  }

  void prePassivate() {
    log.info("Evicting cache " + emitted);
    emitted.clear();
    classCache.clear();
  }

  void emit(TemplateMetaModel template, Element[] elements) {
    TemplateProvider<?> provider = owner.resolveTemplateProvider(template.getPath().getExt());
    resolvedQualified(provider, template, elements);
    emitScript(template, provider, elements);
  }

  private void emitScript(final TemplateMetaModel template, final TemplateProvider provider, final Element[] elements) {
    owner.application.getProcessingContext().executeWithin(elements[0], new Callable<Void>() {
      public Void call() throws Exception {

        //
        Path.Absolute path = template.getPath();

        // If it's the cache we do nothing
        if (!emitted.contains(path)) {
          //
          try {
            EmitContext emitCtx = new EmitContext() {

              @Override
              public TagHandler resolveTagHandler(String name) {
                return owner.resolveTagHandler(name);
              }

              @Override
              public void createResource(Path.Absolute path, CharSequence content) throws IOException {
                FileKey key = FileKey.newName(path);
                FileObject scriptFile = owner.application.getProcessingContext().createResource(StandardLocation.CLASS_OUTPUT, key, elements);
                Writer writer = null;
                try {
                  writer = scriptFile.openWriter();
                  writer.append(content);
                  log.info("Generated template script " + path.getCanonical() + " as " + scriptFile.toUri() +
                      " with originating elements " + Arrays.asList(elements));
                }
                finally {
                  Tools.safeClose(writer);
                }
              }
            };

            //
            provider.emit(emitCtx, template.templateModel);

            // Put it in cache
            emitted.add(path);
          }
          catch (Exception e) {
            throw TemplateMetaModel.CANNOT_WRITE_TEMPLATE_SCRIPT.failure(e, template.getPath());
          }
        }
        else {
          log.info("Template " + template.getPath() + " was found in cache");
        }
        return null;
      }
    });
  }

  protected abstract void emitClass(
      TemplateProvider<?> provider,
      TemplateMetaModel template,
      Element[] elements,
      Writer writer) throws IOException;

  private void resolvedQualified(
      TemplateProvider<?> provider,
      TemplateMetaModel template,
      Element[] elements) {

    //
    Path.Absolute path = template.getPath();
    if (classCache.containsKey(path)) {
      log.info("Template class " + path + " was found in cache");
    } else {
      Path.Absolute resolvedPath = owner.resolvePath(path);
      Writer writer = null;
      try {
        FileObject classFile = owner.application.getProcessingContext().createSourceFile(resolvedPath.getName(), elements);
        writer = classFile.openWriter();
        emitClass(provider, template, elements, writer);
        classCache.put(path, classFile);
        log.info("Generated template class " + path + " as " + classFile.toUri() +
            " with originating elements " + Arrays.asList(elements));
      }
      catch (IOException e) {
        e.printStackTrace();
        throw TemplateMetaModel.CANNOT_WRITE_TEMPLATE_CLASS.failure(e, elements[0], path);
      }
      finally {
        Tools.safeClose(writer);
      }
    }
  }
}
TOP

Related Classes of juzu.impl.plugin.template.metamodel.AbstractEmitter

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.