Source Code Cross Referenced for FileOps.java in  » IDE » DrJava » edu » rice » cs » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.util;
038:
039:        import java.io.*;
040:        import java.net.MalformedURLException;
041:        import java.net.URL;
042:        import java.util.*;
043:
044:        import edu.rice.cs.drjava.config.FileOption;
045:
046:        import edu.rice.cs.util.Log;
047:
048:        import edu.rice.cs.plt.io.IOUtil;
049:
050:        /** A class to provide some convenient file operations as static methods.
051:         *  It's abstract to prevent (useless) instantiation, though it can be subclassed
052:         *  to provide convenient namespace importation of its methods.
053:         *
054:         *  @version $Id: FileOps.java 4255 2007-08-28 19:17:37Z mgricken $
055:         */
056:        public abstract class FileOps {
057:
058:            private static Log _log = new Log("FileOpsTest.txt", false);
059:
060:            /** Special File object corresponding to a dummy file. Simliar to FileOption.NULL_FILE but exists() returns false. */
061:            public static final File NONEXISTENT_FILE = new File("") {
062:                public String getAbsolutePath() {
063:                    return "";
064:                }
065:
066:                public String getName() {
067:                    return "";
068:                }
069:
070:                public String toString() {
071:                    return "";
072:                }
073:
074:                public boolean exists() {
075:                    return false;
076:                }
077:            };
078:
079:            /** @deprecated  If a best-attempt canonical file is needed, use 
080:             *              {@link edu.rice.cs.plt.io.IOUtil#attemptCanonicalFile} instead
081:             *              (for example, {@code IOUtil.attemptCanonicalFile(new File(path))})
082:             */
083:            @Deprecated
084:            public static File makeFile(String path) {
085:                File f = new File(path);
086:                try {
087:                    return f.getCanonicalFile();
088:                } catch (IOException e) {
089:                    return f;
090:                }
091:            }
092:
093:            /** @deprecated  If a best-attempt canonical file is needed, 
094:             *              use {@link edu.rice.cs.plt.io.IOUtil#attemptCanonicalFile} instead
095:             *              (for example, {@code IOUtil.attemptCanonicalFile(new File(parentDir, child))})
096:             */
097:            @Deprecated
098:            public static File makeFile(File parentDir, String child) {
099:                File f = new File(parentDir, child);
100:                try {
101:                    return f.getCanonicalFile();
102:                } catch (IOException e) {
103:                    return f;
104:                }
105:            }
106:
107:            /** Determines whether the specified file in within the specified file tree. 
108:             * @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#isMember} instead.  Note that the
109:             *              replacement method does not test for {@code null} values and does not
110:             *              convert to canonical paths -- if these things are necessary, they should
111:             *              be done before invoking the method.
112:             */
113:            @Deprecated
114:            public static boolean inFileTree(File f, File root) {
115:                if (root == null || f == null)
116:                    return false;
117:                try {
118:                    if (!f.isDirectory())
119:                        f = f.getParentFile();
120:                    String filePath = f.getCanonicalPath() + File.separator;
121:                    String projectPath = root.getCanonicalPath()
122:                            + File.separator;
123:                    return (filePath.startsWith(projectPath));
124:                } catch (IOException e) {
125:                    return false;
126:                }
127:            }
128:
129:            /** Makes a file equivalent to the given file f that is relative to base file b.  In other words,
130:             * <code>new File(b,makeRelativeTo(base,abs)).getCanonicalPath()</code> equals
131:             * <code>f.getCanonicalPath()</code>
132:             * 
133:             * <p>In Linux/Unix, if the file f is <code>/home/username/folder/file.java</code> and the file b is 
134:             * <code>/home/username/folder/sublevel/file2.java</code>, then the resulting File path from this method would be 
135:             * <code>../file.java</code> while its canoncial path would be <code>/home/username/folder/file.java</code>.</p>
136:             * 
137:             * <p>Warning: this method is inherently broken, because it assumes a relative path exists between all
138:             * files.  The Java file system model, however, supports multiple system roots (see {@link File#listRoots}).
139:             * Thus, two files from different "file systems" (in Windows, different drives) have no common parent.</p>
140:             * 
141:             * @param f The path that is to be made relative to the base file
142:             * @param b The file to make the next file relative to
143:             * @return A new file whose path is relative to the base file while the value of <code>getCanonicalPath()</code> 
144:             *    for the returned file is the same as the result of <code>getCanonicalPath()</code> for the given file.
145:             */
146:            public static File makeRelativeTo(File f, File b)
147:                    throws IOException, SecurityException {
148:                File base = b.getCanonicalFile();
149:                File abs = f.getCanonicalFile(); // If  f is relative, uses current working directory ("user.dir")
150:                if (!base.isDirectory())
151:                    base = base.getParentFile();
152:
153:                String last = "";
154:                if (!abs.isDirectory()) {
155:                    String tmp = abs.getPath();
156:                    last = tmp.substring(tmp.lastIndexOf(File.separator) + 1);
157:                    abs = abs.getParentFile();
158:                }
159:
160:                //    System.err.println("makeRelativeTo called; f = " + f + " = " + abs + "; b = " + b + " = " + base);
161:                String[] basParts = splitFile(base);
162:                String[] absParts = splitFile(abs);
163:
164:                final StringBuilder result = new StringBuilder();
165:                // loop until elements differ, record what part of absParts to append
166:                // next find out how many .. to put in.
167:                int diffIndex = -1;
168:                boolean different = false;
169:                for (int i = 0; i < basParts.length; i++) {
170:                    if (!different
171:                            && ((i >= absParts.length) || !basParts[i]
172:                                    .equals(absParts[i]))) {
173:                        different = true;
174:                        diffIndex = i;
175:                    }
176:                    if (different)
177:                        result.append("..").append(File.separator);
178:                }
179:                if (diffIndex < 0)
180:                    diffIndex = basParts.length;
181:                for (int i = diffIndex; i < absParts.length; i++) {
182:                    result.append(absParts[i]).append(File.separator);
183:                }
184:                result.append(last);
185:                //    System.err.println("makeRelativeTo(" + f + ", " + b + ") = " + result);
186:                return new File(result.toString());
187:            }
188:
189:            /** Splits a file into an array of strings representing each parent folder of the given file.  The file whose path
190:             *  is <code>/home/username/txt.txt</code> in linux would be split into the string array: 
191:             *  {&quot;&quot;,&quot;home&quot;,&quot;username&quot;,&quot;txt.txt&quot;}. Delimeters are excluded.
192:             *  @param fileToSplit the file to split into its directories.
193:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#fullPath} instead.  It returns a list of {@code File}
194:             *               objects rather than strings, but they appear in the same order.
195:             */
196:            @Deprecated
197:            public static String[] splitFile(File fileToSplit) {
198:                String path = fileToSplit.getPath();
199:                ArrayList<String> list = new ArrayList<String>();
200:                while (!path.equals("")) {
201:                    int idx = path.indexOf(File.separator);
202:                    if (idx < 0) {
203:                        list.add(path);
204:                        path = "";
205:                    } else {
206:                        list.add(path.substring(0, idx));
207:                        path = path.substring(idx + 1);
208:                    }
209:                }
210:                return list.toArray(new String[list.size()]);
211:            }
212:
213:            /** List all files (that is, {@code File}s for which {@code isFile()} is {@code true}) matching the provided filter in
214:             *  the given directory.
215:             *  @param d  The directory to search.
216:             *  @param recur  Whether subdirectories accepted by {@code f} should be recursively searched.  Note that 
217:             *         subdirectories that <em>aren't</em> accepted by {@code f} will be ignored.
218:             *  @param f  The filter to apply to contained {@code File}s.
219:             *  @return  An array of Files in the directory specified; if the directory does not exist, returns an empty list.
220:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#attemptListFilesAsIterable} or
221:             *               {@link edu.rice.cs.plt.io.IOUtil#listFilesRecursively(File, FileFilter, FileFilter)} instead.
222:             */
223:            @Deprecated
224:            public static ArrayList<File> getFilesInDir(File d, boolean recur,
225:                    FileFilter f) {
226:                ArrayList<File> l = new ArrayList<File>();
227:                getFilesInDir(d, l, recur, f);
228:                return l;
229:            }
230:
231:            /** Helper fuction for getFilesInDir(File d, boolean recur). {@code acc} is mutated to contain
232:             *  a list of <c>File</c>s in the directory specified, not including directories.
233:             */
234:            private static void getFilesInDir(File d, List<File> acc,
235:                    boolean recur, FileFilter filter) {
236:                if (d.isDirectory()) {
237:                    File[] files = d.listFiles(filter);
238:                    if (files != null) { // listFiles may return null if there's an IO error
239:                        for (File f : files) {
240:                            if (f.isDirectory() && recur)
241:                                getFilesInDir(f, acc, recur, filter);
242:                            else if (f.isFile())
243:                                acc.add(f);
244:                        }
245:                    }
246:                }
247:            }
248:
249:            /** @return the canonical file equivalent to f.  Identical to f.getCanonicalFile() except it does not throw an 
250:             *  exception when the file path syntax is incorrect (or an IOException or SecurityException occurs for any
251:             *  other reason).  It returns the absolute File intead.
252:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#attemptCanonicalFile}, which provides the same
253:             *               functionality, instead.
254:             */
255:            @Deprecated
256:            public static File getCanonicalFile(File f) {
257:                if (f == null)
258:                    return f;
259:                try {
260:                    return f.getCanonicalFile();
261:                } catch (IOException e) { /* fall through */
262:                } catch (SecurityException e) { /* fall through */
263:                }
264:                return f.getAbsoluteFile();
265:            }
266:
267:            /** @return the canonical path for f.  Identical to f.getCanonicalPath() except it does not throw an 
268:             *  exception when the file path syntax is incorrect; it returns the absolute path instead.
269:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#attemptCanonicalFile}, which provides the same
270:             *               functionality, instead.  (The result will be a {@code File} instead of a {@code String}.)
271:             */
272:            @Deprecated
273:            public static String getCanonicalPath(File f) {
274:                return getCanonicalFile(f).getPath();
275:            }
276:
277:            /** @return the file f unchanged if f exists; otherwise returns NULL_FILE. */
278:            public static File validate(File f) {
279:                if (f.exists())
280:                    return f;
281:                return FileOption.NULL_FILE; // This File object exists
282:            }
283:
284:            /** This filter checks for files with names that end in ".java".  (Note that while this filter was <em>intended</em>
285:             *              to be a {@code javax.swing.filechooser.FileFilter}, it actually implements a {@code java.io.FileFilter},
286:             *              because thats what {@code FileFilter} means in the context of this source file.)
287:             * @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#extensionFileFilter} instead.  Example:
288:             *              {@code IOUtil.extensionFileFilter("java")}.  
289:             */
290:            @Deprecated
291:            public static final FileFilter JAVA_FILE_FILTER = new FileFilter() {
292:                public boolean accept(File f) {
293:                    // Do this runaround for filesystems that are case preserving but case insensitive. Remove the last 5 
294:                    // letters from the file name, append ".java" to the end, create a new file and see if its equivalent 
295:                    // to the original
296:                    final StringBuilder name = new StringBuilder(f
297:                            .getAbsolutePath());
298:                    String shortName = f.getName();
299:                    if (shortName.length() < 6)
300:                        return false;
301:                    name.delete(name.length() - 5, name.length());
302:                    name.append(".java");
303:                    File test = new File(name.toString());
304:                    return (test.equals(f));
305:                }
306:
307:                public String getDescription() {
308:                    return "Java Source Files (*.java)";
309:                }
310:            };
311:
312:            /** Reads the stream until it reaches EOF, and then returns the read contents as a byte array. This call may 
313:             *  block, since it will not return until EOF has been reached.
314:             *  @param stream Input stream to read.
315:             *  @return Byte array consisting of all data read from stream.
316:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#toByteArray} instead, which provides the same functionality.
317:             *               Note that the {@code IOUtil} method will not close the {@code InputStream}, while this method does.
318:             */
319:            @Deprecated
320:            public static byte[] readStreamAsBytes(final InputStream stream)
321:                    throws IOException {
322:                BufferedInputStream buffered;
323:
324:                if (stream instanceof  BufferedInputStream)
325:                    buffered = (BufferedInputStream) stream;
326:                else
327:                    buffered = new BufferedInputStream(stream);
328:
329:                ByteArrayOutputStream out = new ByteArrayOutputStream();
330:
331:                int readVal = buffered.read();
332:                while (readVal != -1) {
333:                    out.write(readVal);
334:                    readVal = buffered.read();
335:                }
336:
337:                stream.close();
338:                return out.toByteArray();
339:            }
340:
341:            /** Reads the entire contents of a file and return them as canonicalized Swing Document text. All newLine sequences,
342:             * including "\n", "\r", and "\r\n" are converted to "\n". */
343:            public static String readFileAsSwingText(final File file)
344:                    throws IOException {
345:                FileReader reader = new FileReader(file);
346:                final StringBuilder buf = new StringBuilder();
347:
348:                char pred = (char) 0; // initialize as null character
349:                while (reader.ready()) {
350:                    char c = (char) reader.read();
351:
352:                    if (c == '\n' && pred == '\r') {
353:                    } // do nothing ignoring second character of "\r\n";
354:                    else if (c == '\r')
355:                        buf.append('\n');
356:                    else
357:                        buf.append(c);
358:
359:                    pred = c;
360:                }
361:
362:                reader.close();
363:                return buf.toString();
364:            }
365:
366:            /** Reads the entire contents of a file and return them as a String.
367:             * @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#toString(File)} instead, which provides the same functionality.
368:             */
369:            @Deprecated
370:            public static String readFileAsString(final File file)
371:                    throws IOException {
372:                FileReader reader = new FileReader(file);
373:                final StringBuilder buf = new StringBuilder();
374:
375:                while (reader.ready()) {
376:                    char c = (char) reader.read();
377:                    buf.append(c);
378:                }
379:
380:                reader.close();
381:                return buf.toString();
382:            }
383:
384:            /** Copies the text of one file into another.
385:             *  @param source the file to be copied
386:             *  @param dest the file to be copied to
387:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#copyFile} instead, which provides the same functionality
388:             *               but scales in a much more efficient manner.
389:             */
390:            @Deprecated
391:            public static void copyFile(File source, File dest)
392:                    throws IOException {
393:                String text = readFileAsString(source);
394:                writeStringToFile(dest, text);
395:            }
396:
397:            /** Creates a new temporary file and writes the given text to it. The file will be deleted on exit.
398:             *  @param prefix Beginning part of file name, before unique number
399:             *  @param suffix Ending part of file name, after unique number
400:             *  @param text Text to write to file
401:             *  @return name of the temporary file that was created
402:             *  @deprecated  Instead, create a temp file with {@link edu.rice.cs.plt.io.IOUtil#createAndMarkTempFile(String, String)},
403:             *               then write to it with {@link edu.rice.cs.plt.io.IOUtil#writeStringToFile(File, String)}.
404:             */
405:            @Deprecated
406:            public static File writeStringToNewTempFile(final String prefix,
407:                    final String suffix, final String text) throws IOException {
408:
409:                File file = File.createTempFile(prefix, suffix);
410:                file.deleteOnExit();
411:                writeStringToFile(file, text);
412:                return file;
413:            }
414:
415:            /** Writes text to the file overwriting whatever was there.
416:             *  @param file File to write to
417:             *  @param text Test to write
418:             *  @deprecated  Use the equivalent {@link edu.rice.cs.plt.io.IOUtil#writeStringToFile(File, String)} instead
419:             */
420:            @Deprecated
421:            public static void writeStringToFile(File file, String text)
422:                    throws IOException {
423:                writeStringToFile(file, text, false);
424:            }
425:
426:            /** Writes text to the file.
427:             *  @param file File to write to
428:             *  @param text Text to write
429:             *  @param append whether to append. (false=overwrite)
430:             *  @deprecated  Use the equivalent {@link edu.rice.cs.plt.io.IOUtil#writeStringToFile(File, String, boolean)} instead
431:             */
432:            @Deprecated
433:            public static void writeStringToFile(File file, String text,
434:                    boolean append) throws IOException {
435:                FileWriter writer = new FileWriter(file, append);
436:                writer.write(text);
437:                writer.close();
438:            }
439:
440:            /** Writes the text to the given file returning true if it happend and false if it could not.  This is a 
441:             *  simple wrapper for writeStringToFile that doesn't throw an IOException.
442:             *  @param file File to write to
443:             *  @param text Text to write
444:             *  @param append whether to append. (false=overwrite)
445:             *  @deprecated  Use the equivalent {@link edu.rice.cs.plt.io.IOUtil#attemptWriteStringToFile(File, String, boolean)}
446:             *               instead
447:             */
448:            @Deprecated
449:            public static boolean writeIfPossible(File file, String text,
450:                    boolean append) {
451:                try {
452:                    writeStringToFile(file, text, append);
453:                    return true;
454:                } catch (IOException e) {
455:                    return false;
456:                }
457:            }
458:
459:            /** Create a new temporary directory. The directory will be deleted on exit, if empty.
460:             *  (To delete it recursively on exit, use deleteDirectoryOnExit.)
461:             *  @param name Non-unique portion of the name of the directory to create.
462:             *  @return File representing the directory that was created.
463:             */
464:            //   *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#createAndMarkTempDirectory(String, String)} instead.
465:            //   *               Example: {@code IOUtil.createAndMarkTempDirectory(name, "")}.
466:            /*  @Deprecated */public static File createTempDirectory(
467:                    final String name) throws IOException {
468:                return createTempDirectory(name, null);
469:            }
470:
471:            /** Create a new temporary directory. The directory will be deleted on exit, if it only contains temp files and temp
472:             *  directories created after it.  (To delete it on exit regardless of contents, call deleteDirectoryOnExit after
473:             *  constructing the file tree rooted at this directory.  Note that createTempDirectory(..) is not much more helpful 
474:             *  than mkdir() in this context (other than generating a new temp file name) because cleanup is a manual process.)
475:             *  @param name Non-unique portion of the name of the directory to create.
476:             *  @param parent Parent directory to contain the new directory
477:             *  @return File representing the directory that was created.
478:             */
479:            //   *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#createAndMarkTempDirectory(String, String, File)} instead.
480:            //   *               Example: {@code IOUtil.createAndMarkTempDirectory(name, "", parent)}.
481:            /* @Deprecated */public static File createTempDirectory(
482:                    /* final */String name, /* final */File parent)
483:                    throws IOException {
484:                File result = File.createTempFile(name, "", parent);
485:                boolean success = result.delete();
486:                success = success && result.mkdir();
487:                if (!success) {
488:                    throw new IOException("Attempt to create directory failed");
489:                }
490:                IOUtil.attemptDeleteOnExit(result);
491:                return result;
492:                //    File file =  File.createTempFile(name, "", parent);
493:                //    file.delete();
494:                //    file.mkdir();
495:                //    file.deleteOnExit();
496:                //
497:                //    return file;
498:            }
499:
500:            /** Delete the given directory including any files and directories it contains.
501:             *  @param dir File object representing directory to delete. If, for some reason, this file object is not a 
502:             *             directory, it will still be deleted.
503:             *  @return true if there were no problems in deleting. If it returns false, something failed and the directory
504:             *          contents likely at least partially still exist.
505:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#deleteRecursively} instead
506:             */
507:            @Deprecated
508:            public static boolean deleteDirectory(final File dir) {
509:                //    System.err.println("Deleting file or directory " + dir);
510:                if (!dir.isDirectory()) {
511:                    boolean res;
512:                    res = dir.delete();
513:                    //      System.err.println("Deletion of " + dir + " returned " + res);
514:                    return res;
515:                }
516:
517:                boolean ret = true;
518:                File[] childFiles = dir.listFiles();
519:                if (childFiles != null) { // listFiles may return null if there's an IO error
520:                    for (File f : childFiles) {
521:                        ret = ret && deleteDirectory(f);
522:                    }
523:                }
524:
525:                // Now we should have an empty directory
526:                ret = ret && dir.delete();
527:                //    System.err.println("Recursive deletion of " + dir + " returned " + ret);
528:                return ret;
529:            }
530:
531:            /** Instructs Java to recursively delete the given directory and its contents when the JVM exits.
532:             *  @param dir File object representing directory to delete. If, for some reason, this file object is not a 
533:             *             directory, it will still be deleted.
534:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#deleteOnExitRecursively} instead
535:             */
536:            @Deprecated
537:            public static void deleteDirectoryOnExit(final File dir) {
538:
539:                // Delete this on exit, whether it's a directory or file
540:                _log.log("Deleting file/directory " + dir + " on exit");
541:                dir.deleteOnExit();
542:
543:                // If it's a directory, visit its children.  This recursive walk has to be done AFTER calling deleteOnExit
544:                //  on the directory itself because Java closes the list of files to deleted on exit in reverse order.
545:                if (dir.isDirectory()) {
546:                    File[] childFiles = dir.listFiles();
547:                    if (childFiles != null) { // listFiles may return null if there's an IO error
548:                        for (File f : childFiles) {
549:                            deleteDirectoryOnExit(f);
550:                        }
551:                    }
552:                }
553:            }
554:
555:            /** This function starts from the given directory and finds all  packages within that directory
556:             *  @param prefix the package name of files in the given root
557:             *  @param root the directory to start exploring from
558:             *  @return a list of valid packages, excluding the root ("") package
559:             */
560:            public static LinkedList<String> packageExplore(String prefix,
561:                    File root) {
562:                /* Inner holder class. */
563:                class PrefixAndFile {
564:                    public String prefix;
565:                    public File root;
566:
567:                    public PrefixAndFile(String prefix, File root) {
568:                        this .root = root;
569:                        this .prefix = prefix;
570:                    }
571:                }
572:
573:                // This set makes sure we don't get caught in a loop if the filesystem has symbolic links
574:                // that form a circle by tracking the directories we have already explored
575:                final Set<File> exploredDirectories = new HashSet<File>();
576:
577:                LinkedList<String> output = new LinkedList<String>();
578:                Stack<PrefixAndFile> working = new Stack<PrefixAndFile>();
579:                working.push(new PrefixAndFile(prefix, root));
580:                exploredDirectories.add(root);
581:
582:                // This filter allows only directories, and accepts each directory only once
583:                FileFilter directoryFilter = new FileFilter() {
584:                    public boolean accept(File f) {
585:                        boolean toReturn = f.isDirectory()
586:                                && !exploredDirectories.contains(f);
587:                        exploredDirectories.add(f);
588:                        return toReturn;
589:                    }
590:
591:                    public String getDescription() {
592:                        return "All Folders";
593:                    }
594:                };
595:
596:                // Explore each directory, adding (unique) subdirectories to the working list.  If a directory has .java 
597:                // files, add the associated package to the list of packages
598:                while (!working.empty()) {
599:                    PrefixAndFile current = working.pop();
600:                    File[] subDirectories = current.root
601:                            .listFiles(directoryFilter);
602:                    if (subDirectories != null) { // listFiles may return null if there's an IO error
603:                        for (File dir : subDirectories) {
604:                            PrefixAndFile paf;
605:                            //         System.out.println("exploring " + dir);
606:                            if (current.prefix.equals(""))
607:                                paf = new PrefixAndFile(dir.getName(), dir);
608:                            else
609:                                paf = new PrefixAndFile(current.prefix + "."
610:                                        + dir.getName(), dir);
611:                            working.push(paf);
612:                        }
613:                    }
614:                    File[] javaFiles = current.root.listFiles(JAVA_FILE_FILTER);
615:
616:                    if (javaFiles != null) { // listFiles may return null if there's an IO error
617:                        //Only add package names if they have java files and are not the root package
618:                        if (javaFiles.length != 0 && !current.prefix.equals("")) {
619:                            output.add(current.prefix);
620:                            //         System.out.println("adding " + current.prefix);
621:                        }
622:                    }
623:                }
624:                return output;
625:            }
626:
627:            /** Renames the given file to the given destination.  Needed since Windows will not allow a rename to 
628:             *  overwrite an existing file.
629:             *  @param file the file to rename
630:             *  @param dest the destination file
631:             *  @return true iff the rename was successful
632:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#attemptMove}, which is equally Windows-friendly, instead.
633:             */
634:            @Deprecated
635:            public static boolean renameFile(File file, File dest) {
636:                if (dest.exists())
637:                    dest.delete();
638:                return file.renameTo(dest);
639:            }
640:
641:            /** This method writes files correctly; it takes care of catching errors and
642:             *  making backups and keeping an unsuccessful file save from destroying the old
643:             *  file (unless a backup is made).  It makes sure that the file to be saved is 
644:             *  not read-only, throwing an IOException if it is.  Note: if saving fails and a 
645:             *  backup was being created, any existing backup will be destroyed (this is 
646:             *  because the backup is written before saving begins, and then moved back over 
647:             *  the original file when saving fails).  As the old backup would have been destroyed 
648:             *  anyways if saving had succeeded, I do not think that this is incorrect or 
649:             *  unreasonable behavior.
650:             *  @param fileSaver keeps track of the name of the file to write, whether to back up the file, and has 
651:             *                   a method that actually performs the writing of the file
652:             *  @throws IOException if the saving or backing up of the file fails for any reason
653:             */
654:            public static void saveFile(FileSaver fileSaver) throws IOException {
655:
656:                //    ScrollableDialog sd1 = new ScrollableDialog(null, "saveFile (" + fileSaver + ") called in FileOps.java", "", "");
657:                //    sd1.show();
658:                boolean makeBackup = fileSaver.shouldBackup();
659:                boolean success = false;
660:                File file = fileSaver.getTargetFile();
661:                File backup = null;
662:                boolean tempFileUsed = true;
663:                // file.canWrite() is false if file.exists() is false
664:                // but we want to be able to save a file that doesn't
665:                // yet exist.
666:                if (file.exists() && !file.canWrite())
667:                    throw new IOException("Permission denied");
668:                /* First back up the file, if necessary */
669:                if (makeBackup) {
670:                    backup = fileSaver.getBackupFile();
671:                    if (!renameFile(file, backup)) {
672:                        throw new IOException(
673:                                "Save failed. Could not create backup file "
674:                                        + backup.getAbsolutePath()
675:                                        + "\nIt may be possible to save by disabling file backups\n");
676:                    }
677:                    fileSaver.backupDone();
678:                }
679:
680:                //    ScrollableDialog sd2 = new ScrollableDialog(null, "backup done in FileOps.saveFile", "", "");
681:                //    sd2.show();
682:
683:                //Create a temp file in the same directory as the file to be saved.
684:                //From this point forward, enclose in try...finally so that we can clean
685:                //up the temp file and restore the file from its backup.
686:                File parent = file.getParentFile();
687:                File tempFile = File.createTempFile("drjava", ".temp", parent);
688:
689:                //    ScrollableDialog sd3 = new ScrollableDialog(null, "temp file " + tempFile + "created in FileOps.saveFile", "", "");
690:                //    sd3.show();
691:
692:                try {
693:                    /* Now, write your output to the temp file, then rename it to the correct
694:                     name.  This way, if writing fails in the middle, the old file is not
695:                     lost. */
696:                    FileOutputStream fos;
697:                    try {
698:                        /* The next line will fail if we can't create the temp file.  This may mean that
699:                         * the user does not have write permission on the directory the file they
700:                         * are editing is in.  We may want to go ahead and try writing directly
701:                         * to the target file in this case
702:                         */
703:                        fos = new FileOutputStream(tempFile);
704:                    } catch (FileNotFoundException fnfe) {
705:                        if (fileSaver.continueWhenTempFileCreationFails()) {
706:                            fos = new FileOutputStream(file);
707:                            tempFileUsed = false;
708:                        } else
709:                            throw new IOException("Could not create temp file "
710:                                    + tempFile + " in attempt to save " + file);
711:                    }
712:                    BufferedOutputStream bos = new BufferedOutputStream(fos);
713:                    fileSaver.saveTo(bos);
714:                    bos.close();
715:                    fos.close();
716:
717:                    if (tempFileUsed && !renameFile(tempFile, file))
718:                        throw new IOException(
719:                                "Save failed. Another process may be using "
720:                                        + file + ".");
721:
722:                    success = true;
723:                } finally {
724:                    //      ScrollableDialog sd4 = new ScrollableDialog(null, "finally clause reached in FileOps.saveFile", "", "");
725:                    //      sd4.show();
726:
727:                    if (tempFileUsed)
728:                        tempFile.delete(); /* Delete the temp file */
729:
730:                    if (makeBackup) {
731:                        /* On failure, attempt to move the backup back to its original location if we
732:                         made one.  On success, register that a backup was successfully made */
733:                        if (success)
734:                            fileSaver.backupDone();
735:                        else
736:                            renameFile(backup, file);
737:                    }
738:                }
739:            }
740:
741:            public interface FileSaver {
742:
743:                /** This method tells what to name the backup of the file, if a backup is to be made.
744:                 *  It may depend on getTargetFile(), so it can thrown an IOException
745:                 */
746:                public abstract File getBackupFile() throws IOException;
747:
748:                /** This method indicates whether or not a backup of the file should be made.  It
749:                 *  may depend on getTargetFile(), so it can throw an IOException
750:                 */
751:                public abstract boolean shouldBackup() throws IOException;
752:
753:                /** This method specifies if the saving process should continue trying to save
754:                 *  if it can not create the temp file that is written initially.  If you do
755:                 *  continue saving in this case, the original file may be lost if saving fails.
756:                 */
757:                public abstract boolean continueWhenTempFileCreationFails();
758:
759:                /** This method is called to tell the file saver that a backup was successfully made. */
760:                public abstract void backupDone();
761:
762:                /**
763:                 * This method actually writes info to a file.  NOTE: It is important that this
764:                 * method write to the stream it is passed, not the target file.  If you write
765:                 * directly to the target file, the target file will be destroyed if saving fails.
766:                 * Also, it is important that when saving fails this method throw an IOException
767:                 * @throws IOException when saving fails for any reason
768:                 */
769:                public abstract void saveTo(OutputStream os) throws IOException;
770:
771:                /** This method tells what the file is that we want to save to.  It should
772:                 *  use the canonical name of the file (this means resolving symlinks).  Otherwise,
773:                 *  the saver would not deal correctly with symlinks.  Resolving symlinks may cause
774:                 *  an IOException, so this method throws an IOException.
775:                 */
776:                public abstract File getTargetFile() throws IOException;
777:            }
778:
779:            /** This class is a default implementation of FileSaver that makes only 1 backup
780:             *  of each file per instantiation of the program (following Emacs' lead).  It 
781:             *  backs up to files named <file>~.  It does not implement the saveTo method.
782:             */
783:            public abstract static class DefaultFileSaver implements  FileSaver {
784:
785:                private File outputFile = null;
786:                private static Set<File> filesNotNeedingBackup = new HashSet<File>();
787:                private static boolean backupsEnabled = true;
788:
789:                /** This field keeps track of whether or not outputFile has been resolved to its canonical name. */
790:                private boolean isCanonical = false;
791:
792:                /** Globally enables backups for any DefaultFileSaver that does not override the shouldBackup method. */
793:                public static void setBackupsEnabled(boolean isEnabled) {
794:                    backupsEnabled = isEnabled;
795:                }
796:
797:                public DefaultFileSaver(File file) {
798:                    outputFile = file.getAbsoluteFile();
799:                }
800:
801:                public boolean continueWhenTempFileCreationFails() {
802:                    return true;
803:                }
804:
805:                public File getBackupFile() throws IOException {
806:                    return new File(getTargetFile().getPath() + "~");
807:                }
808:
809:                public boolean shouldBackup() throws IOException {
810:                    if (!backupsEnabled)
811:                        return false;
812:                    if (!getTargetFile().exists())
813:                        return false;
814:                    if (filesNotNeedingBackup.contains(getTargetFile()))
815:                        return false;
816:                    return true;
817:                }
818:
819:                public void backupDone() {
820:                    try {
821:                        filesNotNeedingBackup.add(getTargetFile());
822:                    } catch (IOException ioe) {
823:                        throw new UnexpectedException(ioe,
824:                                "getTargetFile should fail earlier");
825:                    }
826:                }
827:
828:                public File getTargetFile() throws IOException {
829:                    if (!isCanonical) {
830:                        outputFile = outputFile.getCanonicalFile();
831:                        isCanonical = true;
832:                    }
833:                    return outputFile;
834:                }
835:            }
836:
837:            /** Convert all path entries in a path string to absolute paths. The delimiter in the path string is the 
838:             *  "path.separator" property.  Empty entries are equivalent to "." and will thus are converted to the 
839:             *  "user.dir" (working directory).
840:             *  Example:
841:             *    ".:drjava::/home/foo/junit.jar" with "user.dir" set to "/home/foo/bar" will be converted to 
842:             *    "/home/foo/bar:/home/foo/bar/drjava:/home/foo/bar:/home/foo/junit.jar".
843:             * 
844:             *  @param path path string with entries to convert
845:             *  @return path string with all entries as absolute paths
846:             *  @deprecated  Use {@link edu.rice.cs.plt.io.IOUtil#parsePath}, {@link edu.rice.cs.plt.io.IOUtil#getAbsoluteFiles},
847:             *               {@link edu.rice.cs.plt.io.IOUtil#attemptAbsoluteFiles}, and {@link edu.rice.cs.plt.io.IOUtil#pathToString},
848:             *               as needed, instead.
849:             */
850:            @Deprecated
851:            public static String convertToAbsolutePathEntries(String path) {
852:                String pathSep = System.getProperty("path.separator");
853:
854:                // split leaves off trailing empty strings
855:                // (see API javadocs: "Trailing empty strings are therefore not included in the resulting array.")
856:                // we therefore append one element at the end and later remove it
857:                path += pathSep + "x";
858:
859:                // now path ends with ":x", so we'll have an additional "x" element in the pathEntries array
860:
861:                // split up the path into individual entries, turn all of the entries
862:                // into absolute paths, and put the path back together
863:                // EXCEPT for the last item in the array, because that's the "x" we added
864:                String[] pathEntries = path.split(pathSep);
865:                final StringBuilder sb = new StringBuilder();
866:                for (int i = 0; i < pathEntries.length - 1; ++i) { // length-1 to ignore the last element
867:                    File f = new File(pathEntries[i]);
868:                    sb.append(f.getAbsolutePath());
869:                    sb.append(pathSep);
870:                }
871:                String reconstructedPath = sb.toString();
872:
873:                // if the reconstructed path is non-empty, then it will have an extra
874:                // path separator at the end; take it off
875:                if (reconstructedPath.length() != 0) {
876:                    reconstructedPath = reconstructedPath.substring(0,
877:                            reconstructedPath.length() - 1);
878:                }
879:
880:                return reconstructedPath;
881:            }
882:
883:            /** Return a valid directory for use, i.e. one that exists and is as "close" to the file specified. It is
884:             * 1) file, if file is a directory and exists
885:             * 2) the closest parent of file, if file is not a directory or does not exist
886:             * 3) "user.home"
887:             * @return a valid directory for use */
888:            public static File getValidDirectory(final File origFile) {
889:                File file = origFile;
890:
891:                // if it's the NULL_FILE or null, use "user.home"
892:                if ((file == FileOption.NULL_FILE) || (file == null)) {
893:                    file = new File(System.getProperty("user.home"));
894:                }
895:                assert file != null;
896:
897:                while (file != null && !file.exists()) {
898:                    // if the saved path doesn't exist anymore, try the parent
899:                    //NB: getParentFile() may return null
900:                    file = file.getParentFile();
901:                }
902:                if (file == null) {
903:                    // somehow we ended up with null, use "user.home"
904:                    file = new File(System.getProperty("user.home"));
905:                }
906:                assert file != null;
907:
908:                // if it's not a directory, try the parent
909:                if (!file.isDirectory()) {
910:                    if (file.getParent() != null) {
911:                        file = file.getParentFile();
912:                        //NB: getParentFile() may return null
913:                        if (file == null) {
914:                            // somehow we ended up with null, use "user.home"
915:                            file = new File(System.getProperty("user.home"));
916:                        }
917:                        assert file != null;
918:                    }
919:                }
920:
921:                // this should be an existing directory now
922:                if (file.exists() && file.isDirectory()) {
923:                    return file;
924:                }
925:
926:                // ye who enter here, abandon all hope...
927:                // the saved path didn't work, and neither did "user.home"
928:                throw new UnexpectedException(new IOException(origFile
929:                        .getPath()
930:                        + " is not a valid directory, and all attempts "
931:                        + "to locate a valid directory have failed. "
932:                        + "Check your configuration."));
933:            }
934:
935:            /** Converts the abstract pathname for f into a URL.  This method is included in class java.io.File as f.toURL(), but
936:             * has been deprecated in Java 6.0 because escape characters on some systems are not handled correctly.  The workaround,
937:             * f.toURI().toURL(), is unsatisfactory because we rely on the old (broken) behavior: toURI() produces escape
938:             * characters (for example, " " becomes "%20"), which remain in the name when we attempt to convert back
939:             * to a filename.  That is, f.toURI().toURL().getFile() may not be a valid path, even if f exists.  (The correct
940:             * solution is to avoid trying to convert from a URL to a File, because this conversion is not guaranteed
941:             * to work.)
942:             */
943:            public static URL toURL(File f) throws MalformedURLException {
944:                return f.toURL();
945:            }
946:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.