Dateiverwaltung für die WebBox
ulrich
2021-01-06 ef1b11d43280a61e37a7c4cbab2271c61664e601
src/java/de/uhilger/filecms/api/CompileService.java
@@ -18,9 +18,11 @@
package de.uhilger.filecms.api;
import de.uhilger.filecms.data.CompilerIssue;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -35,6 +37,9 @@
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.apache.commons.io.FileUtils;
import org.apache.tomcat.util.log.SystemLogHandler;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
/**
 *
@@ -42,6 +47,91 @@
public class CompileService extends Api {
  
  private static final Logger logger = Logger.getLogger(CompileService.class.getName());
  public String antBuild(String relPath) {
    // Create a stream to hold the output
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos);
    // IMPORTANT: Save the old System.out!
    PrintStream old = System.out;
    PrintStream err = System.err;
    // Tell Java to use your special stream
    System.setOut(ps);
    System.setErr(ps);
    File targetDir = getTargetDir(relPath); // App-Ordner
    StringBuilder sb = new StringBuilder();
    sb.append("Ant build ist noch nicht implementiert.");
    sb.append("<br/>");
    sb.append("targetDir: ");
    sb.append(targetDir.getAbsolutePath());
    File buildFile = new File(targetDir, "build.xml");
    Project p = new Project();
    //p.setName("FileCms Build");
    FileCmsBuildListener listener = new FileCmsBuildListener();
    p.addBuildListener(listener);
    p.setUserProperty("ant.file", buildFile.getAbsolutePath());
    p.init();
    ProjectHelper helper = ProjectHelper.getProjectHelper();
    p.addReference("ant.projectHelper", helper);
    helper.parse(p, buildFile);
    p.executeTarget(p.getDefaultTarget());
    sb.append("<br/>");
    sb.append(listener.getOutput());
    // Print some output: goes to your special stream
    //System.out.println("Foofoofoo!");
    // Put things back
    System.out.flush();
    System.err.flush();
    System.setOut(old);
    System.setErr(err);
    // Show what happened
    //System.out.println("Here: " + baos.toString());
    sb.append("<br/>");
    sb.append(baos.toString());
    return sb.toString();
  }
  /**
   * Annahme: relPath zeigt auf einen Ordner, in dem ein build-Ordner die
   * fertigen Klassen und ein web-Ordner die Struktur mit WEB-INF
   * enthaelt.
   *
   * @param relPath  der relative Pfad, der auf den App-Ordner verweist
   * @return
   */
  public String buildApp(String relPath) {
    String result = "ok";
    try {
      File targetDir = getTargetDir(relPath); // App-Ordner
      File classesDir = new File(targetDir, "web/WEB-INF/classes");
      if(classesDir.exists()) {
        FileUtils.deleteDirectory(classesDir);
      }
      classesDir.mkdirs();
      File buildDir = new File(targetDir, "build/");
      File[] files = buildDir.listFiles();
      for(int i = 0; i < files.length; i++) {
        if(files[i].isDirectory()) {
          FileUtils.copyDirectoryToDirectory(files[i], classesDir);
        } else {
          FileUtils.copyFileToDirectory(files[i], classesDir);
        }
      }
    } catch(Exception ex) {
      logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
    }
    return result;
  }
    
  public List<CompilerIssue> compileAll(String relPath) {
    logger.fine(relPath);
@@ -55,16 +145,9 @@
      StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
      Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
      
      File buildDir = new File(targetDir.getParentFile(), "build");
      final Iterable<String> options = Arrays.asList(new String[]{"-Xlint",
                    /*"-cp", project.getClassPath(),*/
                    /*
                      ausgehend von src eins hoeher, dann nach build
                    */
                    "-d", buildDir.getAbsolutePath()
                    });
      FileUtils.deleteDirectory(buildDir);
      buildDir.mkdir();
      final Iterable<String> options = buildOptions(targetDir);
      compiler.getTask(null, null, diagnostics, options, null, compilationUnits).call();
      fileManager.close();
      collectResults(diagnostics, compilerIssues, relPath);
@@ -124,6 +207,19 @@
  
  }
  
  public class JarFileFilter implements FileFilter {
    @Override
    public boolean accept(File pathname) {
      boolean doAccept = false;
      if(pathname.getName().endsWith(".jar")) {
        doAccept = true;
      }
      return doAccept;
    }
  }
  /**
   * 
   * @param relPath
@@ -149,24 +245,69 @@
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
    Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(files);    
    if( mode.equals("1")) {
      final Iterable<String> options = Arrays.asList(new String[]{"-Xlint",
              /*"-cp", project.getClassPath(),*/
              "-d", targetDir.getAbsolutePath()
              });
      compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits1).call();
    } else {
      compiler.getTask(null, null, diagnostics, null, null, compilationUnits1).call();
    }
    final Iterable<String> options = buildOptions(targetDir);
    compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits1).call();
    fileManager.close();
    List<CompilerIssue> compilerIssues = new ArrayList();
    collectResults(diagnostics, compilerIssues, relPath);
    return compilerIssues;
  }
  private final Iterable<String> buildOptions(File targetDir) {
      String cbase = getCatalinaBase(getServletContext());
      File lib = new File(cbase, "lib");
      String cp = "";
      cp = buildCPFromDir(cp, lib);
      logger.fine(lib.getAbsolutePath());
      logger.fine(cp);
      /*
        wegen dieser Funktion MUSS alles in 'src' liegen
      */
      File srcDir = targetDir;
      while(!srcDir.getName().endsWith("src")) {
        srcDir = srcDir.getParentFile();
      }
      File appDir = srcDir.getParentFile();
      File appLibDir = new File(appDir, "web/WEB-INF/lib");
      cp = buildCPFromDir(cp, appLibDir);
      logger.fine(cp);
      /*
        ausgehend von src eins hoeher, dann nach build
      */
      File buildDir = new File(appDir, "build");
      final Iterable<String> options = Arrays.asList(new String[]{"-Xlint",
                    "-cp", cp,
                    "-d", buildDir.getAbsolutePath()
                    });
      try {
        FileUtils.deleteDirectory(buildDir);
        buildDir.mkdir();
      } catch (IOException ex) {
        logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
      }
      return options;
  }
  /*
  -classpath $JLIB/jettison-1.3.3.jar:$JLIB/xstream-1.4.7.jar
  */
  private String buildCPFromDir(String cp, File dir) {
    StringBuffer buf = new StringBuffer(cp);
    File[] files = dir.listFiles(new JarFileFilter());
    for(int i = 0; i < files.length; i++) {
      if(buf.length() > 0) {
        buf.append(File.pathSeparatorChar);
      }
      //buf.append("\"");
      buf.append(files[i].getAbsolutePath());
      //buf.append("\"");
    }
    return buf.toString();
  }
}
/*
 Beispeil fuer einen dynamischen Compiler-Aufruf