001: /*
002: * MCS Media Computer Software Copyright (c) 2005 by MCS
003: * -------------------------------------- Created on 16.01.2004 by w.klaas
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
006: * use this file except in compliance with the License. You may obtain a copy of
007: * the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014: * License for the specific language governing permissions and limitations under
015: * the License.
016: */
017:
018: package de.mcs.utils;
019:
020: import java.io.BufferedReader;
021: import java.io.BufferedWriter;
022: import java.io.File;
023: import java.io.FileInputStream;
024: import java.io.FileNotFoundException;
025: import java.io.FileWriter;
026: import java.io.FilenameFilter;
027: import java.io.IOException;
028: import java.io.InputStreamReader;
029: import java.util.ArrayList;
030: import java.util.regex.Pattern;
031:
032: /**
033: * filetool class.
034: *
035: * @author w.klaas
036: * @deprecated please use the files class.
037: */
038: public final class FileTool {
039:
040: /** prevent instancing. */
041: private FileTool() {
042: }
043:
044: /**
045: * Retrieves the existance of a file or directory (to be or not to be....).
046: *
047: * @param fileName
048: * name of the file or directory.
049: * @return success
050: */
051: public static boolean fileExists(final String fileName) {
052: return new File(fileName).exists();
053: }
054:
055: /**
056: * Create a directory; all ancestor directories must exist.
057: *
058: * @param directory
059: * name of the directory
060: * @return success
061: */
062: public static boolean createDirectory(final String directory) {
063: boolean success = (new File(directory)).mkdir();
064: if (!success) {
065: System.err.println("Directory [" + directory
066: + "] creation failed !");
067: }
068: return success;
069: }
070:
071: /**
072: * Create a directory; all non-existent ancestor directories are.
073: * automatically created
074: *
075: * @param directory
076: * the directory
077: * @return success
078: */
079: public static boolean createDirectories(final String directory) {
080: boolean success = (new File(directory)).mkdirs();
081: if (!success) {
082: System.err.println("Directory [" + directory
083: + "] creation failed !");
084: }
085: return success;
086: }
087:
088: /**
089: * Create a directory and a number of subdirectories specified in the String
090: * array automatically created.
091: *
092: * @param aDirectory
093: * the directory
094: * @param subdirectories
095: * the subdirectories
096: * @return success
097: */
098: public static boolean createDirectoryStructure(
099: final String aDirectory, final String[] subdirectories) {
100: String directory = aDirectory;
101: boolean success = true;
102: directory = eliminateDoubleSlashes(directory);
103: if (!fileExists(directory)) {
104: if (!createDirectories(directory)) {
105: return false;
106: }
107: }
108: if (!directory.endsWith("/")) {
109: directory += '/';
110: }
111: for (int iLoop = 0; iLoop < subdirectories.length; iLoop++) {
112: File subDir = new File(directory + subdirectories[iLoop]);
113: if (!subDir.exists()) {
114: if (!createDirectory(directory + subdirectories[iLoop])) {
115: success = false;
116: break;
117: }
118: }
119: // success=(iLoop==subdirectories.length-1);
120: }
121:
122: if (!success) {
123: System.err.println("Directory [" + directory
124: + "] creation failed !");
125: }
126: return success;
127: }
128:
129: /**
130: * Move / Rename source location to destination. String array automatically
131: * created
132: *
133: * @param source
134: * source
135: * @param destination
136: * destination
137: * @return success
138: */
139: public static boolean move(final String source,
140: final String destination) {
141: try {
142: return (new File(source)).renameTo(new File(destination));
143: } catch (SecurityException e) {
144: System.err.println("The file " + source
145: + " could not moved to " + destination + " : "
146: + e.getLocalizedMessage());
147: return false;
148: }
149: }
150:
151: /**
152: * Copy source location to destination.
153: *
154: * @param source
155: * source
156: * @param destination
157: * destination
158: * @return success
159: */
160: public static boolean copy(final String source,
161: final String destination) {
162: searchDepth = 0;
163: return filecopy(source, destination, true);
164: }
165:
166: /**
167: * Copy source location to destination.
168: *
169: * @param source
170: * source
171: * @param destination
172: * destination
173: * @param subdirectories
174: * subdirectories
175: * @return success
176: */
177: public static boolean copy(final String source,
178: final String destination, final boolean subdirectories) {
179: searchDepth = 0;
180: return filecopy(source, destination, subdirectories);
181: }
182:
183: /**
184: * Filename filter class.
185: *
186: * @author w.klaas
187: */
188: static class FileIncludes implements FilenameFilter {
189:
190: /** directory to eveluate. */
191: private File dir;
192:
193: /** the regex. */
194: private Pattern mask;
195:
196: /** prevent instancing with the default constructor. */
197: private FileIncludes() {
198: throw new UnsupportedOperationException();
199: }
200:
201: /**
202: * is the mask a mask?
203: *
204: * @param mask
205: * the mask
206: *
207: * @return <code>true</code> if the mask containing a * or ?
208: */
209: private static boolean isMask(final String mask) {
210: int pos = mask.indexOf('*');
211: if (pos < 0) {
212: pos = mask.indexOf('?');
213: }
214: return pos >= 0;
215: }
216:
217: /**
218: * special regexp chars : '.', '\\', '$', '^', '(' , ')', '[', ']' ,'+', .
219: * (must be masked if in mask) special mask chars to convert for regexp :
220: * '*' -> '.*', '?' -> '.+'
221: */
222: private static String regexpSpecChars = ".\\$^()[]+";
223:
224: /**
225: * convert the mask to a regualr expression.
226: *
227: * @param aMask
228: * the mask
229: * @return String regular expression.
230: */
231: String toRegExp(final String aMask) {
232: StringBuffer sb = new StringBuffer();
233: int length = aMask.length();
234: for (int index = 0; index < length; index++) {
235: char ch = aMask.charAt(index);
236: if (ch == '*') {
237: sb.append(".*");
238: } else if (ch == '?') {
239: sb.append(".+");
240: } else if (regexpSpecChars.indexOf(ch) >= 0) {
241: sb.append('\\').append(ch);
242: } else {
243: sb.append(ch);
244: }
245: }
246: return sb.toString();
247: }
248:
249: /**
250: * Constructs a FilenameFilter instance to filter files, which base name
251: * (without the directoy path) that match the given regular expression.
252: *
253: * @param aDir
254: * the directory
255: * @param aMask
256: * the mask
257: * @throws java.util.regex.PatternSyntaxException
258: */
259: public FileIncludes(final File aDir, final String aMask) {
260: this .dir = aDir;
261: this .mask = Pattern.compile(toRegExp(aMask));
262: // System.out.println("FileIncludes: dir=" + dir.toString() + ",
263: // mask=" + mask);
264:
265: }
266:
267: /**
268: * Tests if a specified file should be included in a file list.
269: *
270: * @param aDir
271: * the directory in which the file was found.
272: * @param name
273: * the name of the file.
274: * @return <code>true</code> if and only if the name should be
275: * included in the file list; <code>false</code> otherwise.
276: * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String)
277: */
278: public boolean accept(final File aDir, final String name) {
279: // System.out.println("accept: dir=" + dir.toString() + ", name=" +
280: // name);
281: if (aDir.equals(this .dir)) {
282: boolean matches = mask.matcher(name).matches();
283: // System.out.println("accept: result=" + matches);
284: return matches;
285: } else {
286: // System.out.println("accept: result=" + false);
287: return false;
288: }
289: }
290:
291: }
292:
293: /** default subdirectory depth to copy. */
294: private static int searchDepth = 0;
295:
296: /**
297: * Copy source location to destination.
298: *
299: * @param source
300: * The pathname of a single directory or a single file or
301: * multiple files through a filemask.
302: * @param destination
303: * destination path
304: * @param subdirectories
305: * allow subdirectories to be copied
306: * @return <code>true</code> if this operation succseeded
307: */
308: protected static boolean filecopy(final String source,
309: final String destination, final boolean subdirectories) {
310:
311: boolean success = true; // just be optimistic
312: File sourceFile = new File(source);
313: if (sourceFile.isDirectory()) {
314: if (searchDepth++ > 0 && !subdirectories) {
315: return true;
316: }
317: if (!fileExists(destination)) {
318: createDirectories(destination);
319: }
320: String[] subFiles = sourceFile.list();
321: for (int iLoop = 0; iLoop < subFiles.length; iLoop++) {
322: filecopy(source + File.separator + subFiles[iLoop],
323: destination + File.separator + subFiles[iLoop],
324: subdirectories);
325: }
326: } else {
327: // create destination directory if it does not exist
328: int fSlash = destination.lastIndexOf("/"), bSlash = destination
329: .lastIndexOf("\\");
330: int slash;
331: if (fSlash > bSlash) {
332: slash = fSlash;
333: } else {
334: slash = bSlash;
335: }
336: if (slash > -1) {
337: String path = destination.substring(0, slash);
338: File dest = new File(path);
339: if (!dest.exists()) {
340: createDirectories(path);
341: }
342: }
343:
344: File[] inputFiles = new File[] { sourceFile };
345: String mask = sourceFile.getName();
346: if (FileIncludes.isMask(mask)) {
347: File sourceDir = sourceFile.getParentFile();
348: if (null != sourceDir && mask.length() > 0) {
349: try {
350: FilenameFilter filter = new FileIncludes(
351: sourceDir, mask);
352: inputFiles = sourceDir.listFiles(filter);
353: } catch (java.util.regex.PatternSyntaxException e) {
354: // nothing to do here
355: }
356: }
357: }
358:
359: File destFile = new File(destination);
360: if (null != inputFiles) {
361: if (destFile.isFile() && inputFiles.length > 1) {
362: System.err
363: .println("For copying multiple files to the destination \""
364: + destination
365: + "\" it must be a directory and NOT A SINGLE file.");
366: success = false;
367: } else {
368: for (int idx = 0; idx < inputFiles.length; idx++) {
369: File inputFile = inputFiles[idx];
370:
371: File destinationFile;
372: if (destFile.isDirectory()) {
373: destinationFile = new File(destFile,
374: inputFile.getName());
375: } else {
376: destinationFile = destFile;
377: }
378:
379: try {
380: // calling filecopy using FileChannel
381: Files.fileCopy(inputFile, destinationFile,
382: true);
383: success = true;
384: } catch (FileNotFoundException eFNF) {
385: System.err
386: .println("The source file could not be found. "
387: + eFNF);
388: System.err.println("Tried to copy "
389: + inputFile + " to "
390: + destinationFile + " : " + eFNF);
391: success = false;
392: break;
393: } catch (IOException eIO) {
394: System.err
395: .println("IOException occured while copying file.");
396: System.err.println("Tried to copy "
397: + inputFile + " to "
398: + destinationFile + " : " + eIO);
399: success = false;
400: break;
401: }
402: }
403: }
404: }
405: }
406: return success;
407: }
408:
409: /**
410: * @param filename
411: * A filename that may be a relative filename like "." or "..".
412: * @return The absolute <code>File</code> name instance fo the given
413: * (relative) filename. Return <code>null</code> if ".." is given
414: * and the current or parent directory is /
415: */
416: public static File getAbsoluteFile(final String filename) {
417: File file = new File(filename).getAbsoluteFile();
418: if (".".equals(file.getName())) {
419: file = file.getParentFile();
420: } else if ("..".equals(file.getName())) {
421: file = file.getParentFile();
422: if (null != file) {
423: file = file.getParentFile();
424: }
425: }
426: return file;
427: }
428:
429: /**
430: * making a string to a directory with ending on File.separator.
431: *
432: * @param aPath
433: * path to convert
434: * @return string
435: */
436: public static String makeDirectory(final String aPath) {
437: String path = aPath;
438: String separatorChar = System.getProperty("file.separator");
439: if (path != null && !path.endsWith(separatorChar)) {
440: path += separatorChar;
441: }
442: return path;
443: }
444:
445: /**
446: * removes a directory recursively. All Files and Subdirectories are
447: * removed. If bRecursive is false and the directory is not empty, an
448: * IOException is thrown.
449: *
450: * @param filename
451: * path or file to remove
452: * @param bRecursive
453: * delete all subfolders too
454: * @return success <code>true</code> if all files could be removed, else
455: * return <code>false</code>
456: * @throws IOException
457: * if something goes wrong
458: */
459: public static boolean remove(final String filename,
460: final boolean bRecursive) throws IOException {
461: return remove(filename, bRecursive, null);
462: }
463:
464: /**
465: * removes a directory recursively. All Files and Subdirectories are
466: * removed. If bRecursive is false and the directory is not empty, an
467: * IOException is thrown.
468: *
469: * @param filename
470: * path or file to remove
471: * @param bRecursive
472: * delete all subfolders too
473: * @param excludes
474: * list with files to exclude from deleting
475: * @return success <code>true</code> if all files could be removed, else
476: * return <code>false</code>
477: * @throws IOException
478: * if something goes wrong
479: */
480: public static boolean remove(final String filename,
481: final boolean bRecursive, final ArrayList excludes)
482: throws IOException {
483: boolean bSuccess = true;
484: if (filename != null && 0 != filename.length()) {
485: File file = new File(filename);
486: if (file.isDirectory()) {
487: String[] files = file.list();
488:
489: if (!bRecursive && files.length > 0) {
490: System.err.println();
491: throw new IOException("Directory "
492: + file.getAbsolutePath() + " is not Empty");
493: } else {
494: for (int iLoop = 0; iLoop < files.length; iLoop++) {
495: String toRemove = FileTool.convertSlashes(file
496: .getAbsolutePath()
497: + "/" + files[iLoop]);
498: if (!isExcluded(toRemove, excludes)) {
499: if (!remove(toRemove, true)) {
500: bSuccess = false;
501: }
502: }
503: }
504: if (bSuccess) {
505: if (!isExcluded(filename, excludes)) {
506: bSuccess = remove(filename);
507: }
508: }
509: }
510: } else {
511: if (!isExcluded(filename, excludes)) {
512: bSuccess = remove(filename);
513: }
514: }
515: }
516: return bSuccess;
517: }
518:
519: /**
520: * checks if a file is in the exclude list.
521: *
522: * @param filename
523: * file to test
524: * @param excludes
525: * list with the excluded files
526: * @return boolean <code>true</code> if the file is in the excludelist,
527: * else <code>false</code>
528: */
529: private static boolean isExcluded(final String filename,
530: final ArrayList excludes) {
531: boolean bDelete = true;
532: if (excludes != null && excludes.size() > 0) {
533: for (int iFileLoop = 0; iFileLoop < excludes.size(); iFileLoop++) {
534: String exclude = FileTool
535: .convertSlashes((String) excludes
536: .get(iFileLoop));
537: if (filename.indexOf(exclude) > -1
538: || exclude.startsWith(filename)) {
539: bDelete = false;
540: break;
541: }
542: }
543: }
544: return !bDelete;
545: }
546:
547: /**
548: * Delete the file.
549: *
550: * @param filename
551: * file to delete
552: * @return <code>true</code> if the file could be delete,
553: * <code>false</code> if not.
554: */
555: public static boolean remove(final String filename) {
556: try {
557: return new File(filename).delete();
558: } catch (SecurityException e) {
559: System.err.println("The file " + filename
560: + " could not be removed: "
561: + e.getLocalizedMessage());
562: return false;
563: }
564: }
565:
566: /**
567: * reading a file into an arraylist. Every line is one entry.
568: *
569: * @param fileName
570: * file to read
571: * @return ArrayList with all lines
572: */
573: public static ArrayList readFileToArrayList(final String fileName) {
574: ArrayList<String> list = new ArrayList<String>();
575: BufferedReader br = null;
576: try {
577: br = new BufferedReader(new InputStreamReader(
578: new FileInputStream(fileName)));
579: } catch (FileNotFoundException e) {
580: System.err.println("The File " + fileName
581: + " could not be found !!");
582: e.printStackTrace();
583: System.exit(3);
584: }
585: String line = "";
586: try {
587: while ((line = br.readLine()) != null) {
588: if (line.trim().length() > 0
589: && line.trim().charAt(0) != '#') {
590: list.add(line);
591: }
592: }
593: } catch (IOException e1) {
594: System.err.println("IOException occured while reading "
595: + fileName + "");
596: e1.printStackTrace();
597: } finally {
598: try {
599: br.close();
600: } catch (IOException e) {
601: e.printStackTrace();
602: }
603: }
604: return list;
605: }
606:
607: /**
608: * reading a file into an arraylist. Every line is one entry.
609: *
610: * @param fileName
611: * file to read
612: * @return ArrayList with all lines
613: */
614: public static String readFileToString(final String fileName) {
615: StringBuffer buffer = new StringBuffer();
616: BufferedReader br = null;
617: try {
618: br = new BufferedReader(new InputStreamReader(
619: new FileInputStream(fileName)));
620: } catch (FileNotFoundException e) {
621: System.err.println("The File " + fileName
622: + " could not be found !!");
623: e.printStackTrace();
624: System.exit(3);
625: }
626: String line = "";
627: try {
628: while ((line = br.readLine()) != null) {
629: if (line.trim().length() > 0
630: && line.trim().charAt(0) != '#') {
631: buffer.append(line);
632: }
633: }
634:
635: } catch (IOException e1) {
636: System.err.println("IOException occured while reading "
637: + fileName + "");
638: e1.printStackTrace();
639: } finally {
640: try {
641: br.close();
642: } catch (IOException e) {
643: e.printStackTrace();
644: }
645: }
646:
647: return buffer.toString();
648: }
649:
650: /**
651: * simple writing a string into a file.
652: *
653: * @param filename
654: * of the file to create
655: * @param content
656: * string to write into the file.
657: */
658: public static void writeStringToFile(final String filename,
659: final String content) {
660: File file = new File(filename);
661: try {
662: BufferedWriter bufWriter = new BufferedWriter(
663: new FileWriter(file));
664: bufWriter.write(content);
665: bufWriter.close();
666: } catch (IOException e) {
667: // TODO Auto-generated catch block
668: e.printStackTrace();
669: }
670: }
671:
672: /**
673: * Eleminates // in a filename.
674: *
675: * @param filename
676: * to convert
677: * @return String
678: */
679: public static String eliminateDoubleSlashes(final String filename) {
680: String result = "";
681: if (filename.indexOf(":") == -1 && filename.startsWith("//")) {
682: result = filename.substring(0, 2)
683: + filename.substring(2).replaceAll("//", "/");
684: } else {
685: result = filename.replaceAll("//", "/");
686: }
687: return result;
688: }
689:
690: /**
691: * converts 2 backslashes into one slash.
692: *
693: * @param path
694: * to convert
695: * @return string
696: */
697: public static String convertSlashes(final String path) {
698: return path.replaceAll("\\\\", "/");
699: }
700:
701: /**
702: * converts one slash into 2 backslashes.
703: *
704: * @param path
705: * to convert
706: * @return string
707: */
708: public static String convertBackSlashes(final String path) {
709: return path.replaceAll("/", "\\\\");
710: }
711:
712: /**
713: * converts only if backslash is not proceeded by a blank.
714: *
715: * @param aPath
716: * to convert
717: * @return string
718: */
719: public static String convertBackSlashesNoParams(final String aPath) {
720: String path = aPath;
721: int slash = -1;
722: while ((slash = path.indexOf("/", slash + 1)) > -1) {
723: if (slash > -1 && path.charAt(slash - 1) != ' ') {
724: String sLineStart = path.substring(0, slash);
725: String sLineEnd = path.substring(slash + 1);
726: path = sLineStart + "\\" + sLineEnd;
727: }
728: }
729: return path;
730: }
731:
732: /**
733: * converting the given path with an File.separator at the end.
734: *
735: * @param aPath
736: * the path to convert
737: * @return the converted path
738: */
739: public static String normPath(final String aPath) {
740: if (!aPath.endsWith("/") && !aPath.endsWith("\\")) {
741: return aPath + File.separator;
742: } else {
743: return aPath;
744: }
745: }
746: }
|