PageRenderTime 4ms CodeModel.GetById 60ms app.highlight 150ms RepoModel.GetById 27ms app.codeStats 1ms

/src/mpv5/utils/files/FileDirectoryHandler.java

http://mp-rechnungs-und-kundenverwaltung.googlecode.com/
Java | 668 lines | 423 code | 49 blank | 196 comment | 78 complexity | 00917de7f877ced3ec7baa3f2d268289 MD5 | raw file
  1/*
  2 * 
  3 * 
  4 */
  5package mpv5.utils.files;
  6
  7/**
  8 *
  9 *  Galileo Computing
 10 */
 11import java.awt.Desktop;
 12import java.io.BufferedOutputStream;
 13import java.io.FileNotFoundException;
 14
 15import java.io.File;
 16import java.io.FileInputStream;
 17import java.io.FileOutputStream;
 18import java.io.IOException;
 19import java.io.InputStream;
 20import java.io.OutputStream;
 21import java.net.URI;
 22import java.net.URL;
 23import java.net.URLConnection;
 24import java.util.ArrayList;
 25import java.util.Arrays;
 26import java.util.List;
 27import java.util.logging.Level;
 28import java.util.logging.Logger;
 29import mpv5.globals.Constants;
 30import mpv5.globals.LocalSettings;
 31import mpv5.globals.Messages;
 32import mpv5.logging.Log;
 33import mpv5.ui.dialogs.DialogForFile;
 34import mpv5.ui.dialogs.Notificator;
 35import mpv5.ui.dialogs.Popup;
 36import mpv5.utils.text.RandomText;
 37
 38public abstract class FileDirectoryHandler {
 39
 40    /**
 41     * Deletes a file now or later
 42     * @param localFile
 43     * @param now
 44     */
 45    public static void deleteFile(File localFile, boolean now) {
 46        if (now) {
 47            try {
 48                deleteTree(localFile);
 49            } catch (IOException ex) {
 50                Log.Debug(ex);
 51            }
 52        } else {
 53            localFile.deleteOnExit();
 54        }
 55    }
 56
 57    /**
 58     * Deletes a whole directory tree and files in it
 59     * @param path
 60     * @throws java.io.IOException
 61     */
 62    public synchronized static void deleteTree(File path) throws IOException {
 63        deleteDirectoryContent(path);
 64        if (!path.delete()) {
 65            path.deleteOnExit();
 66        }
 67    }
 68
 69    /**
 70     * Deletes the content of a directory
 71     * @param path
 72     * @throws java.io.IOException
 73     */
 74    public synchronized static void deleteDirectoryContent(File path) throws IOException {
 75        for (File file : path.listFiles()) {
 76            if (file.isDirectory()) {
 77                deleteTree(file);
 78            } else {
 79                Log.Debug(FileDirectoryHandler.class, "Delete: " + file.getCanonicalPath());
 80                if (!file.delete()) {
 81                    file.deleteOnExit();
 82                }
 83            }
 84        }
 85    }
 86
 87    /**
 88     * 
 89     * @param sourceLocation
 90     * @param targetLocation
 91     * @return 
 92     * @throws java.io.IOException
 93     */
 94    public static URI copyDirectory(File sourceLocation, File targetLocation) throws IOException {
 95
 96        if (sourceLocation.isDirectory()) {
 97            if (!targetLocation.exists()) {
 98                targetLocation.mkdir();
 99            }
100
101            String[] children = sourceLocation.list();
102            for (int i = 0; i < children.length; i++) {
103                copyDirectory(new File(sourceLocation, children[i]),
104                        new File(targetLocation, children[i]));
105            }
106        } else {
107
108            InputStream in = new FileInputStream(sourceLocation);
109            OutputStream out = new FileOutputStream(targetLocation);
110
111            // Copy the bits from instream to outstream
112            byte[] buf = new byte[1024];
113            int len;
114            while ((len = in.read(buf)) > 0) {
115                out.write(buf, 0, len);
116            }
117            in.close();
118            out.close();
119        }
120        return targetLocation.toURI();
121    }
122
123    /**
124     * Copies a file via stream
125     * @param source
126     * @param target
127     * @return
128     * @throws java.io.FileNotFoundException
129     * @throws java.io.IOException
130     */
131    public static File copyFile2(File source, File target, boolean silent) throws FileNotFoundException, IOException {
132        Log.Debug(FileDirectoryHandler.class, "Copying file from "
133                + source + " to " + target);
134        return new File(copyFile(source, target, silent));
135    }
136
137    /**
138     * Copies a file via stream
139     * @param source
140     * @param target
141     * @return
142     * @throws java.io.FileNotFoundException
143     * @throws java.io.IOException
144     */
145    public static File copyFile2(File source, File target) throws FileNotFoundException, IOException {
146        Log.Debug(FileDirectoryHandler.class, "Copying file from "
147                + source + " to " + target);
148        return new File(copyFile(source, target, true));
149    }
150
151    /**
152     * Copies a file via stream
153     * @param sourceFile
154     * @param targetDirectory
155     * @param targetFilename
156     * @param deleteOnExit Shall we delete the NEW file on exit
157     * @return
158     * @throws java.io.IOException
159     */
160    public static URI copyFile(File sourceFile, File targetDirectory, String targetFilename, boolean deleteOnExit)
161            throws IOException {
162        targetFilename = check(targetFilename);
163        return copyFile(sourceFile, targetDirectory, targetFilename, deleteOnExit, true);
164    }
165
166    /**
167     * Copies a file via stream
168     * @param sourceFile
169     * @param targetDirectory
170     * @param targetFilename
171     * @param deleteOnExit Shall we delete the NEW file on exit
172     * @param silent 
173     * @return
174     * @throws java.io.IOException
175     */
176    public static URI copyFile(File sourceFile, File targetDirectory, String targetFilename, boolean deleteOnExit, boolean silent)
177            throws IOException {
178        targetFilename = check(targetFilename);
179        FileOutputStream out = null;
180        InputStream in = new FileInputStream(sourceFile);
181        File outp = null;
182        if (targetDirectory != null) {
183            outp = new File(targetDirectory + File.separator + targetFilename);
184            if (!targetDirectory.exists()) {
185                targetDirectory.mkdirs();
186            }
187            outp.delete();
188            out = new FileOutputStream(targetDirectory + File.separator + targetFilename);
189        } else {
190            outp = new File(targetFilename);
191            outp.delete();
192            out = new FileOutputStream(targetFilename);
193        }
194
195
196        // Copy the bits from instream to outstream
197        byte[] buf = new byte[1024];
198        int len;
199        while ((len = in.read(buf)) > 0) {
200            out.write(buf, 0, len);
201        }
202        in.close();
203        out.close();
204
205        if (deleteOnExit) {
206            outp.deleteOnExit();
207        }
208
209        if (!silent) {
210            Notificator.raiseNotification(Messages.FILE_SAVED + " " + outp.getPath(), false);
211        }
212
213        return outp.toURI();
214    }
215
216    /**
217     * Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.
218     * Files (or directories) are deleted in the reverse order that they are registered.
219     * Invoking this method to delete a file or directory that is already registered for deletion has no effect.
220     * Deletion will be attempted only for normal termination of the virtual machine, as defined by the Java Language Specification.
221     * Once deletion has been requested, it is not possible to cancel the request.
222     * @param path
223     * @throws IOException
224     */
225    public static void deleteTreeOnExit(File path) throws IOException {
226        for (File file : path.listFiles()) {
227            if (file.isDirectory()) {
228                deleteTreeOnExit(file);
229            } else {
230                Log.Debug(FileDirectoryHandler.class, "Delete On Exit: " + file.getCanonicalPath());
231                file.deleteOnExit();
232            }
233        }
234        path.deleteOnExit();
235    }
236
237    /**
238     *
239     * @param directory
240     * @param identifier
241     * @return A File array with the files (not directories) within the given directory
242     */
243    @SuppressWarnings("unchecked")
244    public static File[] getFilesOfDirectory(File directory) {
245        File src;
246        ArrayList<File> lstFiles = new ArrayList<File>();
247        if (directory.isDirectory()) {
248            try {
249                src = directory;
250                Log.Debug(FileDirectoryHandler.class, "Verzeichnis: " + src);
251                File[] files = src.listFiles();
252                Log.Debug(FileDirectoryHandler.class, "Dateien analysieren...");
253                lstFiles = new ArrayList<java.io.File>();
254                if (files != null && files.length > 0) {
255                    for (int i = 0, k = 0; i < files.length; i++) {
256//                Log.Debug(this,"Datei analysieren: " + files[i].getName());
257                        if (files[i].isFile()) {
258                            try {
259                                lstFiles.add(files[i]);
260                                Log.Debug(FileDirectoryHandler.class, "Datei gefunden: " + files[i].getName());
261                                k++;
262                            } catch (Exception ex) {
263                                Log.Debug(FileDirectoryHandler.class, ex.getMessage());
264                            }
265                        }
266                    }
267                } else {
268                    Log.Debug(FileDirectoryHandler.class, "Keine Datei gefunden.");
269                }
270            } catch (Exception exception) {
271                Log.Debug(FileDirectoryHandler.class, exception);
272                Log.Debug(FileDirectoryHandler.class, exception.getMessage());
273            }
274        }
275        return lstFiles.toArray(new File[0]);
276    }
277
278    /**
279     *
280     * @param directory
281     * @param identifier
282     * @return A File array with the files (not directories) within the given directory
283     */
284    @SuppressWarnings("unchecked")
285    public static File[] getFilesOfDirectory(String directory, String identifier) {
286        File src;
287        ArrayList<File> lstFiles = null;
288        try {
289            lstFiles = new ArrayList<java.io.File>();
290            src = new File(directory);
291            Log.Debug(FileDirectoryHandler.class, "Verzeichnis: " + src);
292            File[] files = src.listFiles();
293            Log.Debug(FileDirectoryHandler.class, "Dateien analysieren...");
294            lstFiles = new ArrayList<java.io.File>();
295            if (files != null && files.length > 0) {
296                for (int i = 0, k = 0; i < files.length; i++) {
297//                Log.Debug(this,"Datei analysieren: " + files[i].getName());
298                    if (files[i].isFile() && (identifier == null || files[i].toString().contains(identifier))) {
299                        try {
300                            lstFiles.add(files[i]);
301                            Log.Debug(FileDirectoryHandler.class, "Datei gefunden: " + files[i].getName());
302                            k++;
303                        } catch (Exception ex) {
304                            Log.Debug(FileDirectoryHandler.class, ex.getMessage());
305                        }
306                    }
307                }
308            } else {
309                Log.Debug(FileDirectoryHandler.class, "Keine Datei gefunden.");
310            }
311        } catch (Exception exception) {
312            Log.Debug(FileDirectoryHandler.class, exception);
313            Log.Debug(FileDirectoryHandler.class, exception.getMessage());
314        }
315        return lstFiles.toArray(new File[0]);
316    }
317
318    /**
319     * Open a file in default app or as "save as" dialog, depending on the platform
320     * @param file
321     */
322    public static void open(File file) {
323        if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
324            try {
325                Desktop.getDesktop().open(file);
326            } catch (Exception ex) {
327                Log.Debug(FileDirectoryHandler.class, ex.getMessage());
328                Popup.notice(Messages.FILE_OPEN_FAILED + file.getPath());
329            }
330        } else {
331            new DialogForFile().saveFile(file);
332        }
333    }
334
335    /**
336     * Edit a file in default app or as "save as" dialog, depending on the platform
337     * @param file
338     */
339    public static void edit(File file) {
340        if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) {
341            try {
342                Desktop.getDesktop().edit(file);
343            } catch (Exception ex) {
344                Log.Debug(FileDirectoryHandler.class, ex.getMessage());
345                Popup.notice(Messages.FILE_OPEN_FAILED + file.getPath());
346            }
347        } else {
348            new DialogForFile(DialogForFile.FILES_ONLY).saveFile(file);
349        }
350    }
351
352    public static void save(File file) {
353        DialogForFile d = new DialogForFile(DialogForFile.FILES_ONLY, new File(file.getName()));
354        d.saveFile(file);
355    }
356
357    /**
358     * Copies a file to a temporary file. The resulting file is NOT linked
359     * to the original one and even the original file is locked,
360     * the resulting file is not
361     * @param file
362     * @return The file with a randomly generated suffix
363     */
364    public static File tempFileClone(File file) {
365        return tempFileClone(file, new RandomText(3).getString());
366    }
367
368    /**
369     * Copies a file to a temporary file. The resulting file is NOT linked
370     * to the original one and even the original file is locked,
371     * the resulting file is not
372     * @param file
373     * @param suffix
374     * @return
375     */
376    public static File tempFileClone(File file, String suffix) {
377        try {
378            suffix = check(suffix);
379            cacheCheck();
380            File fil = new File(copyFile(file, new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR)), new RandomText().getString() + "." + suffix, true));
381            fil.deleteOnExit();
382            return fil;
383        } catch (IOException ex) {
384            Log.Debug(FileDirectoryHandler.class, ex);
385        }
386        return null;
387    }
388
389    /**
390     * Returns a completely random named temporay file
391     * @param suffix no '.' please
392     * @return
393     */
394    public static File getTempFile(String suffix) {
395        suffix = check(suffix);
396        return getTempFile(new RandomText(18).getString(), suffix);
397    }
398
399    /**
400     *
401     * @return A temporary file with MP suffix (~mp)
402     */
403    public static File getTempFile() {
404        return getTempFile("~yabs");
405    }
406
407    /**
408     *
409     * @param filename
410     * @param suffix
411     * @return A temporay file with the given name
412     */
413    public static File getTempFile(String filename, String suffix) {
414        cacheCheck();
415        filename = check(filename);
416        suffix = check(suffix);
417        File fil = new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR) + File.separator + filename + "." + suffix);
418        fil.deleteOnExit();
419        return fil;
420    }
421
422    /**
423     *
424     * @return The temporary directory + File.separator
425     */
426    public static String getTempDir() {
427        cacheCheck();
428        return LocalSettings.getProperty(LocalSettings.CACHE_DIR) + File.separator;
429    }
430
431    /**
432     *
433     * @return The temporary directory
434     */
435    public static String getTempDir2() {
436        cacheCheck();
437        return LocalSettings.getProperty(LocalSettings.CACHE_DIR);
438    }
439
440    /**
441     *
442     * @return The temporary directory as File object
443     */
444    public static File getTempDirAsFile() {
445        cacheCheck();
446        return new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR));
447    }
448
449    /**
450     * Downloads a file
451     * @param address
452     * @param localFileName
453     * @return
454     *  Marco Schmidt
455     */
456    public static File download(String address, String localFileName) {
457        localFileName = check(localFileName);
458        OutputStream out = null;
459        URLConnection conn = null;
460        InputStream in = null;
461        try {
462            URL url = new URL(address);
463            out = new BufferedOutputStream(
464                    new FileOutputStream(localFileName));
465            conn = url.openConnection();
466            in = conn.getInputStream();
467            byte[] buffer = new byte[1024];
468            int numRead;
469            long numWritten = 0;
470            while ((numRead = in.read(buffer)) != -1) {
471                out.write(buffer, 0, numRead);
472                numWritten += numRead;
473            }
474            Log.Debug(FileDirectoryHandler.class, localFileName + "\t" + numWritten);
475        } catch (Exception exception) {
476            Log.Debug(FileDirectoryHandler.class, exception);
477        } finally {
478            try {
479                if (in != null) {
480                    in.close();
481                }
482                if (out != null) {
483                    out.close();
484                }
485            } catch (IOException ioe) {
486            }
487        }
488        File file = new File(localFileName);
489//        file.deleteOnExit();
490        return file;
491    }
492
493    /**
494     * Downloads a file
495     * @param address
496     * @return
497     */
498    public static File download(String address) {
499        int lastSlashIndex = address.lastIndexOf('/');
500        if (lastSlashIndex >= 0
501                && lastSlashIndex < address.length() - 1) {
502            return download(address, address.substring(lastSlashIndex + 1));
503        } else {
504            Log.Debug(FileDirectoryHandler.class, "Could not figure out local file name for "
505                    + address);
506        }
507        return null;
508    }
509
510    /**
511     * Copies a file via streaming
512     * @param sourceFile
513     * @param outp
514     * @param silent
515     * @return
516     * @throws java.io.FileNotFoundException
517     * @throws java.io.IOException
518     */
519    public static URI copyFile(File sourceFile, File outp, boolean silent) throws FileNotFoundException, IOException {
520        InputStream in = new FileInputStream(sourceFile);
521
522        OutputStream out = new FileOutputStream(outp);
523
524        // Copy the bits from instream to outstream
525        byte[] buf = new byte[1024];
526        int len;
527        while ((len = in.read(buf)) > 0) {
528            out.write(buf, 0, len);
529        }
530        in.close();
531        out.close();
532
533        if (!silent) {
534            Notificator.raiseNotification(Messages.FILE_SAVED + " " + outp.getPath(), false);
535        }
536
537        return outp.toURI();
538    }
539
540    /**
541     * Copies a file via streaming
542     * @param sourceFile
543     * @param outp
544     * @return
545     * @throws java.io.FileNotFoundException
546     * @throws java.io.IOException
547     */
548    public static URI copyFile(File sourceFile, File outp) throws FileNotFoundException, IOException {
549        return copyFile(sourceFile, outp, true);
550    }
551
552    private static void cacheCheck() {
553        File e = null;
554        try {
555            e = new File(LocalSettings.getProperty(LocalSettings.CACHE_DIR));
556        } catch (Exception ex) {//avoid npe
557            Log.Debug(ex);
558            LocalSettings.setProperty(LocalSettings.CACHE_DIR, Constants.FALLBACK_CACHE_DIR);
559            e = new File(Constants.FALLBACK_CACHE_DIR);
560        }
561        if (!e.exists()) {
562            e.mkdirs();
563        }
564        //Cannot access Cache dir?
565        if (!e.isDirectory() || !e.canWrite() || e.listFiles() == null) {
566            LocalSettings.setProperty(LocalSettings.CACHE_DIR, Constants.FALLBACK_CACHE_DIR);
567            cacheCheck();
568            try {
569                FileDirectoryHandler.deleteTreeOnExit(getTempDirAsFile());
570            } catch (IOException ex) {
571                Log.Debug(ex);
572            }
573        }
574    }
575
576    private static synchronized String check(String filename) {
577        return filename.replaceAll("[?:\\\\/*\\\"\\\"<>|]", "-").replace("..", ".");
578    }
579
580    /**
581     * Unzips the file (if it is a zip file, returns the original file if it is not a zip file).
582     * If the given file is a zip file containing multiple files, returns a temporary directory containing the extracted files.
583     * @param file
584     * @return
585     */
586    public static File unzipFile(File file) {
587        if (file.getName().endsWith(".zip") || file.getName().endsWith(".jar")) {
588            File c = getnewTemporaryDirectory();
589            UnZip.deflate(file.getPath(), c.getPath());
590            if (c.listFiles().length == 1) {
591                File k = c.listFiles()[0];
592                if (k.isFile()) {
593                    return k;
594                } else if (k.listFiles().length == 1) {
595                    return (k.listFiles()[0].isFile()) ? k.listFiles()[0] : c;
596                }
597            }
598
599            return c;
600        } else {
601            return file;
602        }
603    }
604
605    /**
606     * Creates a new, RW, temporary directory within the cache directory
607     * @return
608     */
609    public static File getnewTemporaryDirectory() {
610        File f = getTempDirAsFile();
611        File t = new File(f.getPath() + File.separator + RandomText.getText() + File.separator + RandomText.getText());
612        t.mkdirs();
613        t.getParentFile().setWritable(true);
614        t.getParentFile().setReadable(true);
615        return t;
616    }
617
618    /**
619     * Deletes the content of a directory, omitting files which contain $omit in their name
620     * No Subdirectories are deleted!
621     * @param path 
622     * @param omit
623     * @throws IOException 
624     */
625    public static void deleteDirectoryContent(File path, String... omit) throws IOException {
626        for (File file : path.listFiles()) {
627            List<String> o = Arrays.asList(omit);
628            String name = file.getName();
629            boolean rd = true;
630            for (int i = 0; i < o.size(); i++) {
631                String string = o.get(i);
632                if (name.toLowerCase().contains(string.toLowerCase())) {
633                    rd = false;
634                }
635            }
636            if (rd) {
637                file.delete();
638            }
639        }
640    }
641
642    /**
643     * Deletes the content of a directory, omitting files which contain $omit in their name
644     * ALL Subdirectories are deleted!
645     * @param path 
646     * @param omit
647     * @throws IOException 
648     */
649    public static void deleteDirectoryContent2(File path, String... omit) throws IOException {
650        for (File file : path.listFiles()) {
651            if (file.isDirectory()) {
652                deleteDirectoryContent2(file, omit);
653            }
654            List<String> o = Arrays.asList(omit);
655            String name = file.getName();
656            boolean rd = true;
657            for (int i = 0; i < o.size(); i++) {
658                String string = o.get(i);
659                if (name.toLowerCase().contains(string.toLowerCase())) {
660                    rd = false;
661                }
662            }
663            if (rd) {
664                file.delete();
665            }
666        }
667    }
668}