Dateiverwaltung für die WebBox
ulrich
2021-01-03 719f73ea3ea9204585de5487fb83f6d5be97d1ac
commit | author | age
0ac262 1 /*
U 2     Dateiverwaltung - File management in your browser
3     Copyright (C) 2017 Ulrich Hilger, http://uhilger.de
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Affero General Public License as
7     published by the Free Software Foundation, either version 3 of the
8     License, or (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Affero General Public License for more details.
14
15     You should have received a copy of the GNU Affero General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 package de.uhilger.filecms.api;
19
e3043f 20 import de.uhilger.filecms.data.CompilerIssue;
977840 21 import java.io.ByteArrayOutputStream;
0ac262 22 import java.io.File;
72e43d 23 import java.io.FileFilter;
0ac262 24 import java.io.IOException;
977840 25 import java.io.PrintStream;
0ac262 26 import java.util.ArrayList;
U 27 import java.util.Arrays;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Locale;
72e43d 31 import java.util.logging.Level;
0ac262 32 import java.util.logging.Logger;
U 33 import javax.tools.Diagnostic;
34 import javax.tools.DiagnosticCollector;
35 import javax.tools.JavaCompiler;
36 import javax.tools.JavaFileObject;
37 import javax.tools.StandardJavaFileManager;
38 import javax.tools.ToolProvider;
a450f2 39 import org.apache.commons.io.FileUtils;
977840 40 import org.apache.tomcat.util.log.SystemLogHandler;
2e303f 41 import org.apache.tools.ant.Project;
U 42 import org.apache.tools.ant.ProjectHelper;
0ac262 43
U 44 /**
45  *
46  */
72e43d 47 public class CompileService extends Api {
0ac262 48   
U 49   private static final Logger logger = Logger.getLogger(CompileService.class.getName());
7b3372 50   
f59dce 51   public String antBuild(String relPath) {
977840 52     
U 53     // Create a stream to hold the output
54     ByteArrayOutputStream baos = new ByteArrayOutputStream();
55     PrintStream ps = new PrintStream(baos);
56     // IMPORTANT: Save the old System.out!
57     PrintStream old = System.out;
58     PrintStream err = System.err;
59     // Tell Java to use your special stream
60     System.setOut(ps);    
61     System.setErr(ps);
62     
f59dce 63     File targetDir = getTargetDir(relPath); // App-Ordner
U 64     StringBuilder sb = new StringBuilder();
65     sb.append("Ant build ist noch nicht implementiert.");
2e303f 66
f59dce 67     sb.append("<br/>");
U 68     sb.append("targetDir: ");
69     sb.append(targetDir.getAbsolutePath());
2e303f 70     
U 71     File buildFile = new File(targetDir, "build.xml");
72     Project p = new Project();
73     //p.setName("FileCms Build");
74     FileCmsBuildListener listener = new FileCmsBuildListener();
75     p.addBuildListener(listener);
76     p.setUserProperty("ant.file", buildFile.getAbsolutePath());
77     p.init();
78     ProjectHelper helper = ProjectHelper.getProjectHelper();
79     p.addReference("ant.projectHelper", helper);
80     helper.parse(p, buildFile);
81     p.executeTarget(p.getDefaultTarget());  
82     sb.append("<br/>");
83     sb.append(listener.getOutput());
84     
977840 85     
U 86     // Print some output: goes to your special stream
87     //System.out.println("Foofoofoo!");
88     // Put things back
89     System.out.flush();
90     System.err.flush();
91     System.setOut(old);
92     System.setErr(err);
93     // Show what happened
94     //System.out.println("Here: " + baos.toString());    
95     
96     sb.append("<br/>");
97     sb.append(baos.toString());
98     
99     
f59dce 100     return sb.toString();
U 101   }
102   
103   
7b3372 104   /**
U 105    * Annahme: relPath zeigt auf einen Ordner, in dem ein build-Ordner die 
106    * fertigen Klassen und ein web-Ordner die Struktur mit WEB-INF 
107    * enthaelt.
108    * 
109    * @param relPath  der relative Pfad, der auf den App-Ordner verweist
110    * @return 
111    */
112   public String buildApp(String relPath) {
113     String result = "ok";
114     try {
115       File targetDir = getTargetDir(relPath); // App-Ordner
116       File classesDir = new File(targetDir, "web/WEB-INF/classes");
117       if(classesDir.exists()) {
118         FileUtils.deleteDirectory(classesDir);
119       }
120       classesDir.mkdirs();
121       File buildDir = new File(targetDir, "build/");
122       File[] files = buildDir.listFiles();
123       for(int i = 0; i < files.length; i++) {
124         if(files[i].isDirectory()) {
125           FileUtils.copyDirectoryToDirectory(files[i], classesDir);
126         } else {
127           FileUtils.copyFileToDirectory(files[i], classesDir);   
128         }
129       }
130     } catch(Exception ex) {
131       logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
132     }
133     return result;
134   }
72e43d 135     
U 136   public List<CompilerIssue> compileAll(String relPath) {
137     logger.fine(relPath);
138     List<CompilerIssue> compilerIssues = new ArrayList();
139     try {
140       File targetDir = getTargetDir(relPath);
141       ArrayList<File> files = new ArrayList();
142       collectFiles(files, targetDir, new JavaFileFilter());
143       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
144       DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector();
145       StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
146       Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
a450f2 147       
d9d37b 148       
U 149       final Iterable<String> options = buildOptions(targetDir);
150       
a450f2 151       compiler.getTask(null, null, diagnostics, options, null, compilationUnits).call();
72e43d 152       fileManager.close();
a450f2 153       collectResults(diagnostics, compilerIssues, relPath);
72e43d 154     } catch(Exception ex) {
U 155       logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
156     }
157     return compilerIssues;
f23f2b 158   }
U 159   
a450f2 160   private void collectResults(DiagnosticCollector<JavaFileObject> diagnostics, List<CompilerIssue> compilerIssues, String relPath) {
f23f2b 161     List compileResults = diagnostics.getDiagnostics();
U 162     Iterator i = compileResults.iterator();
163     while (i.hasNext()) {
164       Object o = i.next();
165       Diagnostic<? extends JavaFileObject> err;
166       if (o instanceof Diagnostic) {
167         err = (Diagnostic) o;
168         CompilerIssue issue = new CompilerIssue();
169         issue.setKind(err.getKind().name());
170         issue.setLineNumber(err.getLineNumber());
171         issue.setMessage(err.getMessage(Locale.GERMANY));
a450f2 172         
U 173         String srcName = err.getSource().getName().replace("\\", "/");
174         String cleanRelPath = relPath.replace(HOME_DIR_NAME + "/", "").replace(PUB_DIR_NAME + "/", "");
175         int pos = srcName.indexOf(cleanRelPath);
176         String className = srcName.substring(pos + cleanRelPath.length());
177         issue.setSourceName(className.replace("/", ".").substring(1));
178         //issue.setSourceName(srcName + "\r\n" + relPath);
f23f2b 179         compilerIssues.add(issue);
U 180       }
181     }
72e43d 182   }
0ac262 183   
72e43d 184   private void collectFiles(ArrayList<File> files, File dir, FileFilter filter) {
U 185     File[] dirFiles = dir.listFiles(filter);
186     for(int i = 0; i < dirFiles.length; i++) {
187       if(dirFiles[i].isDirectory()) {
188         logger.fine("drill down to " + dirFiles[i].getAbsolutePath());
189         collectFiles(files, dirFiles[i], filter);
190       } else {
191         logger.fine("add " + dirFiles[i].getAbsolutePath());
192         files.add(dirFiles[i]);
193       }
194     }
195   }
196   
197   public class JavaFileFilter implements FileFilter {
198
199     @Override
200     public boolean accept(File pathname) {
201       boolean doAccept = false;
202       if(pathname.getName().endsWith(".java") || pathname.isDirectory()) {
203         doAccept = true;
204       }
205       return doAccept;
206     }
207   
208   }
0ac262 209   
d9d37b 210   public class JarFileFilter implements FileFilter {
U 211
212     @Override
213     public boolean accept(File pathname) {
214       boolean doAccept = false;
215       if(pathname.getName().endsWith(".jar")) {
216         doAccept = true;
217       }
218       return doAccept;
219     }
220   
221   }
222   
fd0b4c 223   /**
U 224    * 
225    * @param relPath
226    * @param fileNames
227    * @param mode 0 = test, 1 = build
228    * @return
229    * @throws IOException 
230    */
231   public List<CompilerIssue> compile(String relPath, List fileNames, String mode) throws IOException {
0ac262 232     File targetDir = getTargetDir(relPath);
U 233     ArrayList<File> files = new ArrayList();
234     for(int i=0; i < fileNames.size(); i++) {
235       Object o = fileNames.get(i);
236       if(o instanceof ArrayList) {
237         ArrayList al = (ArrayList) o;
238         logger.fine(al.get(0).toString());
239         File targetFile = new File(targetDir, al.get(0).toString());
240         logger.fine(targetFile.getAbsolutePath());
241         files.add(targetFile);
242       }
243     }
244     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
245     DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector();
246     StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
f23f2b 247     Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(files);    
d9d37b 248     final Iterable<String> options = buildOptions(targetDir);
U 249     compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits1).call();
0ac262 250     fileManager.close();
e3043f 251     List<CompilerIssue> compilerIssues = new ArrayList();
a450f2 252     collectResults(diagnostics, compilerIssues, relPath);
e3043f 253     return compilerIssues;
0ac262 254   }
d9d37b 255
U 256   private final Iterable<String> buildOptions(File targetDir) {
6e1a29 257       String cbase = getCatalinaBase(getServletContext());
d9d37b 258       File lib = new File(cbase, "lib");
U 259       String cp = "";
260       cp = buildCPFromDir(cp, lib);
261       logger.fine(lib.getAbsolutePath());
262       logger.fine(cp);
263       /*
264         wegen dieser Funktion MUSS alles in 'src' liegen
265       */
266       File srcDir = targetDir;
267       while(!srcDir.getName().endsWith("src")) {        
268         srcDir = srcDir.getParentFile();
269       }
270       File appDir = srcDir.getParentFile();
271       File appLibDir = new File(appDir, "web/WEB-INF/lib");
272       cp = buildCPFromDir(cp, appLibDir);
273       logger.fine(cp);
274       /*
275         ausgehend von src eins hoeher, dann nach build
276       */
277       File buildDir = new File(appDir, "build");
278       final Iterable<String> options = Arrays.asList(new String[]{"-Xlint",
279                     "-cp", cp,
280                     "-d", buildDir.getAbsolutePath()
281                     });      
282       try {
283         FileUtils.deleteDirectory(buildDir);
284         buildDir.mkdir();
285       } catch (IOException ex) {
286         logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
287       }
288       return options;
289   }
290   /*
291   -classpath $JLIB/jettison-1.3.3.jar:$JLIB/xstream-1.4.7.jar
292   */
293   private String buildCPFromDir(String cp, File dir) {
294     StringBuffer buf = new StringBuffer(cp);
295     File[] files = dir.listFiles(new JarFileFilter());
296     for(int i = 0; i < files.length; i++) {
297       if(buf.length() > 0) {
298         buf.append(File.pathSeparatorChar);
299       }
300       //buf.append("\"");
301       buf.append(files[i].getAbsolutePath());
302       //buf.append("\"");
303     }
304     
305     return buf.toString();
306   }
0ac262 307 }
U 308
309
d9d37b 310
0ac262 311 /*
U 312
313  Beispeil fuer einen dynamischen Compiler-Aufruf
314  'in memory'
315
316  String className = "mypackage.MyClass";
317  String javaCode = "package mypackage;\n" +
318                   "public class MyClass implements Runnable {\n" +
319                   "    public void run() {\n" +
320                   "        System.out.println("\"Hello World\");\n" +
321                   "    }\n" +
322                   "}\n";
323  Class aClass = CompilerUtils.CACHED_COMPILER.loadFromJava(className, javaCode);
324  Runnable runner = (Runnable) aClass.newInstance();
325  runner.run();
326
d920b7 327 */
U 328
329 /*
330   CodeMirror Breakpoint bzw. Gutter Marker
331
332   https://codemirror.net/demo/marker.html
0ac262 333 */