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