PageRenderTime 93ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

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