All Downloads are FREE. Search and download functionalities are using the official Maven repository.

juzu.impl.runtime.ModuleRuntime Maven / Gradle / Ivy

/*
 * 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.runtime;

import juzu.impl.common.Completion;
import juzu.impl.common.LiveClassLoader;
import juzu.impl.common.ParentJarClassLoader;
import juzu.impl.common.Logger;
import juzu.impl.compiler.*;
import juzu.impl.compiler.Compiler;
import juzu.impl.fs.FileSystemScanner;
import juzu.impl.fs.Filter;
import juzu.impl.fs.Snapshot;
import juzu.impl.fs.spi.ReadFileSystem;
import juzu.impl.fs.spi.ram.RAMFileSystem;
import juzu.impl.fs.spi.url.URLFileSystem;
import juzu.processor.MainProcessor;

import java.io.IOException;
import java.net.URL;

/**
 * The module life cycle.
 *
 * @author Julien Viet
 */
public abstract class ModuleRuntime {

  /** . */
  protected final Logger logger;

  protected ModuleRuntime(Logger logger) {
    this.logger = logger;
  }

  /**
   * Refresh the module.
   *
   * @param recompile true if recompilation can occur
   * @return true when the refresh operation has triggered changes
   */
  public abstract Completion refresh(boolean recompile) ;

  /**
   * Returns the module classloader.
   *
   * @return the module classloader
   */
  public abstract ClassLoader getClassLoader();

  /**
   * Returns the module classes.
   *
   * @return the module classes
   */
  public abstract ReadFileSystem getClasses();

  /**
   * Returns the module dynamicity.
   *
   * @return the module dynamicity
   */
  public abstract boolean isDynamic();

  public static class Dynamic extends ModuleRuntime {

    /** . */
    private final ClassLoader baseClassLoader;

    /** . */
    private URLFileSystem classPath;

    /** . */
    private FileSystemScanner scanner;

    /** . */
    private Snapshot snapshot;

    /** . */
    private ClassLoader classLoader;

    /** . */
    private ClassLoader classPathLoader;

    /** . */
    private ReadFileSystem classes;

    /** . */
    private boolean failed;

    public Dynamic(Logger logger, ClassLoader baseClassLoader, ReadFileSystem source) {
      super(logger);

      //
      this.classLoader = null;
      this.baseClassLoader = baseClassLoader;
      this.classPathLoader = new ParentJarClassLoader(baseClassLoader);
      this.scanner = FileSystemScanner.createHashing(source);
      this.snapshot = scanner.take();
      this.classPath = null;
      this.failed = false;
    }

    @Override
    public synchronized Completion refresh(boolean recompile) {
      if (!recompile) {
        throw new UnsupportedOperationException("Not yet implemented");
      } else {
        try {
          return Completion.completed(refresh());
        }
        catch (Exception e) {
          return Completion.failed(e);
        }
      }
    }

    private boolean refresh() throws Exception, CompilationException {


      // Lazy initialize
      if (classPath == null) {
        classPath = new URLFileSystem().add(classPathLoader, ClassLoader.getSystemClassLoader().getParent());
      }

      Snapshot next = snapshot.scan();

      //
      if (!failed && !next.hasChanges()) {
        logger.info("No changes detected");
        return false;
      }
      else {
        logger.info("Building application");

        //
        this.failed = true;

        //
        final ReadFileSystem sourcePath = scanner.getFileSystem();

        //
        final RAMFileSystem classOutput = new RAMFileSystem();
        Compiler compiler = Compiler.
            builder().
            sourcePath(sourcePath).
            sourceOutput(classOutput).
            classOutput(classOutput).
            addClassPath(classPath).build();
        compiler.addAnnotationProcessor(new MainProcessor());
        compiler.compile();

        // Copy everything that is not a java source and not already present
        sourcePath.copy(new Filter.Default() {
          @Override
          public boolean acceptFile(S file, String name) throws IOException {
            Iterable names = sourcePath.getNames(file);
            String[] path = classOutput.getPath(names);
            return path == null && !name.endsWith(".java");
          }
        }, classOutput);

        //
        this.classLoader = new LiveClassLoader(new URL[]{classOutput.getURL()}, baseClassLoader);
        this.classes = classOutput;
        this.snapshot = next;
        this.failed = false;

        //
        return true;
      }
    }

    @Override
    public ClassLoader getClassLoader() {
      return classLoader;
    }

    @Override
    public ReadFileSystem getClasses() {
      return classes;
    }

    @Override
    public boolean isDynamic() {
      return true;
    }
  }

  public static class Static

extends ModuleRuntime

{ /** . */ private final ClassLoader classLoader; /** . */ private final ReadFileSystem

classes; public Static(Logger logger, ClassLoader classLoader, ReadFileSystem

classes) { super(logger); // this.classLoader = classLoader; this.classes = classes; } @Override public Completion refresh(boolean recompile) { return Completion.completed(false); } @Override public ClassLoader getClassLoader() { return classLoader; } @Override public ReadFileSystem

getClasses() { return classes; } @Override public boolean isDynamic() { return false; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy