Dateiverwaltung für die WebBox
ulrich
2020-11-17 f59dcede93351149bb5ff99c9310f467efd0d660
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;
0ac262 21 import java.io.File;
72e43d 22 import java.io.FileFilter;
0ac262 23 import java.io.IOException;
U 24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Locale;
72e43d 29 import java.util.logging.Level;
0ac262 30 import java.util.logging.Logger;
U 31 import javax.tools.Diagnostic;
32 import javax.tools.DiagnosticCollector;
33 import javax.tools.JavaCompiler;
34 import javax.tools.JavaFileObject;
35 import javax.tools.StandardJavaFileManager;
36 import javax.tools.ToolProvider;
a450f2 37 import org.apache.commons.io.FileUtils;
0ac262 38
U 39 /**
40  *
41  */
72e43d 42 public class CompileService extends Api {
0ac262 43   
U 44   private static final Logger logger = Logger.getLogger(CompileService.class.getName());
7b3372 45   
f59dce 46   public String antBuild(String relPath) {
U 47     File targetDir = getTargetDir(relPath); // App-Ordner
48     StringBuilder sb = new StringBuilder();
49     sb.append("Ant build ist noch nicht implementiert.");
50     //sb.append(System.lineSeparator());
51     sb.append("<br/>");
52     sb.append("targetDir: ");
53     sb.append(targetDir.getAbsolutePath());
54     return sb.toString();
55   }
56   
57   
7b3372 58   /**
U 59    * Annahme: relPath zeigt auf einen Ordner, in dem ein build-Ordner die 
60    * fertigen Klassen und ein web-Ordner die Struktur mit WEB-INF 
61    * enthaelt.
62    * 
63    * @param relPath  der relative Pfad, der auf den App-Ordner verweist
64    * @return 
65    */
66   public String buildApp(String relPath) {
67     String result = "ok";
68     try {
69       File targetDir = getTargetDir(relPath); // App-Ordner
70       File classesDir = new File(targetDir, "web/WEB-INF/classes");
71       if(classesDir.exists()) {
72         FileUtils.deleteDirectory(classesDir);
73       }
74       classesDir.mkdirs();
75       File buildDir = new File(targetDir, "build/");
76       File[] files = buildDir.listFiles();
77       for(int i = 0; i < files.length; i++) {
78         if(files[i].isDirectory()) {
79           FileUtils.copyDirectoryToDirectory(files[i], classesDir);
80         } else {
81           FileUtils.copyFileToDirectory(files[i], classesDir);   
82         }
83       }
84     } catch(Exception ex) {
85       logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
86     }
87     return result;
88   }
72e43d 89     
U 90   public List<CompilerIssue> compileAll(String relPath) {
91     logger.fine(relPath);
92     List<CompilerIssue> compilerIssues = new ArrayList();
93     try {
94       File targetDir = getTargetDir(relPath);
95       ArrayList<File> files = new ArrayList();
96       collectFiles(files, targetDir, new JavaFileFilter());
97       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
98       DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector();
99       StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
100       Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
a450f2 101       
d9d37b 102       
U 103       final Iterable<String> options = buildOptions(targetDir);
104       
a450f2 105       compiler.getTask(null, null, diagnostics, options, null, compilationUnits).call();
72e43d 106       fileManager.close();
a450f2 107       collectResults(diagnostics, compilerIssues, relPath);
72e43d 108     } catch(Exception ex) {
U 109       logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
110     }
111     return compilerIssues;
f23f2b 112   }
U 113   
a450f2 114   private void collectResults(DiagnosticCollector<JavaFileObject> diagnostics, List<CompilerIssue> compilerIssues, String relPath) {
f23f2b 115     List compileResults = diagnostics.getDiagnostics();
U 116     Iterator i = compileResults.iterator();
117     while (i.hasNext()) {
118       Object o = i.next();
119       Diagnostic<? extends JavaFileObject> err;
120       if (o instanceof Diagnostic) {
121         err = (Diagnostic) o;
122         CompilerIssue issue = new CompilerIssue();
123         issue.setKind(err.getKind().name());
124         issue.setLineNumber(err.getLineNumber());
125         issue.setMessage(err.getMessage(Locale.GERMANY));
a450f2 126         
U 127         String srcName = err.getSource().getName().replace("\\", "/");
128         String cleanRelPath = relPath.replace(HOME_DIR_NAME + "/", "").replace(PUB_DIR_NAME + "/", "");
129         int pos = srcName.indexOf(cleanRelPath);
130         String className = srcName.substring(pos + cleanRelPath.length());
131         issue.setSourceName(className.replace("/", ".").substring(1));
132         //issue.setSourceName(srcName + "\r\n" + relPath);
f23f2b 133         compilerIssues.add(issue);
U 134       }
135     }
72e43d 136   }
0ac262 137   
72e43d 138   private void collectFiles(ArrayList<File> files, File dir, FileFilter filter) {
U 139     File[] dirFiles = dir.listFiles(filter);
140     for(int i = 0; i < dirFiles.length; i++) {
141       if(dirFiles[i].isDirectory()) {
142         logger.fine("drill down to " + dirFiles[i].getAbsolutePath());
143         collectFiles(files, dirFiles[i], filter);
144       } else {
145         logger.fine("add " + dirFiles[i].getAbsolutePath());
146         files.add(dirFiles[i]);
147       }
148     }
149   }
150   
151   public class JavaFileFilter implements FileFilter {
152
153     @Override
154     public boolean accept(File pathname) {
155       boolean doAccept = false;
156       if(pathname.getName().endsWith(".java") || pathname.isDirectory()) {
157         doAccept = true;
158       }
159       return doAccept;
160     }
161   
162   }
0ac262 163   
d9d37b 164   public class JarFileFilter implements FileFilter {
U 165
166     @Override
167     public boolean accept(File pathname) {
168       boolean doAccept = false;
169       if(pathname.getName().endsWith(".jar")) {
170         doAccept = true;
171       }
172       return doAccept;
173     }
174   
175   }
176   
fd0b4c 177   /**
U 178    * 
179    * @param relPath
180    * @param fileNames
181    * @param mode 0 = test, 1 = build
182    * @return
183    * @throws IOException 
184    */
185   public List<CompilerIssue> compile(String relPath, List fileNames, String mode) throws IOException {
0ac262 186     File targetDir = getTargetDir(relPath);
U 187     ArrayList<File> files = new ArrayList();
188     for(int i=0; i < fileNames.size(); i++) {
189       Object o = fileNames.get(i);
190       if(o instanceof ArrayList) {
191         ArrayList al = (ArrayList) o;
192         logger.fine(al.get(0).toString());
193         File targetFile = new File(targetDir, al.get(0).toString());
194         logger.fine(targetFile.getAbsolutePath());
195         files.add(targetFile);
196       }
197     }
198     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
199     DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector();
200     StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
f23f2b 201     Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(files);    
d9d37b 202     final Iterable<String> options = buildOptions(targetDir);
U 203     compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits1).call();
0ac262 204     fileManager.close();
e3043f 205     List<CompilerIssue> compilerIssues = new ArrayList();
a450f2 206     collectResults(diagnostics, compilerIssues, relPath);
e3043f 207     return compilerIssues;
0ac262 208   }
d9d37b 209
U 210   private final Iterable<String> buildOptions(File targetDir) {
6e1a29 211       String cbase = getCatalinaBase(getServletContext());
d9d37b 212       File lib = new File(cbase, "lib");
U 213       String cp = "";
214       cp = buildCPFromDir(cp, lib);
215       logger.fine(lib.getAbsolutePath());
216       logger.fine(cp);
217       /*
218         wegen dieser Funktion MUSS alles in 'src' liegen
219       */
220       File srcDir = targetDir;
221       while(!srcDir.getName().endsWith("src")) {        
222         srcDir = srcDir.getParentFile();
223       }
224       File appDir = srcDir.getParentFile();
225       File appLibDir = new File(appDir, "web/WEB-INF/lib");
226       cp = buildCPFromDir(cp, appLibDir);
227       logger.fine(cp);
228       /*
229         ausgehend von src eins hoeher, dann nach build
230       */
231       File buildDir = new File(appDir, "build");
232       final Iterable<String> options = Arrays.asList(new String[]{"-Xlint",
233                     "-cp", cp,
234                     "-d", buildDir.getAbsolutePath()
235                     });      
236       try {
237         FileUtils.deleteDirectory(buildDir);
238         buildDir.mkdir();
239       } catch (IOException ex) {
240         logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
241       }
242       return options;
243   }
244   /*
245   -classpath $JLIB/jettison-1.3.3.jar:$JLIB/xstream-1.4.7.jar
246   */
247   private String buildCPFromDir(String cp, File dir) {
248     StringBuffer buf = new StringBuffer(cp);
249     File[] files = dir.listFiles(new JarFileFilter());
250     for(int i = 0; i < files.length; i++) {
251       if(buf.length() > 0) {
252         buf.append(File.pathSeparatorChar);
253       }
254       //buf.append("\"");
255       buf.append(files[i].getAbsolutePath());
256       //buf.append("\"");
257     }
258     
259     return buf.toString();
260   }
0ac262 261 }
U 262
263
d9d37b 264
0ac262 265 /*
U 266
267  Beispeil fuer einen dynamischen Compiler-Aufruf
268  'in memory'
269
270  String className = "mypackage.MyClass";
271  String javaCode = "package mypackage;\n" +
272                   "public class MyClass implements Runnable {\n" +
273                   "    public void run() {\n" +
274                   "        System.out.println("\"Hello World\");\n" +
275                   "    }\n" +
276                   "}\n";
277  Class aClass = CompilerUtils.CACHED_COMPILER.loadFromJava(className, javaCode);
278  Runnable runner = (Runnable) aClass.newInstance();
279  runner.run();
280
d920b7 281 */
U 282
283 /*
284   CodeMirror Breakpoint bzw. Gutter Marker
285
286   https://codemirror.net/demo/marker.html
0ac262 287 */