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